Deploy

The published image is the same one used in dev — one image, three Compose files. Two prod shapes:

  • Self-hosted prod (VPS / k8s, docker-compose.prod.yml): a published image (read-only, hardened, non-root uid 1000) does a one-shot php artisan migrate --force, then starts the queue worker, scheduler, and Reverb sidecar against a remote libSQL database (Bunny Database, Turso, or your own sqld). These are always-on processes on the self-hosted host, not CaaS sidecars (ADR 0009).
  • CaaS prod (Magic Containers, Cloud Run, Cloudflare): the same image runs the HTTP app + the first-run installer only. No queue / reverb / scheduler containers in the CaaS spec. Point Laravel at a self-hosted or vendor endpoint via QUEUE_CONNECTION and BROADCAST_CONNECTION (see Environment variables).

TLS terminates upstream; the container serves plain HTTP on :8080.

Three paths cover the rest:

  • Magic Containers on Bunny — stateless pods, the /install first-boot flow, and the env wiring Bunny expects.
  • Compose productiondocker-compose.prod.yml, the migrate sidecar, optional bundled sqld, and the Redis profile.
  • Secrets and keysAPP_KEY, Passport PEMs, Bunny Storage S3 env, and INSTALLER_ENABLED.

Nothing is pushed unless you explicitly run build --push with your own registry user. The default docker-compose.build.yml builds linux/amd64 locally and leaves it on the host.

See also

Built by Qcentic