Service Adapters
Service adapters are shell scripts that configure services inside Docker containers at startup. They handle tasks like setting the correct user, adjusting file permissions, and updating service configuration to run under the dde user.
How Adapters Work
Section titled “How Adapters Work”When dde starts a project, it overrides each container’s entrypoint with /dde/entrypoint.sh. This entrypoint script:
- Creates the
ddeuser with the host user’s UID/GID (DDE_UID/DDE_GIDenvironment variables) - Detects and configures the login shell
- Runs built-in adapters from
/dde/adapters/(mounted from dde’s resources) - Runs project adapters from
/dde/adapters-project/(mounted from.dde/adapters/) - Executes the original container entrypoint and command
For each adapter script, the entrypoint sources it and calls detect(). If detect() returns 0 (success), configure() is called. Both functions are then cleaned up before processing the next adapter.
Adapter Interface
Section titled “Adapter Interface”Every adapter script must define two shell functions:
detect()
Section titled “detect()”Returns 0 if this adapter applies to the current container. Typically checks for the presence of a binary:
detect() { command -v nginx >/dev/null 2>&1}configure()
Section titled “configure()”Performs the actual configuration. Runs only if detect() returned 0:
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}Built-in Adapters
Section titled “Built-in Adapters”dde ships with three built-in adapters in resources/adapters/:
| Adapter | Detects | Configures |
|---|---|---|
| apache.sh | apache2 or httpd | Updates run user/group to dde |
| nginx.sh | nginx | Updates user directive and directory ownership to dde |
| php-fpm.sh | php-fpm | Updates pool user/group and listen owner/group to dde |
apache.sh
Section titled “apache.sh”Detects apache2 or httpd and updates the run user/group to dde in:
/etc/apache2/envvars(Debian/Ubuntu)/etc/httpd/conf/httpd.conf(Alpine/CentOS)
nginx.sh
Section titled “nginx.sh”Detects nginx and:
- Updates the
userdirective in/etc/nginx/nginx.conftodde - Fixes ownership of
/var/cache/nginx,/var/log/nginx, and/var/run
php-fpm.sh
Section titled “php-fpm.sh”Detects php-fpm and updates the FPM pool configuration (www.conf) to run as dde:
- Sets
user,group,listen.owner, andlisten.groupdirectives - Searches common FPM config paths across distributions
Custom Project Adapters
Section titled “Custom Project Adapters”Place custom adapter scripts in .dde/adapters/ in your project directory. They are automatically mounted into the container at /dde/adapters-project/ and executed after the built-in adapters.
Execution Order
Section titled “Execution Order”- Built-in adapters (
/dde/adapters/*.sh) — alphabetically sorted - Project adapters (
/dde/adapters-project/*.sh) — alphabetically sorted
Use numeric prefixes to control order within each group:
.dde/adapters/ 01-custom-service.sh 02-permissions.shExample: Custom Service Adapter
Section titled “Example: Custom Service Adapter”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}Example: Fix Application Permissions
Section titled “Example: Fix Application Permissions”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}Important Notes
Section titled “Important Notes”- Adapters run as root inside the container (before the process drops to the
ddeuser). - The
configure()function should be idempotent — it may run every time the container starts. - Failures in
configure()are silently caught (configure || true), so a failing adapter does not prevent the container from starting. - Adapter scripts are sourced (not executed), so they share the same shell environment. Functions are cleaned up (
unset -f detect configure) between adapters.