Core Concepts
System services vs. project containers
Section titled “System services vs. project containers”dde manages two layers of Docker containers:
System services are long-running, shared infrastructure containers managed by system:install. They run independently of any project and are shared across all projects on the machine:
- Traefik — Reverse proxy on ports 80 and 443. Routes traffic to project containers based on labels.
- dnsmasq — DNS server that resolves
*.testdomains to127.0.0.1. Forwards other queries to upstream DNS (default:9.9.9.9,149.112.112.112). - SSH agent — Holds SSH keys and makes them available to project containers via a shared volume.
Project containers are defined in your project’s docker-compose.yml and started/stopped by project:up and project:down. These include your application container(s) and any per-project services (databases, caches, mail).
The supported per-project services are:
| Service | Default version | Default port |
|---|---|---|
| MariaDB | 11.8 | 3306 |
| PostgreSQL | 18.3 | 5432 |
| Valkey | 9 | 6379 |
| Mailpit | latest | 8025 |
Configuration hierarchy
Section titled “Configuration hierarchy”dde resolves configuration values using a layered override chain. Values from higher layers take precedence:
CLI options (highest priority) |Project config (.dde/config.yml) |Global config (~/.dde/config.yml) |Built-in defaults (lowest priority)For example, the MariaDB version resolves as follows:
- If
.dde/config.ymlspecifies an explicit version for the mariadb service, that version is used. - Otherwise, if
~/.dde/config.ymldefines a global service version override, that version is used. - Otherwise, the built-in default (
11.8) is used.
Global config
Section titled “Global config”Located at ~/.dde/config.yml. Controls machine-wide defaults:
output: text # Default output format (text or json)dns: forward: - 9.9.9.9 - 149.112.112.112ssh: keys: [] # SSH key paths to add to the agentservices: mariadb: version: "11.8" postgres: version: "18.3"Project config
Section titled “Project config”Located at .dde/config.yml inside the project root. Controls per-project settings:
name: my-appservices: - name: mariadb version: "11.8" - name: valkeycontainers: web: shell: /bin/bashThe .dde/ directory
Section titled “The .dde/ directory”project:init creates a .dde/ directory in your project root with the following structure:
.dde/ .gitignore # Excludes data/ and snapshots/ from version control config.yml # Project configuration data/ # Persistent data for services (database files, etc.) snapshots/ # Database snapshots hooks/ # Lifecycle hook scripts project.up.pre/ # Runs before project:up project.up.post/ # Runs after project:up project.down.pre/ # Runs before project:down project.down.post/ # Runs after project:down adapters/ # Custom adapter scripts plugins/ # Project-local plugin definitionsThe .gitignore file excludes data/ and snapshots/ so that database files and snapshots are not committed to version control. Everything else — including config.yml, hooks, adapters, and plugins — is intended to be committed and shared with the team.
The dde network
Section titled “The dde network”All project containers and system services are connected to a shared Docker network called dde. This network enables:
- Traefik to discover and route traffic to project containers
- Project containers to reach system services (e.g., the SSH agent)
- Cross-project communication when needed
The network is created automatically by system:install and attached to project containers via the docker-compose override that project:up generates.
Output formats
Section titled “Output formats”Every dde command supports the --output option to control the output format:
text(default) — Human-readable terminal outputjson— Machine-readable JSON, suitable for scripting and CI pipelines
dde project:describe --output=jsonThe default output format can be set globally in ~/.dde/config.yml via the output key.