Skip to content

Getting started

Docker deployment

The production image runs FrankenPHP (Caddy with PHP 8.4): it serves the site, gets the HTTPS certificate, compresses responses and caches the built assets and photos. The same image runs the worker.

Files

FileWhat it is
docker/production/DockerfileThree stages: Composer packages without dev tools, the asset build (with THEME when set), the runtime image.
docker/production/CaddyfileThe site on SERVER_NAME, compression, a year of caching for /build and /uploads.
docker/production/entrypoint.shWarms the cache, then starts the server or the worker.
compose.prod.yamlapp (ports 80 and 443), worker, and database (MySQL 8, only with --profile database).
.env.prod.distThe variables to copy into .env.prod (never committed).

Start

cp .env.prod.dist .env.prod     # then fill it in
export SERVER_NAME=market.example.com
docker compose -f compose.prod.yaml --profile database up -d --build
docker compose -f compose.prod.yaml exec app php bin/console app:install

With a managed database, leave out --profile database and point DATABASE_URL at it.

Volumes

VolumeHoldsBack up?
uploadsPhotos when storage is localYes, unless photos are on S3
databaseMySQL data (bundled database)Yes: docker compose -f compose.prod.yaml exec database mysqldump ... every night, or volume snapshots
caddy_dataHTTPS certificatesOptional, they are renewed on their own

A theme

THEME=acme docker compose -f compose.prod.yaml build
docker compose -f compose.prod.yaml up -d

Updating

git pull
docker compose -f compose.prod.yaml build
docker compose -f compose.prod.yaml up -d
docker compose -f compose.prod.yaml exec -e SKIP_BACKUP=1 app bin/update

Back up the database before the last command. up -d restarts the worker on the new image.

Logs

docker compose -f compose.prod.yaml logs -f app
docker compose -f compose.prod.yaml logs -f worker

The application writes JSON logs to var/log/prod.log inside the containers; set SENTRY_DSN to get errors reported.

Found a mistake? Tell us.