Skip to content

Getting started

Docker deployment

The backend ships with a production Dockerfile and compose.yaml that run one instance on one server: the web app (FrankenPHP, with automatic HTTPS), MySQL, the scheduled jobs and, optionally, a background worker.

Requirements

  • A Linux server with Docker Engine and Docker Compose 2.24 or newer.
  • A domain whose DNS points at the server, and ports 80 and 443 open (the certificate is obtained automatically).

What runs

  • app: the API, admin and vendor panels on ports 80/443. On start it waits for the database, installs it if it is empty, and runs any pending migrations.
  • database: MySQL 8.4, data in the db_data volume.
  • cron: the scheduled jobs; output appears in docker compose logs cron.
  • worker (optional): only needed when MESSENGER_TRANSPORT_DSN=doctrine://default; start it with --profile worker.

The instance's own files stay on the host or in volumes, so rebuilding the image never loses them: .env.local and config/jwt/ in the project folder, uploads in uploads, courier documents in private, certificates in caddy_data.

First start

Always pass -f compose.yaml: it leaves out compose.override.yaml, which is for local development only.

  1. Build the image:

    docker compose -f compose.yaml build
  2. Create the instance configuration, with its secrets, JWT keys, database credentials and the domain:

    touch .env.local
    docker compose -f compose.yaml run --rm --no-deps app php bin/new-instance --docker \
      --url=https://delivery.example.com --brand="Example Delivery" --from-email=noreply@example.com

    The empty .env.local must exist first so Docker mounts it as a file. The command refuses to overwrite an existing instance.

  3. Start everything:

    docker compose -f compose.yaml up -d
  4. Open https://delivery.example.com/install to create the admin account and enter the platform details, then continue with the settings in New client instance.

Updating

git pull            # or unpack the new release
docker compose -f compose.yaml up -d --build

The app container runs any new migrations when it starts.

Backups

  • Database: docker compose -f compose.yaml exec database sh -c 'mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" app' > backup.sql
  • Files: the uploads and private volumes, plus .env.local and config/jwt/. Losing the JWT keys signs every user out; losing .env.local loses the database password.

Useful commands

docker compose -f compose.yaml logs -f app cron
docker compose -f compose.yaml exec app php bin/console about
docker compose -f compose.yaml exec app php bin/console app:account:process-deletions --dry-run

Found a mistake? Tell us.