Environment Variables#
⚠️ BREAKING CHANGE - Tina4 v3.12.0
Every framework env var now requires the
TINA4_prefix. The legacy un-prefixed names (DATABASE_URL,SECRET,SMTP_HOST,HOST_NAME, etc.) no longer work. Setting them at startup makes the framework refuse to boot with a list of renames.Run
tina4 env --migrateto rewrite your existing.envautomatically, or rename manually using the table below. The runtime guard prints the same mapping if it detects legacy names.Conventional names stay un-prefixed:
PORT,HOST,NODE_ENV,RACK_ENV,RUBY_ENV,ENVIRONMENT. These are runtime/PaaS conventions, not framework config.
Tina4 is configured through environment variables, read from .env at the project root. Every variable has a sensible default; most projects set three or four values and leave the rest alone.
This chapter lists every variable the PHP framework reads, grouped by subsystem. Start with the minimum-config examples at the end, then come back here when you need to tune something specific.
Core Server#
| Variable | Default | Description |
|---|---|---|
HOST | 0.0.0.0 | Bind address. 0.0.0.0 listens on every interface. 127.0.0.1 restricts to localhost. |
TINA4_HOST | 0.0.0.0 | Tina4-specific bind override consulted by App::serve() and Server when no $host argument is passed. Wins over the conventional HOST for the framework's own server. |
PORT | 7145 | HTTP server port. The Rust CLI prefers TINA4_PORT but falls back to PORT. |
TINA4_PORT | (inherits PORT) | Explicit Tina4-specific port override. Takes precedence over PORT when both are set. |
TINA4_WS_PORT | (inherits port) | Separate port for the WebSocket server. Leave unset to share the HTTP port. |
TINA4_HOST_NAME | localhost:7145 | Fully-qualified host used in generated absolute URLs (Swagger, OAuth redirects, emails). |
TINA4_DEBUG | false | Master debug toggle. Enables Swagger UI, dev dashboard, live reload, template dump filter, error overlay. Never set to true in production. |
TINA4_LOG_LEVEL | ERROR | Minimum message level shown when TINA4_DEBUG=true. Options: DEBUG, INFO, WARNING, ERROR, ALL. |
TINA4_NO_BROWSER | false | Stops tina4 serve from opening your browser on every restart. Recommended during active development. |
TINA4_NO_RELOAD | false | Disables the dev hot-reload signal from the Rust CLI. Use when you want a stable server for debugging. |
TINA4_SUPPRESS | false | Hides the Tina4 startup banner. Useful in CI and systemd units where stdout is ingested. |
TINA4_VERSION | (framework) | Override the version string reported by /__dev/api/system. Mostly for testing. |
TINA4_CLI_SERVE | (none) | Set internally by the Rust CLI to signal managed mode. Do not set manually. |
TINA4_PUBLIC_DIR | (empty) | Override directory served as static files at /. When unset, the static-file middleware searches src/public/ and the framework's bundled public assets. |
TINA4_TEMPLATE_ROUTING | on | Auto-routing of Twig templates from src/templates/. Set to off, false, 0, no, or disabled to require explicit Router::get() for every URL. |
TINA4_ALLOW_LEGACY_ENV | false | Bypass the v3.12 boot guard that rejects un-prefixed legacy env vars (DATABASE_URL, SECRET, SMTP_HOST, etc.). Use only in CI / migration scripts during the transition window. |
TINA4_ENV_FILE | .env | Alternate path for the dotenv file loaded at boot. Resolved relative to the project root unless absolute. Useful for per-environment files (e.g. .env.production) without symlinking. |
TINA4_HEALTH_PATH | /health | Path the built-in health-check route registers under. Set /__health to align with the v3 documented alias used by the other frameworks; the default keeps /health for back-compat with existing probes. |
Routing#
| Variable | Default | Description |
|---|---|---|
TINA4_TRAILING_SLASH_REDIRECT | false | When truthy, any request path ending in / (other than the bare root) is 301-redirected to the slash-stripped form. The query string is preserved. Lets you normalise URLs without writing per-route handlers. |
Secrets and Authentication#
| Variable | Default | Description |
|---|---|---|
TINA4_SECRET | (empty) | JWT signing secret. Must be long, random, and unique per environment. Never commit. |
TINA4_JWT_ALGORITHM | HS256 | JWT signing algorithm. Supports HS256, HS384, HS512. |
TINA4_TOKEN_LIMIT | 60 | JWT token lifetime in minutes. |
TINA4_API_KEY | (empty) | Static API key used by Auth::validateApiKey() as a fallback to JWT. |
Database#
| Variable | Default | Description |
|---|---|---|
TINA4_DATABASE_URL | sqlite:///data/app.db | Connection URL. Scheme selects the driver: sqlite, postgres, mysql, mssql, sqlserver, firebird. |
TINA4_DATABASE_USERNAME | (empty) | Overrides the username embedded in TINA4_DATABASE_URL. |
TINA4_DATABASE_PASSWORD | (empty) | Overrides the password embedded in TINA4_DATABASE_URL. |
TINA4_DATABASE_FIREBIRD_PATH | (empty) | Overrides the database path/alias parsed from TINA4_DATABASE_URL for Firebird. Useful for Windows backslash paths and split-config setups. |
TINA4_DATABASE_URL | (empty) | Legacy alias for TINA4_DATABASE_URL. Prefer TINA4_DATABASE_URL in new projects. |
TINA4_AUTOCOMMIT | true | Standalone writes auto-commit on their own connection (durable + visible across a pool); explicit transactions stay atomic. Set false for strict manual-commit mode. |
TINA4_DB_CACHE | false | Enables in-memory query-result caching for read queries. |
TINA4_DB_CACHE_TTL | 60 | Query cache TTL in seconds when TINA4_DB_CACHE=true. |
TINA4_DB_POOL | 0 | Default connection-pool size used when a caller constructs Database without passing $pool. 0 keeps the single-connection behaviour; values above zero enable pooled adapters lazily. An explicit constructor argument always wins. |
TINA4_MIGRATION_ID | (timestamp) | Override the migration ID used when recording applied migrations. |
CORS#
| Variable | Default | Description |
|---|---|---|
TINA4_CORS_ORIGINS | * | Comma-separated allowed origins. Lock down to real domains in production. |
TINA4_CORS_METHODS | GET,POST,PUT,PATCH,DELETE,OPTIONS | Allowed request methods. |
TINA4_CORS_HEADERS | Content-Type,Authorization,X-Requested-With | Allowed request headers. |
TINA4_CORS_CREDENTIALS | false | Send Access-Control-Allow-Credentials: true. Required for cross-origin cookies. |
TINA4_CORS_MAX_AGE | 600 | Preflight cache lifetime in seconds. |
Security Headers#
| Variable | Default | Description |
|---|---|---|
TINA4_CSP | default-src 'self' | Content-Security-Policy header. |
TINA4_CSRF | true | CSRF token validation on POST/PUT/PATCH/DELETE. Requires _csrf in the body or X-CSRF-Token header. |
TINA4_HSTS | (empty/off) | Strict-Transport-Security max-age in seconds. Set 31536000 in production with HTTPS. |
TINA4_FRAME_OPTIONS | DENY | X-Frame-Options header. Set SAMEORIGIN if you embed your own app in an iframe. |
TINA4_REFERRER_POLICY | strict-origin-when-cross-origin | Referrer-Policy header. |
TINA4_PERMISSIONS_POLICY | (empty) | Permissions-Policy header. Example: geolocation=(), microphone=(). |
Rate Limiting#
| Variable | Default | Description |
|---|---|---|
TINA4_RATE_LIMIT | 100 | Maximum requests per window per IP. Set 0 to disable. |
TINA4_RATE_WINDOW | 60 | Rate-limit window in seconds. |
Sessions#
| Variable | Default | Description |
|---|---|---|
TINA4_SESSION_BACKEND | file | Storage backend. Options: file, redis, valkey, mongo, database. |
TINA4_SESSION_HANDLER | (inherits _BACKEND) | Alternate handler class name. Overrides TINA4_SESSION_BACKEND. |
TINA4_SESSION_NAME | tina4_session | Cookie name written by the framework session manager. Distinct from TINA4_PHP_SESSION_NAME, which controls the native PHP session cookie. |
TINA4_SESSION_TTL | 3600 | Session expiry in seconds. |
TINA4_SESSION_SAMESITE | Lax | SameSite cookie attribute. Options: Strict, Lax, None. |
TINA4_SESSION_HTTPONLY | true | Emit the HttpOnly attribute on the session cookie. Leave on unless JavaScript genuinely needs to read the cookie. |
TINA4_SESSION_SECURE | false | Emit the Secure attribute on the session cookie. Setting TINA4_SESSION_SAMESITE=None forces this to true regardless of the value here. |
TINA4_SESSION_PATH | data/sessions | Filesystem path for the file backend. |
TINA4_PHP_SESSION_NAME | PHPSESSID | Cookie name used by native PHP $_SESSION (separate from the framework session). |
TINA4_PHP_SESSION_PATH | (system temp) | session.save_path for native PHP sessions. The framework configures it before session_start() so the SAPI and the built-in server share session storage. |
Redis/Valkey session backend#
| Variable | Default | Description |
|---|---|---|
TINA4_SESSION_REDIS_HOST | localhost | Redis host. |
TINA4_SESSION_REDIS_PORT | 6379 | Redis port. |
TINA4_SESSION_REDIS_PASSWORD | (none) | Redis auth password. |
TINA4_SESSION_REDIS_DB | 0 | Redis database number. |
TINA4_SESSION_REDIS_URL | (none) | Full redis:// URL. Overrides the individual fields when set. |
TINA4_SESSION_VALKEY_HOST | localhost | Valkey host. |
TINA4_SESSION_VALKEY_PORT | 6379 | Valkey port. |
TINA4_SESSION_VALKEY_PASSWORD | (none) | Valkey auth password. |
TINA4_SESSION_VALKEY_DB | 0 | Valkey database number. |
MongoDB session backend#
| Variable | Default | Description |
|---|---|---|
TINA4_SESSION_MONGO_URL | mongodb://localhost:27017 | MongoDB connection string. |
TINA4_SESSION_MONGO_DB | tina4 | MongoDB database name. |
Templates#
| Variable | Default | Description |
|---|---|---|
TINA4_TEMPLATE_CACHE_TTL | 0 | Lifetime of compiled Frond templates in production, in seconds. 0 means cache forever (no filesystem checks per render); a positive value re-reads and re-tokenises a template once it has been cached for that long. Ignored when TINA4_DEBUG=true; debug mode always re-reads. |
Cache#
| Variable | Default | Description |
|---|---|---|
TINA4_CACHE_BACKEND | memory | Response cache backend. Options: memory, file, redis, valkey, memcached, mongodb, database. Falls back to file if the configured backend is unreachable. |
TINA4_CACHE_DIR | data/cache | Cache directory for the file backend. |
TINA4_CACHE_TTL | 60 | Default cache TTL in seconds. |
TINA4_CACHE_MAX_ENTRIES | 1000 | Maximum cache entries. Oldest entries evicted first. |
TINA4_CACHE_URL | (none) | Connection URL for remote cache backends (e.g. redis://localhost:6379). For database, falls back to TINA4_DATABASE_URL when unset. |
TINA4_CACHE_USERNAME | (none) | Username for the cache backend. May also be embedded in TINA4_CACHE_URL. |
TINA4_CACHE_PASSWORD | (none) | Password for the cache backend. May also be embedded in TINA4_CACHE_URL (e.g. redis://:pass@host). Memcached is unauthenticated. |
Queues#
| Variable | Default | Description |
|---|---|---|
TINA4_QUEUE_BACKEND | file | Queue backend. Options: file, kafka, rabbitmq, mongo, database. |
TINA4_QUEUE_PATH | data/queue | Filesystem path for the file backend. |
TINA4_QUEUE_URL | (none) | Connection URL for remote backends. |
Kafka queue backend#
| Variable | Default | Description |
|---|---|---|
TINA4_KAFKA_BROKERS | localhost:9092 | Comma-separated broker list. |
TINA4_KAFKA_GROUP_ID | tina4_consumer_group | Kafka consumer group ID. |
RabbitMQ queue backend#
| Variable | Default | Description |
|---|---|---|
TINA4_RABBITMQ_HOST | localhost | RabbitMQ host. |
TINA4_RABBITMQ_PORT | 5672 | RabbitMQ port. |
TINA4_RABBITMQ_USERNAME | guest | RabbitMQ username. |
TINA4_RABBITMQ_PASSWORD | guest | RabbitMQ password. |
TINA4_RABBITMQ_VHOST | / | RabbitMQ virtual host. |
MongoDB queue backend#
| Variable | Default | Description |
|---|---|---|
TINA4_MONGO_URI | (none) | Full MongoDB connection string. Overrides host/port when set. |
TINA4_MONGO_HOST | localhost | MongoDB host. |
TINA4_MONGO_PORT | 27017 | MongoDB port. |
TINA4_MONGO_USERNAME | (none) | MongoDB username. |
TINA4_MONGO_PASSWORD | (none) | MongoDB password. |
TINA4_MONGO_DB | tina4 | MongoDB database name. |
TINA4_MONGO_COLLECTION | tina4_queue | MongoDB collection name for jobs. |
WebSocket Backplane#
| Variable | Default | Description |
|---|---|---|
TINA4_WS_BACKPLANE | (none) | Backplane type. Set redis for multi-instance broadcasts. |
TINA4_WS_BACKPLANE_URL | redis://localhost:6379 | Connection URL for the backplane. |
Email#
| Variable | Default | Description |
|---|---|---|
TINA4_MAIL_HOST | (none) | SMTP server hostname. |
TINA4_MAIL_PORT | 587 | SMTP server port. |
TINA4_MAIL_USERNAME | (none) | SMTP authentication username. |
TINA4_MAIL_PASSWORD | (none) | SMTP authentication password. |
TINA4_MAIL_FROM | (none) | Default sender email address. |
TINA4_MAIL_FROM_NAME | (none) | Default sender display name. |
TINA4_MAIL_ENCRYPTION | tls | Connection encryption. Options: tls, ssl, none. |
TINA4_MAIL_IMAP_HOST | (none) | IMAP server for inbound mail. |
TINA4_MAIL_IMAP_PORT | 993 | IMAP server port. |
TINA4_MAIL_IMAP_USERNAME | (none) | IMAP authentication username. |
TINA4_MAIL_IMAP_PASSWORD | (none) | IMAP authentication password. |
TINA4_MAIL_IMAP_ENCRYPTION | tls | IMAP transport encryption. Accepts tls, starttls, or none; any other value is silently coerced back to tls. Independent of TINA4_MAIL_ENCRYPTION so Gmail-style setups can use IMAPS on 993 alongside SMTP STARTTLS on 587. |
TINA4_MAILBOX_DIR | data/mailbox | Dev mailbox directory. All outbound mail lands here when TINA4_DEBUG=true. |
TINA4_MAIL_HOST,TINA4_MAIL_PORT,TINA4_MAIL_USERNAME,TINA4_MAIL_PASSWORDare also accepted as aliases for theTINA4_MAIL_*equivalents. New projects should use theTINA4_MAIL_*names.
Logging#
| Variable | Default | Description |
|---|---|---|
TINA4_LOG_LEVEL | ERROR | Minimum log level written to files. Options: ALL, DEBUG, INFO, WARNING, ERROR. |
TINA4_LOG_DEBUG | 0 | Numeric flag for debug-level messages. Used internally by Debug::message(). |
TINA4_LOG_INFO | 1 | Numeric flag for info-level messages. |
TINA4_LOG_ERROR | 3 | Numeric flag for error-level messages. |
TINA4_LOG_MAX_SIZE | 10485760 | Per-file log size limit in bytes (10 MB). Rotated when exceeded. |
TINA4_LOG_KEEP | 5 | Number of rotated log files to retain. |
Log pipeline (sink, format, rotation)#
Logs default to stdout. Set TINA4_LOG_OUTPUT=file plus TINA4_LOG_FILE=app.log to write to disk; the framework rotates at TINA4_LOG_ROTATE_SIZE bytes and keeps TINA4_LOG_ROTATE_KEEP backups.
| Variable | Default | Description |
|---|---|---|
TINA4_LOG_FILE | (empty = stdout only) | Primary log filename. A relative value is joined with TINA4_LOG_DIR; an absolute path overrides both directory and filename. Leave empty to skip file output entirely. |
TINA4_LOG_DIR | logs | Directory log files are written into when TINA4_LOG_OUTPUT includes file. Created on first write if missing. |
TINA4_LOG_FORMAT | text | Wire format for emitted lines. text is human-readable; json emits one structured object per line for ingestion by Loki, ELK, etc. |
TINA4_LOG_OUTPUT | stdout | Where lines are sent. stdout writes to the process stream (great for systemd / containers), file writes only to TINA4_LOG_FILE, both does both. |
TINA4_LOG_CRITICAL | false | Enable Log::critical() emission. Off by default so security-relevant criticals can be intentionally surfaced rather than buried in routine output. |
TINA4_LOG_ROTATE_SIZE | 10485760 | Rotation threshold in bytes (10 MB default). Set 0 to disable rotation entirely, useful when an external tool (logrotate, Docker driver) owns the file. |
TINA4_LOG_ROTATE_KEEP | 5 | Number of rotated backups to retain. Older files are pruned on rotation. |
Uploads#
| Variable | Default | Description |
|---|---|---|
TINA4_MAX_UPLOAD_SIZE | 10485760 | Maximum multipart upload size in bytes (10 MB). |
Localisation#
| Variable | Default | Description |
|---|---|---|
TINA4_LOCALE | en | Default locale for I18n. |
TINA4_LOCALE_DIR | src/locale | Directory containing locale JSON files. |
Services (background tasks)#
| Variable | Default | Description |
|---|---|---|
TINA4_SERVICE_DIR | src/services | Directory scanned for service classes. |
TINA4_SERVICE_SLEEP | 1 | Default tick interval (seconds) when a service does not specify one. |
AI and MCP Tooling#
The dashboard AI chat and the framework's RAG-based code search both default to a local qwen2.5-coder model served via Ollama. Nothing leaves your machine unless you point TINA4_AI_URL at a remote endpoint.
| Variable | Default | Description |
|---|---|---|
TINA4_AI_URL | http://localhost:11434 | OpenAI-compatible HTTP endpoint for the chat/completion model (Ollama by default). |
TINA4_AI_MODEL | qwen2.5-coder | Model identifier the endpoint should serve. |
TINA4_RAG_URL | (inherits TINA4_AI_URL) | Embedding endpoint for the framework RAG index. |
TINA4_RAG_TOPK | 4 | Number of nearest-neighbour matches the dev dashboard RAG search returns per query. |
TINA4_AI_MODEL | nomic-embed-text | Embedding model used to index the framework and src/. |
TINA4_VISION_URL | http://andrevanzuydam.com:11434 | Vision-model endpoint surfaced by the dev dashboard /__dev/api/vision probe. |
TINA4_EMBED_URL | http://andrevanzuydam.com:11435 | Embeddings endpoint surfaced by the dev dashboard /__dev/api/embed probe. |
TINA4_IMAGE_URL | http://andrevanzuydam.com:11436 | Image-generation endpoint (e.g. SDXL Turbo) for the dev dashboard image tools. |
TINA4_SUPERVISOR_URL | (framework port + 2000) | Override the URL of the Rust agent supervisor that the dev dashboard proxies for /__dev/api/supervise/* and /__dev/api/execute. Defaults to http://127.0.0.1:9145 when TINA4_PORT=7145. |
TINA4_MCP | (inherits TINA4_DEBUG) | Master switch for the MCP subsystem. When unset, follows TINA4_DEBUG: MCP is on in dev and off in prod. Set to false to keep MCP disabled while leaving debug mode on, or to true to expose MCP from a production server (combine with TINA4_MCP_REMOTE if binding off-localhost). |
TINA4_MCP_PORT | (framework port + 2000) | Port the MCP server listens on. Defaults to TINA4_PORT + 2000 (so 7145 → 9145). Set explicitly when running multiple Tina4 instances on the same host. |
TINA4_MCP_REMOTE | false | Allow the MCP server to bind on non-localhost interfaces. Never enable in production. |
TINA4_NO_AI_PORT | false | Disables the MCP port listener in dev mode. |
TINA4_OVERRIDE_CLIENT | false | Allow the framework to start without the Rust CLI (tina4 serve). Used in Docker images and CI runners; bypasses SCSS compilation, the file watcher, and live reload. |
Swagger / OpenAPI#
| Variable | Default | Description |
|---|---|---|
TINA4_SWAGGER_TITLE | Tina4 API | OpenAPI spec title shown in the Swagger UI. |
TINA4_SWAGGER_DESCRIPTION | Auto-generated from Tina4 routes | OpenAPI spec description. |
TINA4_SWAGGER_VERSION | 1.0.0 | OpenAPI spec version. |
TINA4_SWAGGER_ENABLED | (inherits TINA4_DEBUG) | Master switch for Swagger UI and the /swagger//swagger.json routes. When unset, follows TINA4_DEBUG so Swagger is on in dev and off in prod automatically. Set explicitly to expose docs in production. |
TINA4_SWAGGER_CONTACT_EMAIL | (empty) | Contact email written into the generated OpenAPI info.contact block. |
TINA4_SWAGGER_LICENSE | (empty) | License name written into the generated OpenAPI info.license block. |
GraphQL#
| Variable | Default | Description |
|---|---|---|
TINA4_GRAPHQL_ENDPOINT | /graphql | URL path the framework binds the GraphQL handler to. The same value is used when generating __schema links and the dev-dashboard query console URL. |
TINA4_GRAPHQL_AUTO_SCHEMA | true | Auto-generate the GraphQL schema from registered ORM models. Set to false to skip introspection scaffolding when you supply a hand-written schema. |
HTTP Status Constants#
For use in route handlers instead of raw integers:
return $response->json($data, \Tina4\HTTP_CREATED);return $response("<error/>", \Tina4\HTTP_BAD_REQUEST, \Tina4\APPLICATION_XML);See Chapter 3: Request and Response for the full table.
Log-Level Constants#
Passed to Debug::message() to tag severity:
| Constant | Description |
|---|---|
TINA4_LOG_DEBUG | Verbose developer messages. |
TINA4_LOG_INFO | Normal operational messages. |
TINA4_LOG_WARNING | Non-fatal anomalies. |
TINA4_LOG_ERROR | Recoverable errors. |
TINA4_LOG_CRITICAL | Fatal or security-relevant events. |
\Tina4\Debug::message("User " . $id . " missed the cache", TINA4_LOG_INFO);Configuration Recipes#
The tables above list every knob. These are the setups most apps actually reach for, ready to paste into .env. Each block sets only what the feature needs. Everything else keeps its default.
PostgreSQL in production#
One URL points the ORM, the migrations, and the query builder at Postgres. Credentials can ride in the URL or sit in their own variables, which keeps the password out of your shell history.
TINA4_DATABASE_URL=postgresql://localhost:5432/myappTINA4_DATABASE_USERNAME=myappTINA4_DATABASE_PASSWORD=changemeTINA4_DB_POOL=4TINA4_DB_POOL=4 opens four connections and rotates across them. Leave it at 0 for a single connection on a small app.
A shared cache on Redis#
The response cache and the cross-request query cache both speak to the same Redis. Point them at it and every instance shares one cache, invalidated globally on every write.
TINA4_CACHE_BACKEND=redisTINA4_CACHE_URL=redis://localhost:6379TINA4_DB_CACHE=trueTINA4_DB_CACHE_BACKEND=redisTINA4_DB_CACHE_URL=redis://localhost:6379If Redis is down or the driver is missing, the cache logs a warning and falls back to the file backend. It never silently stops caching.
Sessions that survive more than one box#
The file backend is fine for a single server. Move sessions to Redis the moment you run more than one instance, so a user stays logged in whichever instance answers the next request.
TINA4_SESSION_BACKEND=redisTINA4_SESSION_REDIS_HOST=localhostTINA4_SESSION_REDIS_PORT=6379TINA4_SESSION_SECURE=trueTINA4_SESSION_SAMESITE=StrictTINA4_SESSION_SECURE=true keeps the cookie off plain HTTP. Turn it on once you have TLS.
A queue on RabbitMQ or Kafka#
One URL is enough for RabbitMQ; the per-field variables only exist for split configs. The queue API stays identical whichever backend you pick.
TINA4_QUEUE_BACKEND=rabbitmqTINA4_QUEUE_URL=amqp://guest:guest@localhost:5672/Kafka reads a broker list instead:
TINA4_QUEUE_BACKEND=kafkaTINA4_KAFKA_BROKERS=localhost:9092TINA4_KAFKA_GROUP_ID=myapp_workersWebSocket broadcasts across instances#
A single server broadcasts in memory. Add a backplane and a message sent on one instance reaches clients connected to every other instance.
TINA4_WS_BACKPLANE=redisTINA4_WS_BACKPLANE_URL=redis://localhost:6379TINA4_WS_ALLOWED_ORIGINS=https://myapp.comSet the origin allow-list in production. Empty allows every origin, which is fine in dev and risky on the public internet.
Locked-down production headers#
The defaults are already safe. These four tighten the screws for a public site on HTTPS.
TINA4_CORS_ORIGINS=https://myapp.com,https://www.myapp.comTINA4_HSTS=31536000TINA4_FRAME_OPTIONS=DENYTINA4_SESSION_SECURE=trueNever pair TINA4_CORS_CREDENTIALS=true with TINA4_CORS_ORIGINS=*. Name your real origins instead.
The dev dashboard AI, kept local#
The dashboard AI talks to a local model through Ollama by default, so nothing leaves your machine. Point the URLs elsewhere only when you run the hosted Tina4 AI services.
TINA4_AI_URL=http://localhost:11437/api/chatTINA4_AI_MODEL=qwen2.5-coder:14bTINA4_RAG_URL=http://localhost:11438Minimal .env for Development#
TINA4_DEBUG=trueTINA4_LOG_LEVEL=DEBUGTINA4_NO_BROWSER=trueThat is it. Debug mode lights up the Swagger UI, the dev dashboard, detailed error pages, and live reload. Keeping the browser flag on stops a new tab opening every time you save a file.
Minimal .env for Production#
TINA4_SECRET=your-long-random-secret-hereTINA4_DATABASE_URL=postgresql://user:password@db-host:5432/myappTINA4_CORS_ORIGINS=https://myapp.com,https://www.myapp.comTINA4_HSTS=31536000TINA4_MAIL_HOST=smtp.example.comTINA4_MAIL_PORT=587TINA4_MAIL_USERNAME=noreply@myapp.comTINA4_MAIL_PASSWORD=your-smtp-passwordTINA4_MAIL_FROM=noreply@myapp.comNo TINA4_DEBUG. It defaults to false, which is what you want in production. Set a real secret, a real database, locked-down CORS origins, HSTS, and SMTP credentials if you send email. Everything else has a production-appropriate default.