Architecture Overview
dde follows a layered architecture with thin commands, manager-based orchestration, and dependency injection throughout. This document describes the namespace structure and design principles.
Namespace Overview
Section titled “Namespace Overview”Application (App\)
Section titled “Application (App\)”Application— extends Symfony Console Application. Defines the app version (APP_VERSION), filters visible commands toproject:*/system:*prefixes, adds the global--outputoption, and registers plugin commands viaPluginCommandLoader.Kernel— Symfony Kernel with PHAR-aware overrides forgetCacheDir()/getLogDir().
Commands (App\Command\)
Section titled “Commands (App\Command\)”Commands are the CLI entry points. They are thin wrappers that delegate to managers and services.
App\Command\Project\*— project-scoped commands (init, up, down, shell, exec, logs, etc.)App\Command\Project\Database\*— database commands (db, db:export, db:import, db:snapshot:*)App\Command\Project\Service\*— per-project service management (service:list, service:enable, service:disable)App\Command\System\*— system-wide commands (install, update, up, down, restart, status, doctor, cleanup)App\Command\AboutCommand— version and system information
Base classes:
AbstractBaseCommand— root base class, providesFormatterResolverandresolveFormatter()AbstractProjectCommand— adds project directory detection, config resolution, database helpersAbstractSystemCommand— marker base class for system commands
All commands use the #[AsCommand] attribute for registration.
Managers (App\Manager\)
Section titled “Managers (App\Manager\)”Managers contain the core business logic and orchestrate complex operations.
| Manager | Responsibility |
|---|---|
ProjectLifecycleManager | Full project up/down/restart orchestration (services, certs, dev layers, overrides) |
ProjectInitManager | .dde/ directory structure creation during project:init |
DockerComposeManager | Docker Compose CLI calls (up, down, build), override file generation |
DockerManager | Low-level Docker CLI (inspect, network, volume, exec, image operations) |
ImageManager | Image label inspection, dev layer Dockerfile generation, build, cache invalidation |
ConfigManager | YAML config loading, override chain resolution, project directory detection, worktree detection |
DatabaseManager | Database shell, export, import, snapshot management, port resolution |
SystemServiceManager | Versionable service container lifecycle (start, stop, status, port allocation) |
ServiceConfigManager | Service container configuration generation |
CertificateManager | TLS certificate orchestration, domain extraction from compose files |
MkcertManager | mkcert CLI wrapper, certificate generation, Traefik dynamic TLS config, cert registry |
CompletionManager | Shell completion generation and installation |
Services (App\Service\)
Section titled “Services (App\Service\)”System services represent the infrastructure containers managed by system:up/system:down.
ServiceInterface— (not used directly;AbstractSystemServiceis the base)AbstractSystemService— base class with start/stop/status logic viaDockerManagerTraefikService— reverse proxy (ports 80/443), network creation, Traefik config managementDnsmasqService— DNS resolver for.testTLD, image build, resolver file managementSshAgentService— SSH agent socket sharing across containersMailpitService— mail testing serviceServiceRegistry— service type definitions (SERVICE_TYPESconstant), version defaults, port mappings, global service collection
Configuration (App\Config\)
Section titled “Configuration (App\Config\)”GlobalConfig— DTO for~/.dde/config.yml(output format, DNS forward, SSH keys, service versions)ProjectConfig— DTO for.dde/config.yml(project name, services, containers)ResolvedConfig— merged configuration from global + project + defaultsWorktreeInfo— data class for git worktree metadata
Definition (App\Config\Definition\)
Section titled “Definition (App\Config\Definition\)”GlobalConfigDefinition— Symfony TreeBuilder schema for global configProjectConfigDefinition— Symfony TreeBuilder schema for project config
Models (App\Model\)
Section titled “Models (App\Model\)”ContainerConfig— Docker container creation parameters (image, ports, volumes, labels, etc.)ContainerInfo— Running container metadata fromdocker inspectServiceDefinition— service name, version, container name, portsServiceStatus— running/stopped status of a service containerUserContext— host UID/GID for user mapping inside containers
Parsers (App\Parser\)
Section titled “Parsers (App\Parser\)”DockerComposeParser— reads and normalizes docker-compose.yml filesDockerfileParser— extracts information from Dockerfiles (base image, labels)
Modifier (App\Util\DockerComposeModifier)
Section titled “Modifier (App\Util\DockerComposeModifier)”DockerComposeModifier— applies persistent modifications to a project’s docker-compose.yml duringproject:init: externalddenetwork, Traefik labels, SSH-Agent volume mount, database environment variables,VIRTUAL_HOST/VIRTUAL_PORTmigration, v1 build args removal
Adapters (App\Adapter\)
Section titled “Adapters (App\Adapter\)”AdapterRegistry— discovers and provides adapter scripts (built-in fromresources/adapters/and project-specific from.dde/adapters/). Handles PHAR extraction.
Database (App\Database\)
Section titled “Database (App\Database\)”DatabaseAdapterInterface— contract for database-specific operations (DSN generation, shell, export, import)MariaDbAdapter— MariaDB/MySQL implementationPostgresAdapter— PostgreSQL implementationDatabaseAdapterRegistry— maps service names to adapters
Doctor (App\Doctor\)
Section titled “Doctor (App\Doctor\)”CheckInterface— contract for health checks (tagged withdde.doctor_check)CheckResult— check outcome (name, status, message, fixHint)CheckStatus— enum:Ok,Warning,ErrorApp\Doctor\Check\*— 10 concrete check implementations
Events (App\Event\)
Section titled “Events (App\Event\)”AbstractProjectEvent— base class carrying project directoryProjectUpPreEvent,ProjectUpPostEvent— dispatched before/after project:upProjectDownPreEvent,ProjectDownPostEvent— dispatched before/after project:down
Hooks (App\Hook\)
Section titled “Hooks (App\Hook\)”HookRunner— executes shell scripts from.dde/hooks/at lifecycle pointsHookSubscriber— event subscriber that triggersHookRunneron project events
Plugins (App\Plugin\)
Section titled “Plugins (App\Plugin\)”PluginLoader— scans~/.dde/plugins/(global) and.dde/plugins/(project) for annotated shell scriptsPluginDefinition— parsed plugin metadata (command name, description, script path)PluginProxyCommand— wraps a plugin script as a Symfony Console command, registered asproject:exec:{name}PluginCommandLoader— lazy command loader that integrates plugins into the Symfony application
Output (App\Output\)
Section titled “Output (App\Output\)”OutputFormatterInterface— contract for output formatting (success, error, table, isInteractive)TextFormatter— human-readable console output with Symfony stylingJsonFormatter— structured JSON outputFormatterResolver— resolves and caches the active formatter
EventListener (App\EventListener\)
Section titled “EventListener (App\EventListener\)”OutputFormatListener— validates--outputoption and configures the formatter on every command
Utilities (App\Util\)
Section titled “Utilities (App\Util\)”ShellDetectorUtil— detects the current shell (zsh, bash, etc.)TempFileUtil— creates temporary directories/filesUrlOpenerUtil— opens URLs in the default browser (cross-platform)DiffUtil— generates unified diffs for file comparisons
Design Principles
Section titled “Design Principles”- Thin commands: Commands only handle CLI I/O. All logic lives in managers and services.
- Dependency injection: All classes use constructor injection with Symfony autowiring. No static methods or service locators.
#[AsCommand]registration: All commands use the attribute, no manual YAML configuration.symfony/processfor all external calls: Docker, git, mkcert, dig — all external tools are called viaProcess. Noshell_exec()orexec().- Strict types: Every file declares
strict_types=1. - Readonly where possible: Value objects and services use
readonlyproperties. - PHP enums for fixed sets:
CheckStatus, output format options, etc. - Explicit return types: No implicit returns, no mixed returns without reason.