Published on

GitLab CI with DDEV: The DDEV Executor

Authors

If you use DDEV locally you know the problem: CI runs in a completely different environment. The GitLab Runner DDEV Executor by Jochen (ochorocho) solves exactly that — it runs every CI/CD job inside its own isolated DDEV environment, directly on your GitLab runner host.

How it works

Each GitLab project gets a dedicated unprivileged Linux user with its own rootless Docker daemon, so projects can't interfere with each other. Temporary tenants for forked MRs keep untrusted code sandboxed. Runs on Linux only (amd64 + arm64, Raspberry Pi 5 is the reference platform).

1) Install

git clone https://gitlab.com/ochorocho/gitlab-runner-ddev-executor.git
cd gitlab-runner-ddev-executor
make install

This builds and installs a patched GitLab Runner binary and walks you through prerequisite setup interactively.

2) Register the runner

gitlab-runner register \
  --executor ddev \
  --url https://gitlab.com \
  --token YOUR_TOKEN

3) Use it in .gitlab-ci.yml

Your pipeline can now call ddev commands directly — the same ones you run locally:

stages:
  - test

test:
  stage: test
  script:
    - ddev composer install
    - ddev exec vendor/bin/phpunit
    - ddev exec php bin/console cache:warmup --env=test

No custom Docker images, no environment variable juggling to replicate what DDEV already handles.

Bonus: Review Apps

The executor has built-in support for GitLab Review Apps. For each MR it spins up a DDEV environment, registers it as a GitLab environment with an auto-assigned hostname, and handles Let's Encrypt TLS automatically. Stop jobs + a systemd timer clean up abandoned environments.

Worth checking out

The gap between local dev and CI is one of the most persistent pain points in web development. This project closes it neatly — if it works in DDEV locally, it works in the pipeline. Give Jochen some stars:

gitlab.com/ochorocho/gitlab-runner-ddev-executor