Guide: Multi-Service Project
This guide covers projects with multiple application containers — for example a web frontend, a background worker, and a scheduler.
Prerequisites
Section titled “Prerequisites”- dde installed and
dde system:doctorpassing
Architecture
Section titled “Architecture”A typical multi-service project has several containers defined in docker-compose.yml, all sharing the same codebase but running different processes:
my-app/ docker-compose.yml Dockerfile .dde/ config.yml src/ ...1. Docker Compose Configuration
Section titled “1. Docker Compose Configuration”services: web: build: context: . target: dev volumes: - .:/var/www labels: - 'traefik.enable=true' - 'traefik.http.routers.web.rule=Host(`my-app.test`)' - 'traefik.http.routers.web.tls=true'
worker: build: context: . target: dev volumes: - .:/var/www command: ["php", "bin/console", "messenger:consume", "async", "--time-limit=3600"]
scheduler: build: context: . target: dev volumes: - .:/var/www command: ["supercronic", "/etc/crontab"]
mariadb: image: mariadb:latest environment: MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: "yes" volumes: - mariadb_data:/var/lib/mysql
valkey: image: valkey/valkey:9-alpine
networks: default: name: dde external: true
volumes: mariadb_data: dde_ssh-agent_socket-dir: external: true2. Initialize the Project
Section titled “2. Initialize the Project”cd ~/projects/my-appdde project:init --name=my-app --services=mariadb,valkey --container=web --shell=bashThe --container=web flag sets web as the default container for dde project:shell and dde project:exec.
3. dde Configuration
Section titled “3. dde Configuration”.dde/config.yml:
name: my-appservices: - mariadb - valkeycontainers: web: shell: bash4. How dde Handles Multiple Services
Section titled “4. How dde Handles Multiple Services”When dde project:up runs, it generates a docker-compose override for every service in the compose file. For each service, the override:
- Sets the entrypoint to
/dde/entrypoint.sh - Mounts the built-in and project adapters
- Sets
DDE_UIDandDDE_GIDenvironment variables - Adds a
dde.managed=truelabel - Preserves the original entrypoint and command from the Docker image
This means all containers (web, worker, scheduler) get the dde user created with matching UID/GID, regardless of which container is set as the default.
5. Execute Commands in Specific Containers
Section titled “5. Execute Commands in Specific Containers”Use the --service (-s) option to target a specific service:
# Run in web container (default, configured via --container in project:init)dde project:exec php bin/console cache:clear
# Run in worker containerdde project:exec -s worker -- php bin/console messenger:consume --limit=10
# Run in scheduler containerdde project:exec -s scheduler cat /etc/crontab6. View Logs Across Services
Section titled “6. View Logs Across Services”# All containersdde project:logs
# Specific containerdde project:logs -s worker
# Follow logsdde project:logs --follow -s worker7. Traefik Labels for Multiple Web Services
Section titled “7. Traefik Labels for Multiple Web Services”If multiple containers serve HTTP traffic, add Traefik labels to each:
services: web: labels: - 'traefik.enable=true' - 'traefik.http.routers.web.rule=Host(`my-app.test`)' - 'traefik.http.routers.web.tls=true'
api: labels: - 'traefik.enable=true' - 'traefik.http.routers.api.rule=Host(`api.my-app.test`)' - 'traefik.http.routers.api.tls=true'Both hostnames receive trusted TLS certificates from dde’s certificate manager.
8. Hooks and Multi-Service Projects
Section titled “8. Hooks and Multi-Service Projects”Hooks run on the host machine and can interact with any container:
#!/usr/bin/env bashset -euo pipefail
# Run migrations in web containerdde project:exec -s web php bin/console doctrine:migrations:migrate --no-interaction
# Warm up caches in all relevant containersdde project:exec -s web php bin/console cache:warmupdde project:exec -s worker php bin/console cache:warmupRelated
Section titled “Related”- Project Lifecycle — up, down, restart commands
- Project Exec — executing commands in containers
- Hooks — lifecycle hook scripts