### Create a project-specific adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-an-adapter.md Example of an adapter located in .dde/adapters/ for application-specific setup tasks. ```bash # .dde/adapters/setup-app.sh detect() { [ -f /var/www/html/composer.json ] } configure() { chown -R dde:dde /var/www/html/var 2>/dev/null || true } ``` -------------------------------- ### Install dependencies before containers start Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/hooks.md Checks for the existence of .env.local and creates it from .env if missing before the project starts. ```bash #!/usr/bin/env bash # .dde/hooks/project.up.pre/01-check-env.sh set -euo pipefail if [ ! -f .env.local ]; then cp .env .env.local echo "Created .env.local from .env" fi ``` -------------------------------- ### Install dde v2 system Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/migration-from-v1.md Initializes the v2 system after the binary has been installed. ```bash dde system:install ``` -------------------------------- ### Create a global plugin example Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/plugin-loader.md A simple example of a global plugin script that accepts arguments. ```bash # ~/.dde/plugins/hello.sh # @command hello # @description Say hello from a plugin echo "Hello from dde plugin!" echo "Arguments: $@" ``` -------------------------------- ### Initialize and Start a Project Source: https://github.com/whatwedo/dde/blob/v2/README.md Commands to configure the system and launch a project environment. ```bash dde system:install cd ~/projects/my-app dde project:init dde project:up ``` -------------------------------- ### Clone and initialize the project Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/development-setup.md Initial steps to clone the repository and install dependencies. ```bash git clone git@github.com:whatwedo/dde.git cd dde composer install bin/console list # Verify it works ``` -------------------------------- ### Install dde-nightly on Fedora, RHEL, Rocky, or AlmaLinux Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Download the repository file and install via dnf. ```bash sudo curl -fsSL https://packages.dde.sh/rpm-nightly/dde-nightly.repo -o /etc/yum.repos.d/dde-nightly.repo sudo dnf install dde-nightly dde system:install ``` -------------------------------- ### Start and verify service status Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-a-service.md Use dde CLI commands to start the project and check the status of running containers. ```bash dde project:up ``` ```bash dde system:status ``` -------------------------------- ### Install dde on Fedora, RHEL, Rocky, or AlmaLinux Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Download the repository configuration file and install using dnf. ```bash sudo curl -fsSL https://packages.dde.sh/rpm/dde.repo -o /etc/yum.repos.d/dde.repo sudo dnf install dde dde system:install ``` -------------------------------- ### Install dde CLI Source: https://github.com/whatwedo/dde/blob/v2/README.md Installation commands for various Linux distributions and macOS. ```bash # macOS brew tap whatwedo/dde && brew install dde # Debian/Ubuntu curl -fsSL https://packages.dde.sh/apt/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/dde.gpg echo "deb [signed-by=/usr/share/keyrings/dde.gpg] https://packages.dde.sh/apt stable main" | sudo tee /etc/apt/sources.list.d/dde.list sudo apt update && sudo apt install dde # Alpine curl -fsSL https://packages.dde.sh/alpine/key.rsa.pub -o /etc/apk/keys/dde.rsa.pub echo "https://packages.dde.sh/alpine" >> /etc/apk/repositories apk add dde # Arch Linux echo -e '\n[dde]\nServer = https://packages.dde.sh/arch/$arch\nSigLevel = Required DatabaseOptional' | sudo tee -a /etc/pacman.conf curl -fsSL https://packages.dde.sh/arch/key.gpg | sudo pacman-key --add - sudo pacman-key --lsign-key "$(curl -fsSL https://packages.dde.sh/arch/key.gpg | gpg --with-colons --import-options show-only --import 2>/dev/null | awk -F: '/^fpr/{print $10; exit}')" sudo pacman -Sy dde ``` -------------------------------- ### Initialize and start a dde project Source: https://github.com/whatwedo/dde/blob/v2/docs/index.md Configure the system environment and launch containers for a specific project. ```bash dde system:install # configure Traefik, dnsmasq, mkcert cd ~/projects/my-app dde project:init # create .dde/config.yml dde project:up # start containers ``` -------------------------------- ### Install dde on Debian/Ubuntu Source: https://github.com/whatwedo/dde/blob/v2/docs/index.md Add the official package repository and install dde using apt. ```bash curl -fsSL https://packages.dde.sh/apt/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/dde.gpg echo "deb [signed-by=/usr/share/keyrings/dde.gpg] https://packages.dde.sh/apt stable main" | sudo tee /etc/apt/sources.list.d/dde.list sudo apt update && sudo apt install dde ``` -------------------------------- ### Install dde on Alpine Linux Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Add the repository key and repository URL to the system configuration before installing. ```bash curl -fsSL https://packages.dde.sh/alpine/key.rsa.pub -o /etc/apk/keys/dde.rsa.pub echo "https://packages.dde.sh/alpine" >> /etc/apk/repositories apk add dde dde system:install ``` -------------------------------- ### Install dde on Arch Linux Source: https://github.com/whatwedo/dde/blob/v2/docs/index.md Configure the pacman repository and install dde. ```bash echo -e '\n[dde]\nServer = https://packages.dde.sh/arch/$arch\nSigLevel = Required DatabaseOptional' | sudo tee -a /etc/pacman.conf curl -fsSL https://packages.dde.sh/arch/key.gpg | sudo pacman-key --add - sudo pacman-key --lsign-key "$(curl -fsSL https://packages.dde.sh/arch/key.gpg | gpg --with-colons --import-options show-only --import 2>/dev/null | awk -F: '/^fpr/{print $10; exit}')" sudo pacman -Sy dde ``` -------------------------------- ### Manage project lifecycle Source: https://github.com/whatwedo/dde/blob/v2/skills/claude/dde/SKILL.md Commands for starting, stopping, and updating the project environment. ```bash dde project:up # Start the project (if already running, no-op) dde project:stop # Stop containers without removing them dde project:down # Stop and remove containers dde project:update # Full rebuild: pull images, rebuild, restart dde project:logs --tail=50 # Show recent logs ``` -------------------------------- ### Run tests plugin Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Example plugin for running a test suite. ```bash #!/usr/bin/env bash # @command test # @description Run the test suite dde project:exec -s web php bin/phpunit ``` -------------------------------- ### Initialize Worktrees with dde Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/worktrees.md Commands to start the project environment within each specific worktree directory. ```bash # Main worktree cd ~/projects/my-app dde project:up # Feature worktree cd ~/projects/my-app-feature-x dde project:up ``` -------------------------------- ### Install dde on Alpine Source: https://github.com/whatwedo/dde/blob/v2/docs/index.md Add the package repository and install dde using apk. ```bash curl -fsSL https://packages.dde.sh/alpine/key.rsa.pub -o /etc/apk/keys/dde.rsa.pub echo "https://packages.dde.sh/alpine" >> /etc/apk/repositories apk add dde ``` -------------------------------- ### Global utility plugin Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Example of a global plugin located in ~/.dde/plugins/. ```bash #!/usr/bin/env bash # @command ports # @description Show all exposed ports for the current project docker compose ps --format "table {{.Name}}\t{{.Ports}}" ``` -------------------------------- ### Initialize project for v2 Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/migration-from-v1.md Configures an existing project for use with dde v2 by creating the necessary directory structure and starting the services. ```bash cd ~/projects/my-app dde project:init dde project:up ``` -------------------------------- ### Install dde-nightly on macOS via Homebrew Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Use Homebrew to tap the repository and install the nightly binary. ```bash brew tap whatwedo/dde brew install dde-nightly dde system:install ``` -------------------------------- ### View port allocation examples Source: https://github.com/whatwedo/dde/blob/v2/docs/services/custom-versions.md Displays the difference between standard port binding for default versions and dynamic allocation for custom versions. ```text 127.0.0.1:3306 (mariadb 11.8, default) ``` ```text 127.0.0.1:10000 (mariadb 10.6) ``` -------------------------------- ### Reset database plugin Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Example plugin for resetting the database with fixtures. ```bash #!/usr/bin/env bash # @command db:reset # @description Drop and recreate database with fixtures set -euo pipefail dde project:exec -s web -- php bin/console doctrine:database:drop --force --if-exists dde project:exec -s web -- php bin/console doctrine:database:create dde project:exec -s web -- php bin/console doctrine:migrations:migrate --no-interaction dde project:exec -s web -- php bin/console doctrine:fixtures:load --no-interaction ``` -------------------------------- ### Lint files plugin Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Example plugin for running multiple linters. ```bash #!/usr/bin/env bash # @command lint # @description Run all linters set -euo pipefail dde project:exec -s web php vendor/bin/ecs check dde project:exec -s web php vendor/bin/phpstan analyse ``` -------------------------------- ### Run database migrations on startup Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/hooks.md Runs database migrations inside the web container after the project has started. ```bash #!/usr/bin/env bash # .dde/hooks/project.up.post/02-migrate.sh set -euo pipefail dde project:exec -s web php bin/console doctrine:migrations:migrate --no-interaction ``` -------------------------------- ### Install dde-nightly on Debian or Ubuntu Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Add the nightly repository and GPG key to APT sources. ```bash curl -fsSL https://packages.dde.sh/apt-nightly/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/dde-nightly.gpg echo "deb [signed-by=/usr/share/keyrings/dde-nightly.gpg] https://packages.dde.sh/apt-nightly stable main" | sudo tee /etc/apt/sources.list.d/dde-nightly.list sudo apt update sudo apt install dde-nightly dde system:install ``` -------------------------------- ### Install dde-nightly on Arch Linux Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Configure pacman.conf and import the repository GPG key. ```bash echo -e '\n[dde-nightly]\nServer = https://packages.dde.sh/arch-nightly/$arch\nSigLevel = Required DatabaseOptional' | sudo tee -a /etc/pacman.conf curl -fsSL https://packages.dde.sh/arch-nightly/key.gpg | sudo pacman-key --add - sudo pacman-key --lsign-key "$(curl -fsSL https://packages.dde.sh/arch-nightly/key.gpg | gpg --with-colons --import-options show-only --import 2>/dev/null | awk -F: '/^fpr/{print $10; exit}')" sudo pacman -Sy dde-nightly dde system:install ``` -------------------------------- ### Invoke a plugin with arguments Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Example of calling a plugin command that accepts arguments. ```bash dde project:web:hash-pw "my-secret-password" ``` -------------------------------- ### Load fixtures after containers start Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/hooks.md Executes doctrine fixtures loading inside the web container after the project has started. ```bash #!/usr/bin/env bash # .dde/hooks/project.up.post/01-load-fixtures.sh set -euo pipefail dde project:exec -s web php bin/console doctrine:fixtures:load --no-interaction ``` -------------------------------- ### Execute a plugin command Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/plugin-loader.md Example usage of a registered plugin command via the dde CLI. ```bash dde project:hello world # Output: # Hello from dde plugin! # Arguments: world ``` -------------------------------- ### Implement nginx.sh adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-an-adapter.md Example of a built-in adapter that detects the nginx binary and updates configuration files and directory ownership. ```bash detect() { command -v nginx >/dev/null 2>&1 } configure() { # Update nginx.conf user directive if [ -f /etc/nginx/nginx.conf ]; then sed -i 's/^user .*/user dde;/' /etc/nginx/nginx.conf fi # Fix cache/log directories for dir in /var/cache/nginx /var/log/nginx /var/run; do [ -d "$dir" ] && chown -R dde:dde "$dir" 2>/dev/null || true done } ``` -------------------------------- ### Install dde on macOS Source: https://github.com/whatwedo/dde/blob/v2/docs/index.md Use Homebrew to install the dde CLI tool on macOS systems. ```bash brew tap whatwedo/dde && brew install dde ``` -------------------------------- ### Docker Compose Service Configuration Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/multi-service-project.md Example configuration for web, worker, scheduler, and local third-party storage services. ```yaml 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"] storage: image: dxflrs/garage:v1.0.1 volumes: - garage_meta:/var/lib/garage/meta - garage_data:/var/lib/garage/data - ./garage.toml:/etc/garage.toml:ro volumes: garage_meta: garage_data: ``` -------------------------------- ### Run multiple branches with Git worktrees Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/worktrees.md Demonstrates the workflow for starting a main project and a feature branch worktree simultaneously. ```bash # Main checkout cd ~/projects/my-app dde project:up # https://my-app.test, DB: my_app # Feature worktree git worktree add ~/projects/my-app-feature-x feature/x cd ~/projects/my-app-feature-x dde project:up # https://feature-x.my-app.test, DB: my_app_feature_x ``` -------------------------------- ### Unit Test Example Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/testing.md A standard unit test class demonstrating dependency mocking and assertion usage. ```php createMock(DockerManager::class); $dockerManager->method('inspect') ->willThrowException(new \RuntimeException('not found')); $userContext = new UserContext(uid: 1000, gid: 1000); $manager = new ImageManager($dockerManager, $userContext); self::assertFalse($manager->hasLabel('nonexistent:latest', 'dde.configured')); } } ``` -------------------------------- ### Install dde-nightly on Alpine Linux Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Add the nightly repository key and repository URL to Alpine package manager. ```bash curl -fsSL https://packages.dde.sh/alpine-nightly/key.rsa.pub -o /etc/apk/keys/dde-nightly.rsa.pub echo "https://packages.dde.sh/alpine-nightly" >> /etc/apk/repositories apk add dde-nightly dde system:install ``` -------------------------------- ### Add Database and Mailer Environment Variables Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md Examples of environment variables added to the web service for database and mailer connectivity. ```yaml services: web: environment: - DATABASE_URL=mysql://root:root@mariadb:3306/myproject ``` ```yaml services: web: environment: - MAILER_DSN=smtp://mailpit:1025 ``` -------------------------------- ### Verify dde installation Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/installation.md Executes a suite of 11 system checks to ensure the environment is correctly configured. ```bash dde system:doctor ``` -------------------------------- ### Seeding the worktree database Source: https://github.com/whatwedo/dde/blob/v2/skills/claude/dde/SKILL.md Commands to initialize the worktree database, either by running an install script or importing a database dump from the main checkout. ```bash dde project:exec make install ``` ```bash # In main: export cd ~/projects/my-app dde project:db:export /tmp/seed.sql # In worktree: import into the auto-named DB cd ~/projects/my-app-feature-x dde project:db:import /tmp/seed.sql ``` -------------------------------- ### Handle service version conflicts Source: https://github.com/whatwedo/dde/blob/v2/docs/services/custom-versions.md Example error message displayed when attempting to run multiple versions of the same service simultaneously. ```text Cannot start dde-mariadb-10.6: service "mariadb" is already running as dde-mariadb-11.8. Stop it first or use the same version. ``` -------------------------------- ### Generate Alpine-based Dockerfile Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/dev-layer-builder.md Dockerfile template for Alpine-based images, installing su-exec and shadow utilities to manage user permissions. ```dockerfile FROM php:8.4-fpm-alpine LABEL dde.configured="true" LABEL dde.project="myproject" USER root RUN apk add --no-cache su-exec shadow \ && addgroup -g 1000 dde || true \ && adduser -u 1000 -G dde -D -h /home/dde dde || true ``` -------------------------------- ### Remove v1 Network Boilerplate Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md Example of the network configuration block removed from docker-compose.yml during project initialization. ```yaml # before project:init networks: default: name: dde external: true ``` -------------------------------- ### Configure Traefik routing labels Source: https://github.com/whatwedo/dde/blob/v2/docs/services/traefik.md Example of the Traefik v3 Docker labels generated automatically by project:init to define routing rules and TLS settings. ```yaml labels: - "traefik.enable=true" - "traefik.http.routers.myapp.rule=Host(`myapp.test`)`" - "traefik.http.routers.myapp.tls=true" ``` -------------------------------- ### Add Traefik Routing Labels Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md Example of Traefik labels added to web services for HTTP/HTTPS traffic routing. ```yaml services: web: labels: - 'traefik.enable=true' - 'traefik.http.routers.myproject-test-web.rule=Host(`myproject.test`)' - 'traefik.http.routers.myproject-test-web-tls.rule=Host(`myproject.test`)' - 'traefik.http.routers.myproject-test-web-tls.tls=true' ``` -------------------------------- ### Add Traefik Load Balancer Port Label Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md Example of the load balancer port label added when VIRTUAL_PORT is specified. ```yaml - 'traefik.http.services.myproject-test-web.loadbalancer.server.port=8080' ``` -------------------------------- ### Hook failure error message format Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/hooks.md Example of the error message displayed when a hook script exits with a non-zero code. ```text Hook "01-load-fixtures.sh" failed with exit code 1: ``` -------------------------------- ### Initialize a new dde project Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/multi-service-project.md Sets up a project directory with specified services and a default container for shell access. ```bash cd ~/projects/my-app dde project:init --name=my-app --services=mariadb,valkey --container=web --shell=bash ``` -------------------------------- ### Build project binaries Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/development-setup.md Commands to build the PHAR or standalone binary. ```bash make build ``` ```bash make build-binary ``` -------------------------------- ### Create a Project Command Class Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-a-command.md Defines a new command class extending AbstractProjectCommand with the required AsCommand attribute. ```php resolveFormatter($output, $input); $config = $this->getResolvedConfig(); $projectDir = $this->getProjectDirectory(); // Your logic here -- delegate to a manager or service return $formatter->success(['message' => 'Done']); } } ``` -------------------------------- ### Configure Entrypoint and Adapters Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md Replaces the container entrypoint and mounts necessary adapter scripts for DDE functionality. ```yaml services: web: user: "0:0" entrypoint: ['/dde/entrypoint.sh'] command: ['/original/entrypoint.sh', 'original-cmd'] volumes: - /path/to/resources/entrypoint.sh:/dde/entrypoint.sh:ro - /path/to/resources/adapters:/dde/adapters:ro ``` ```yaml - /path/to/project/.dde/adapters:/dde/adapters-project:ro ``` -------------------------------- ### Connect to PostgreSQL Source: https://github.com/whatwedo/dde/blob/v2/docs/services/postgresql.md Use these commands to connect to the PostgreSQL instance from either the container network or the host machine. ```bash psql -h postgres -U postgres ``` ```bash psql -h 127.0.0.1 -p 5432 -U postgres ``` -------------------------------- ### Implement a custom service adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/service-adapters.md A sample adapter script that detects supervisord and updates its configuration to run as the dde user. ```bash # .dde/adapters/01-supervisord.sh detect() { command -v supervisord >/dev/null 2>&1 } configure() { # Update supervisord to run programs as dde user if [ -f /etc/supervisor/supervisord.conf ]; then sed -i 's/^user=.*/user=dde/' /etc/supervisor/conf.d/*.conf 2>/dev/null || true fi } ``` -------------------------------- ### Create a custom service adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-an-adapter.md Template for creating a new adapter script in resources/adapters/ to handle service-specific configuration. ```bash # resources/adapters/myservice.sh detect() { # Return 0 if this adapter should run command -v myservice >/dev/null 2>&1 } configure() { # Perform configuration # - Fix file permissions for the dde user # - Update config files to run as dde user # - Create required directories if [ -f /etc/myservice/config.conf ]; then sed -i 's/^user .*/user = dde/' /etc/myservice/config.conf fi chown -R dde:dde /var/lib/myservice 2>/dev/null || true } ``` -------------------------------- ### Connect to Valkey via CLI Source: https://github.com/whatwedo/dde/blob/v2/docs/services/valkey.md Use the standard redis-cli to connect from either the project container or the host machine. ```bash redis-cli -h valkey ``` ```bash redis-cli -h 127.0.0.1 -p 6379 ``` -------------------------------- ### Create a minimal plugin Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md A basic plugin that executes a command in the web container. ```bash #!/usr/bin/env bash # @command hello # @description Say hello from the container dde project:exec -s web echo "Hello from the web container" ``` -------------------------------- ### Describe project with JSON output Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/concepts.md Use the --output flag to retrieve machine-readable project details. ```bash dde project:describe --output=json ``` -------------------------------- ### Configure multi-service projects Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/custom-images.md Demonstrates applying dde to multiple services within a single compose file. ```yaml services: web: image: whatwedo/nginx:v2.6 labels: - 'traefik.enable=true' - 'traefik.http.routers.web.rule=Host(`myapp.test`)' - 'traefik.http.routers.web.tls=true' worker: image: php:8.4-cli command: php bin/console messenger:consume ``` -------------------------------- ### Create a custom Node.js project adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/custom-images.md Defines custom ownership rules for directories like npm cache and node_modules. ```bash # .dde/adapters/node.sh detect() { command -v node >/dev/null 2>&1 } configure() { # Fix ownership of npm cache and app directories for dir in /home/dde/.npm /app/node_modules /app/.next; do [ -d "$dir" ] && chown -R dde:dde "$dir" 2>/dev/null || true done } ``` -------------------------------- ### Load Project Configuration Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/config-loader.md Reads and validates the project-specific configuration file from the provided directory. ```php public function loadProjectConfig(string $projectDir): ProjectConfig ``` -------------------------------- ### Automate Tasks with Project Hooks Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/multi-service-project.md Use hooks to execute commands on the host machine that interact with specific containers after project startup. ```bash #!/usr/bin/env bash # .dde/hooks/project.up.post/01-setup.sh set -euo pipefail # Run migrations in web container dde project:exec -s web php bin/console doctrine:migrations:migrate --no-interaction # Warm up caches in all relevant containers dde project:exec -s web php bin/console cache:warmup dde project:exec -s worker php bin/console cache:warmup ``` -------------------------------- ### Define project configuration Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/configuration.md Place this file at .dde/config.yml in the project root to define project-specific services and container settings. ```yaml name: my-app services: - mariadb - valkey containers: web: shell: zsh ``` -------------------------------- ### Define global configuration Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/configuration.md Create this file at ~/.dde/config.yml to override system-wide defaults for output, browser, DNS, SSH, and service versions. ```yaml # Default output format (text or json) output: text # Browser that `dde project:open` launches the project URL with. # Path or name of an executable that accepts a URL as its argument. # Omit it to use the platform default (open / xdg-open / start). default_browser: /usr/bin/firefox # Upstream DNS servers for non-.test queries dns: forward: - 9.9.9.9 - 149.112.112.112 # SSH keys to load (empty = all keys in ~/.ssh/) ssh: keys: - ~/.ssh/id_ed25519 # Default service versions services: mariadb: version: "11.8" postgres: version: "18.3" valkey: version: "9" ``` -------------------------------- ### Verify adapter execution Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-an-adapter.md Commands to check container logs and access the shell to verify that adapter configurations were applied correctly. ```bash dde project:logs ``` ```bash dde project:shell ``` -------------------------------- ### Manage database snapshots Source: https://github.com/whatwedo/dde/blob/v2/skills/claude/dde/SKILL.md Commands for creating, restoring, and listing fast database snapshots without file-level operations. ```bash dde project:db:snapshot:create --name=before-migration dde project:db:snapshot:restore before-migration dde project:db:snapshot:list ``` -------------------------------- ### Define adapter execution order Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/service-adapters.md Use numeric prefixes in filenames to control the execution sequence of adapter scripts. ```text .dde/adapters/ 01-custom-service.sh 02-permissions.sh ``` -------------------------------- ### Connect to MariaDB from container Source: https://github.com/whatwedo/dde/blob/v2/docs/services/mariadb.md Use the network alias to connect to the MariaDB instance from within a project container. ```bash mysql -h mariadb -u root -proot ``` -------------------------------- ### Implement a permissions fix adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/service-adapters.md A sample adapter script that ensures correct ownership for application directories. ```bash # .dde/adapters/99-permissions.sh detect() { [ -d /var/www ] } configure() { chown -R dde:dde /var/www/var 2>/dev/null || true chown -R dde:dde /var/www/public/uploads 2>/dev/null || true } ``` -------------------------------- ### Create a plugin with arguments Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Passes positional arguments from the command line to the script. ```bash #!/usr/bin/env bash # @command web:hash-pw # @description Generate a password hash dde project:exec -s web -- php bin/console security:hash-password "$1" ``` -------------------------------- ### Connect to MariaDB from host Source: https://github.com/whatwedo/dde/blob/v2/docs/services/mariadb.md Use the exposed port to connect to the MariaDB instance from the host machine. ```bash mysql -h 127.0.0.1 -P 3306 -u root -proot ``` -------------------------------- ### Execute Adapter Scripts Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/entrypoint.md Iterates through adapter scripts in the specified directory, sourcing them and executing their detect and configure functions if applicable. ```sh for adapter in "$DDE_ADAPTERS_DIR"/*.sh; do [ -f "$adapter" ] || continue . "$adapter" if type detect >/dev/null 2>&1 && detect; then configure || true fi unset -f detect configure 2>/dev/null || true done ``` -------------------------------- ### Declare a service in project configuration Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-a-service.md Add the service to the project's .dde/config.yml file. ```yaml services: - name: memcached ``` -------------------------------- ### Configure Ruby/Rails service Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/custom-images.md Uses a multi-stage Dockerfile to build the development environment. ```yaml # docker-compose.yml services: web: build: context: . target: dev volumes: - .:/app labels: - 'traefik.enable=true' - 'traefik.http.routers.web.rule=Host(`myapp.test`)' - 'traefik.http.routers.web.tls=true' - 'traefik.http.services.web.loadbalancer.server.port=3000' ``` ```dockerfile FROM ruby:3.3-slim as base WORKDIR /app FROM base as dev RUN apt-get update && apt-get install -y build-essential libpq-dev ``` -------------------------------- ### Run quality assurance suite Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/development-setup.md Executes the full QA suite including ECS, PHPStan, Rector, and tests. ```bash make qa ``` -------------------------------- ### Define configure() function for service adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/service-adapters.md Performs configuration tasks such as modifying files and updating ownership when the adapter is active. ```bash configure() { # Example: set nginx to run as dde user if [ -f /etc/nginx/nginx.conf ]; then sed -i 's/^user .*/user dde;/' /etc/nginx/nginx.conf fi for dir in /var/cache/nginx /var/log/nginx /var/run; do [ -d "$dir" ] && chown -R dde:dde "$dir" 2>/dev/null || true done } ``` -------------------------------- ### Define detect() function for service adapter Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/service-adapters.md Checks for the presence of a specific binary to determine if the adapter should run. ```bash detect() { command -v nginx >/dev/null 2>&1 } ``` -------------------------------- ### Unit Test for Command Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-a-command.md Template for testing command execution with mocked dependencies. ```php v2.1.0 ``` -------------------------------- ### Define plugin annotations Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Required header comments for all plugin scripts. ```bash # @command # @description ``` -------------------------------- ### Worktree Hostname Pattern Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/worktrees.md The standard format for generated worktree hostnames. ```text ..test ``` -------------------------------- ### Access database shell Source: https://github.com/whatwedo/dde/blob/v2/skills/claude/dde/SKILL.md Opens a shell for the project database. ```bash dde project:db ``` -------------------------------- ### Project Directory Structure Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/multi-service-project.md Standard layout for a multi-service project using dde. ```text my-app/ docker-compose.yml Dockerfile .dde/ config.yml src/ ... ``` -------------------------------- ### Resolve Project Hostname Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/config-loader.md Generates a project hostname, applying worktree suffixes if applicable. ```php public function resolveProjectHostname(string $projectName, ?WorktreeInfo $worktreeInfo): string ``` -------------------------------- ### Resolve and Merge Configuration Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/config-loader.md Merges global and project configurations into a single resolved object. ```php public function resolveConfig(string $projectDir): ResolvedConfig ``` ```php public static function merge(GlobalConfig $global, ProjectConfig $project, array $defaultServiceVersions = []): self ``` -------------------------------- ### Load plugins method signature Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/plugin-loader.md The PluginLoader class uses this method to discover and parse plugins from the filesystem. ```php public function loadPlugins(?string $projectDir = null): array ``` -------------------------------- ### Restart global system services Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/migration-from-v1.md Use these commands to manage global service restarts, either preserving existing containers or performing a full rebuild. ```bash dde system:stop && dde system:up ``` ```bash dde system:update ``` -------------------------------- ### Commit release changes Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/release-process.md Stage and commit the updated changelog and application version with GPG signing and sign-off. ```bash git add CHANGELOG.md src/Application.php git commit -S --signoff -m "chore(release): bump version to v2.1.0" ``` -------------------------------- ### Configure Node.js service in docker-compose.yml Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/custom-images.md Uses an Alpine-based Node.js image with Traefik labels for routing. ```yaml # docker-compose.yml services: web: image: node:20-alpine working_dir: /app volumes: - .:/app command: npm run dev labels: - 'traefik.enable=true' - 'traefik.http.routers.web.rule=Host(`myapp.test`)' - 'traefik.http.routers.web.tls=true' - 'traefik.http.services.web.loadbalancer.server.port=3000' ``` -------------------------------- ### Configure container settings Source: https://github.com/whatwedo/dde/blob/v2/docs/getting-started/configuration.md Override container-specific settings like the shell used by dde project:shell. ```yaml containers: web: shell: zsh # override shell for dde project:shell ``` -------------------------------- ### Generate Debian-based Dockerfile Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/dev-layer-builder.md Dockerfile template for Debian-based images, utilizing shadow binaries to avoid issues with Perl-based user management scripts. ```dockerfile FROM php:8.4-fpm LABEL dde.configured="true" LABEL dde.project="myproject" USER root RUN groupadd -g 1000 dde 2>/dev/null || true; \ useradd -u 1000 -g 1000 -m -d /home/dde -s /bin/sh dde 2>/dev/null || true ``` -------------------------------- ### Run DDE debugging commands Source: https://github.com/whatwedo/dde/blob/v2/skills/claude/dde/SKILL.md Use these commands to verify system health, inspect container logs, and check project status. ```bash dde system:doctor --output=json ``` ```bash dde project:logs --tail=50 ``` ```bash dde project:status --output=json ``` -------------------------------- ### Extract project hostname via JSON output Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/advanced-topics.md Use the --output=json flag to pipe command results into tools like jq for scripting. ```bash dde project:describe --output=json | jq -r '.data.hostname' ``` -------------------------------- ### Remove dde v1 system services Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/migration-from-v1.md Use these commands to stop and remove v1 containers and services. Option A is the recommended approach, while Option B serves as a fallback for manual cleanup. ```bash dde system:destroy ``` ```bash docker rm -f $(docker ps -a --filter "name=dde-" -q) ``` -------------------------------- ### Declare a custom service version Source: https://github.com/whatwedo/dde/blob/v2/docs/services/custom-versions.md Specify a non-default version for a service within the project configuration file. ```yaml services: - name: mariadb version: "10.6" ``` -------------------------------- ### PluginDefinition class structure Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/plugin-loader.md Represents the metadata and path for a discovered plugin. ```php final readonly class PluginDefinition { public function __construct( public string $command, public string $description, public string $scriptPath, ) {} } ``` -------------------------------- ### Register a new service type in ServiceRegistry Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/adding-a-service.md Add the service configuration to the SERVICE_TYPES constant in src/Service/ServiceRegistry.php. ```php private const array SERVICE_TYPES = [ // ... existing services ... 'memcached' => [ 'image' => 'memcached', 'defaultVersion' => '1', 'defaultPort' => 11211, 'dataPath' => 'data', 'dataMount' => '/data', 'environment' => [], ], ]; ``` -------------------------------- ### Execute Commands in Specific Containers Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/multi-service-project.md Use the --service (-s) flag to target specific containers for command execution. ```bash # Run in web container (default, configured via --container in project:init) dde project:exec php bin/console cache:clear # Run in worker container dde project:exec -s worker -- php bin/console messenger:consume --limit=10 # Run in scheduler container dde project:exec -s scheduler cat /etc/crontab ``` -------------------------------- ### Inject Environment Variables Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md Sets user context and SSH agent socket paths for shell-bearing services. ```yaml services: web: environment: DDE_UID: "1000" DDE_GID: "1000" DDE_SHELL: "zsh" SSH_AUTH_SOCK: "/tmp/ssh-agent/socket" ``` -------------------------------- ### Define a namespaced command Source: https://github.com/whatwedo/dde/blob/v2/docs/extending/plugins.md Use colons to group commands logically. ```bash # @command cache:clear # @description Clear all application caches ``` -------------------------------- ### Execute commands in container Source: https://github.com/whatwedo/dde/blob/v2/skills/claude/dde/SKILL.md Run project-dependent commands inside the container environment instead of the host. ```bash dde project:exec ``` ```bash dde project:exec composer install dde project:exec php bin/console cache:clear dde project:exec npm run build dde project:exec python manage.py migrate ``` -------------------------------- ### Test Directory Structure Source: https://github.com/whatwedo/dde/blob/v2/docs/contributing/testing.md The directory layout for tests mirrors the source code structure. ```text tests/ Unit/ Manager/ ImageManagerTest.php ConfigManagerTest.php ... Doctor/ Check/ BinaryPathCheckTest.php ... ... E2E/ ... ``` -------------------------------- ### Docker Compose Command Execution Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md The command structure used by dde to apply user-supplied and system-generated overrides in the correct order. ```bash docker compose \ -f docker-compose.yml \ -f docker-compose.override.yml # user override — optional -f /tmp/dde-override-… # dde runtime overlay — last word up -d ``` -------------------------------- ### Manage global system services Source: https://github.com/whatwedo/dde/blob/v2/skills/claude/dde/SKILL.md Commands to control the lifecycle and health of global services such as Traefik, dnsmasq, and Mailpit. ```bash dde system:status --output=json # Show status of all services dde system:up # Start all services dde system:stop # Stop all dde containers without removing them dde system:down # Stop and remove all services dde system:update # Rebuild global service images and refresh integrations dde system:doctor --output=json # Run health checks ``` -------------------------------- ### View Logs Across Services Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/multi-service-project.md Aggregate logs from all services or filter by a specific container. ```bash # All containers dde project:logs # Specific container dde project:logs -s worker # Follow logs dde project:logs --follow -s worker ``` -------------------------------- ### Configure Traefik Labels for Multiple Web Services Source: https://github.com/whatwedo/dde/blob/v2/docs/guides/multi-service-project.md Define unique host rules for multiple web services to enable automatic TLS certificate management. ```yaml 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' ``` -------------------------------- ### Check for cached dev layer Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/dev-layer-builder.md Verifies if a development image already exists locally for a given project name. ```php public function isLayerCached(string $projectName): bool { return $this->dockerManager->imageExists($this->getDevImageTag($projectName)); } ``` -------------------------------- ### Define Project Networks Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/docker-compose-override.md Configures per-project network isolation using the !override tag to prevent merge conflicts. ```yaml networks: dde-services-myproject: external: true services: web: labels: - 'traefik.docker.network=dde-services-myproject' networks: !override dde-services-myproject: null ``` -------------------------------- ### Define dde image naming convention Source: https://github.com/whatwedo/dde/blob/v2/docs/internals/auto-layer.md The naming pattern for the generated dde image. ```text dde-{projectName}:dev ```