# Control-plane environment for deploy/compose.yml. # # Copy this file and replace every placeholder: # # cp .env.example .env # openssl rand -hex 32 # AJS_MASTER_KEY # # This file holds no real credentials. .env is listed in .gitignore; never # commit a filled-in copy. All values are loopback-only: ajs-accountd and Resin # run with host networking and bind 127.0.0.1, and the dashboard is published on # 127.0.0.1:18081. # --- ajs-accountd ----------------------------------------------------------- # Bearer token for every /v1/* call. The dashboard bundle never embeds it # (VITE_PANEL_TOKEN is refused at build time); keep the token server-side and # terminate real authentication in a BFF or reverse proxy. # Generate a real one before the first deploy — the daemon refuses the # documented placeholder values ("change-me", "admin", "test", ...) and any # token shorter than 32 characters at startup unless AJS_ALLOW_INSECURE=1: # openssl rand -hex 32 AJS_ADMIN_TOKEN=replace-me-with-openssl-rand-hex-32 # 32-byte AES-256-GCM key for account-password sealing, as 64 hex characters. # Generate with: openssl rand -hex 32 # Leave empty to disable at-rest sealing (account passwords are then discarded). AJS_MASTER_KEY= # Browser origin allowed to call the API: the dashboard published on 18081. # Add http://127.0.0.1:18082 when using the standalone vite preview live build. AJS_CORS_ORIGINS=http://127.0.0.1:18081 # Exact browser origins allowed on unsafe admin requests. Defaults to # AJS_CORS_ORIGINS when empty; non-browser clients must send X-AJS-CSRF: 1. AJS_ADMIN_ORIGINS=http://127.0.0.1:18081 # --- optional HTTPS admin listener (AJS-276) -------------------------------- # The plaintext listener on AJS_LISTEN keeps working. Setting BOTH AJS_TLS_CERT # and AJS_TLS_KEY adds a second, HTTPS listener that serves the same routes # with the same bearer auth; only the transport changes. # Files are read inside the container, where compose.yml mounts ./certs at # /certs read-only. Put fullchain.pem and privkey.pem there (*.pem is # gitignored). A partial configuration — one of the pair, or a listen address # without the pair — aborts startup instead of silently serving plaintext. # TLS 1.2+ only; every response carries HSTS max-age=31536000. # Uncomment all three (or at least the first two) to enable: #AJS_TLS_CERT=/certs/fullchain.pem #AJS_TLS_KEY=/certs/privkey.pem # 0.0.0.0:2262 publishes the API on every interface (bearer auth still # applies); 127.0.0.1:2262 keeps it on the host. Default: 127.0.0.1:2262. #AJS_TLS_LISTEN=0.0.0.0:2262 # --- Resin integration ------------------------------------------------------ # Empty AJS_RESIN_ADMIN_TOKEN disables the integration; the daemon then serves # the store-only panel contract. AJS_RESIN_URL=http://127.0.0.1:2260 AJS_RESIN_ADMIN_TOKEN= # --- release images (compose.release.yml, update.sh) ------------------------- # GHCR namespace the release workflow pushes to: ghcr.io//ajs-*. # Defaults to dwgx when unset; the GitHub owner name is lowercase. AJS_GHCR_OWNER=dwgx # GHCR tag to deploy: a release tag (v0.1.0) or latest. update.sh --tag # overrides this without editing the file. AJS_IMAGE_TAG=latest # --- dashboard build -------------------------------------------------------- # Vite bakes these into the bundle at image build time; changing them requires # `docker compose build dashboard`. # false = live mode against VITE_API_BASE. The image refuses mock builds: # the deterministic mock console is a development mode (`npm run dev`). # VITE_PANEL_TOKEN is deliberately not a build argument. A VITE_* token would # be readable by anyone who can fetch the bundle; nginx or a BFF injects auth. VITE_USE_MOCK=false VITE_API_BASE=http://127.0.0.1:2261 # --- Resin service (resin profile) ------------------------------------------ # These two are the only values the Resin container receives: compose.yml # passes them explicitly instead of sharing this whole file, so the third-party # image never sees AJS_MASTER_KEY or AJS_ADMIN_TOKEN. # Admin token for the Resin admin API on 127.0.0.1:2260. Must match # AJS_RESIN_ADMIN_TOKEN above for the daemon's Resin integration to work. RESIN_ADMIN_TOKEN= # SOCKS5 credential Resin expects from proxy clients. RESIN_PROXY_TOKEN=