# Local development env file. install.sh writes ENVIRONMENT=production for # self-hosted installs - keep development here only for the checkout workflow. # Domain Configuration DOMAIN=localhost ACME_EMAIL=admin@localhost ENVIRONMENT=development # Published host ports (change if they collide with other services) HTTP_PORT=3000 API_PORT=8082 POSTGRES_PORT=5432 REDIS_PORT=6379 # Image tag to pull from GHCR (e.g. latest, 0.1.1). Use CONTAINR_BUILD=1 # with install.sh to build from source instead. CONTAINR_VERSION=latest # Database Configuration POSTGRES_DB=containr POSTGRES_USER=containr_user POSTGRES_PASSWORD=your_secure_postgres_password DATABASE_URL=postgres://containr_user:your_secure_postgres_password@localhost:5432/containr?sslmode=disable MAX_CONNECTIONS=25 MAX_IDLE_CONNECTIONS=5 CONN_MAX_LIFETIME=5m CONN_MAX_IDLE_TIME=5m AUTO_MIGRATE=true MIGRATION_LOCK_TIMEOUT=2m SEED_DATA_ON_START=false # Dragonfly Configuration (Redis-compatible cache - REDIS_* names kept for compatibility) REDIS_PASSWORD=your_secure_redis_password REDIS_URL=redis://:your_secure_redis_password@localhost:6379/0 # DRAGONFLY_VERSION=latest # DRAGONFLY_THREADS=1 # DRAGONFLY_MAXMEMORY=256mb # Application Configuration # In production this must be a strong value with at least 32 characters. JWT_SECRET=SuperSecretJWTKey123456789!@#$%^&*() # Encrypts secret env vars at rest. Defaults to JWT_SECRET when unset; # setting it explicitly survives a JWT_SECRET rotation. SECRETS_KEY= # Shared secret for node-agent registration/heartbeat auth. CONTAINR_AGENT_AUTH_TOKEN=replace_with_strong_agent_secret # Optional rotation list (comma-separated). When set, this takes precedence. # CONTAINR_AGENT_AUTH_TOKENS=current_secret,next_secret CORS_ORIGINS=http://localhost:3000,http://localhost:8080 # Optional build-time API URL overrides. Leave empty for the default # same-origin setup - the frontend nginx proxies /api to the backend, which # works from any host or IP without rebuilding the image. # VITE_API_URL=https://api.example.com # VITE_AUTH_URL=https://api.example.com/api/auth AUTH_PORT=3001 # In production this must be true. COOKIE_SECURE=false MAX_REQUEST_BODY_BYTES=10485760 # Better Auth (embedded in backend container, exposed via backend /api/auth proxy) BETTER_AUTH_URL=http://localhost:8082 BETTER_AUTH_SECRET=PLACEHOLDER_BETTER_AUTH_SECRET_CHANGE_ME_32CHARS_MIN BETTER_AUTH_AUTO_MIGRATE=true BETTER_AUTH_INTERNAL_TOKEN=PLACEHOLDER_INTERNAL_AUTH_TOKEN BETTER_AUTH_INTERNAL_URL=http://127.0.0.1:3001/internal/session BETTER_AUTH_PROXY_URL=http://127.0.0.1:3001 # Extra trusted origins (comma-separated). Same-origin traffic is trusted # automatically, so this only needs entries for cross-origin callers. BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000,http://localhost:8082 # Platform owner bootstrap — creates/promotes the admin account on startup. # Keep the real values in a local untracked file, never in committed env files. ADMIN_EMAIL=info@tdvorak.dev ADMIN_PASSWORD= ADMIN_NAME=Platform Admin # Optional explicit auth DB settings (recommended when password contains URL special chars) DB_HOST=postgres DB_PORT=5432 DB_NAME=containr DB_USER=containr_user DB_PASSWORD=your_secure_postgres_password FRONTEND_URL=http://localhost:3000 BACKEND_URL=http://localhost:8082 # OAuth (user auth) - GitHub/Google sign-in is reserved for the managed # offering. Self-hosted installs use email/password only; PLACEHOLDER_* # values are treated as unset and the buttons stay hidden. GITHUB_CLIENT_ID=PLACEHOLDER_GITHUB_OAUTH_CLIENT_ID GITHUB_CLIENT_SECRET=PLACEHOLDER_GITHUB_OAUTH_CLIENT_SECRET GITLAB_CLIENT_ID=PLACEHOLDER_GITLAB_CLIENT_ID GITLAB_CLIENT_SECRET=PLACEHOLDER_GITLAB_CLIENT_SECRET GITLAB_OAUTH_AUTHORIZE_URL=https://gitlab.com/oauth/authorize GITLAB_OAUTH_TOKEN_URL=https://gitlab.com/oauth/token GITLAB_OAUTH_USERINFO_URL=https://gitlab.com/api/v4/user BITBUCKET_CLIENT_ID=PLACEHOLDER_BITBUCKET_CLIENT_ID BITBUCKET_CLIENT_SECRET=PLACEHOLDER_BITBUCKET_CLIENT_SECRET BITBUCKET_OAUTH_AUTHORIZE_URL=https://bitbucket.org/site/oauth2/authorize BITBUCKET_OAUTH_TOKEN_URL=https://bitbucket.org/site/oauth2/access_token BITBUCKET_OAUTH_USERINFO_URL=https://api.bitbucket.org/2.0/user BITBUCKET_OAUTH_EMAILS_URL=https://api.bitbucket.org/2.0/user/emails GITEA_CLIENT_ID=PLACEHOLDER_GITEA_CLIENT_ID GITEA_CLIENT_SECRET=PLACEHOLDER_GITEA_CLIENT_SECRET GITEA_OAUTH_AUTHORIZE_URL=https://gitea.example.com/login/oauth/authorize GITEA_OAUTH_TOKEN_URL=https://gitea.example.com/login/oauth/access_token GITEA_OAUTH_USERINFO_URL=https://gitea.example.com/api/v1/user # GitHub App (repo sync) GITHUB_APP_ID=PLACEHOLDER_GITHUB_APP_ID GITHUB_APP_SLUG=PLACEHOLDER_GITHUB_APP_SLUG GITHUB_APP_PRIVATE_KEY=PLACEHOLDER_GITHUB_APP_PRIVATE_KEY_PEM_ESCAPED GITHUB_APP_BASE_URL=https://api.github.com GITLAB_API_URL=https://gitlab.com/api/v4 GITLAB_BASE_URL=https://gitlab.com BITBUCKET_API_URL=https://api.bitbucket.org/2.0 BITBUCKET_BASE_URL=https://bitbucket.org GITEA_BASE_URL=https://gitea.example.com # Backward compatibility (optional) CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080 # Demo Mode Configuration # true: Limited features for testing/evaluation # false: Full features with no limits DEMO_MODE=false # Traefik Authentication (Basic Auth for dashboard) # Generate with: htpasswd -nb username password TRAEFIK_AUTH=admin:$$apr1$$b8mh8c8v$$KkR8hQZQZQZQZQZQZQZQZ/ # Development convenience: true in local dev, false in production TRAEFIK_API_INSECURE=true # Optional: Cloudflare Tunnel (alternative to domain). Can also be set in-app # under Settings > Platform (in-app value overrides this). # Get token from: https://dash.cloudflare.com/argotunnel CLOUDFLARED_TOKEN=your_cloudflare_tunnel_token_here # Optional: reopen public registration after the owner account exists. # Manageable in-app under Settings > Platform (in-app value overrides this). # SIGNUP_ENABLED=false # Docker socket gid AS SEEN INSIDE containers - lets the backend manage # containers (deployments, cloudflared sidecar). install.sh detects it with a # throwaway container. Modern Docker maps the socket to root: use 0. # Older daemons expose the host docker gid: stat -c %g /var/run/docker.sock DOCKER_GID=0 # Optional: Custom Docker Registry # DOCKER_REGISTRY=your-registry.com # DOCKER_USERNAME=your_username # DOCKER_PASSWORD=your_password # Optional: External Services # SENTRY_DSN=https://your-sentry-dsn # SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/webhook/url # Optional: Debug # DEBUG=true # Optional: trust reverse proxy CIDR (default local Docker bridge used by Traefik) TRUSTED_PROXY_CIDR=172.20.0.0/16 # Optional: audit log retention in days (default 90; 0 disables pruning) # AUDIT_RETENTION_DAYS=90