Skip to content

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.

When dde starts a project, it overrides each container’s entrypoint with /dde/entrypoint.sh. This entrypoint script:

  1. Creates the dde user with the host user’s UID/GID (DDE_UID/DDE_GID environment variables)
  2. Detects and configures the login shell
  3. Runs built-in adapters from /dde/adapters/ (mounted from dde’s resources)
  4. Runs project adapters from /dde/adapters-project/ (mounted from .dde/adapters/)
  5. 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.

Every adapter script must define two shell functions:

Returns 0 if this adapter applies to the current container. Typically checks for the presence of a binary:

Terminal window
detect() {
command -v nginx >/dev/null 2>&1
}

Performs the actual configuration. Runs only if detect() returned 0:

Terminal window
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
}

dde ships with three built-in adapters in resources/adapters/:

AdapterDetectsConfigures
apache.shapache2 or httpdUpdates run user/group to dde
nginx.shnginxUpdates user directive and directory ownership to dde
php-fpm.shphp-fpmUpdates pool user/group and listen owner/group to dde

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)

Detects nginx and:

  • Updates the user directive in /etc/nginx/nginx.conf to dde
  • Fixes ownership of /var/cache/nginx, /var/log/nginx, and /var/run

Detects php-fpm and updates the FPM pool configuration (www.conf) to run as dde:

  • Sets user, group, listen.owner, and listen.group directives
  • Searches common FPM config paths across distributions

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.

  1. Built-in adapters (/dde/adapters/*.sh) — alphabetically sorted
  2. 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.sh
.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
}
.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
}
  • Adapters run as root inside the container (before the process drops to the dde user).
  • 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.
  • Hooks — scripts that run on the host during project lifecycle events
  • Plugins — custom dde commands