Skip to content

Ship the application as two production Docker images - #106

Merged
lyrixx merged 1 commit into
mainfrom
prod
Sep 24, 2026
Merged

lyrixx merged 1 commit into
mainfrom
prod

Conversation

@lyrixx

@lyrixx lyrixx commented Sep 24, 2026

Copy link
Copy Markdown
Member

Ships the application as two self-contained Docker images, built and pushed to GHCR by the CI on every push to main and on every tag:

  • php: php-fpm listening on the unix socket /var/run/php/php-fpm.sock, with the code, the vendors and the compiled assets baked in, APP_ENV=prod. It is also the CLI image (bin/console) for the cron job and the migrations.
  • nginx: the official nginx image with the compiled public/ directory and the site configuration, forwarding PHP requests to that socket.

Both run as non-root users. Everything else (secrets, database, Slack and Google credentials) is provided through environment variables at runtime, and public/uploads must be a volume shared by all the containers.

Other changes:

  • the php-fpm and nginx configuration is shared between the dev frontend container and the production images (services/php/fpm/, services/php/nginx/); the production-only differences live in services/php/prod/. The dev php-fpm listens on the same unix socket, and the dev container exposes port 8080;
  • a prod castor context runs the usual tasks on a dedicated compose stack, to test the images locally: castor build -c prod, castor start -c prod, castor destroy -c prod (see the README);
  • castor docker:push can also push the images themselves with --tag, which is what the new "Build and push production images" workflow does. Images are tagged with the short commit sha, latest on main, and the git tag when there is one.

Two self-contained images, built from new stages of the Dockerfile:
"php" (php-fpm with the code, the vendors and the compiled assets baked
in, APP_ENV=prod, also the CLI image for the cron job and the
migrations) and "nginx" (the official image with the compiled public/
directory). They talk through the php-fpm unix socket shared via a
volume, and run as non-root users. Everything else (secrets, database,
Slack and Google credentials) comes from environment variables at
runtime, and public/uploads must be a shared volume.

The php-fpm and nginx configuration is now shared between the dev
"frontend" container and the production images (php/, nginx/), the
production-only differences living in php/mods-available/app-prod.ini.
The dev php-fpm listens on the same unix socket, and the dev container
exposes port 8080.

A "prod" castor context runs the usual tasks on a dedicated compose
stack (castor build|start|destroy -c prod) to test the images locally,
and `castor docker:push --tag=...` also pushes the images themselves.
The "Build and push production images" workflow does so on every push
to main and on every tag, tagging the images with the short commit sha,
"latest" on main, and the tag name.
@lyrixx
lyrixx merged commit 69eb8c4 into main Sep 24, 2026
1 check passed
@lyrixx
lyrixx deleted the prod branch September 24, 2026 15:51
@lyrixx lyrixx mentioned this pull request Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant