Minimal, production‑ready Drupal 11 for deployment with Kamal.
Core:
- Based on the official drupal/recommended-project template (Drupal 11).
- Multi‑stage Docker build with serversideup/php (php‑fpm + nginx).
- Includes Drush for CLI administration.
- Redis module pre-required and ready for caching.
Deployment & Ops:
- Production and local Kamal deploy configs.
- Accessories: Redis (prod & local), MySQL (local).
- Persistent volume for
web/sites/default/files. - Serversideup/php exposes
/healthcheck. - Registry configuration + secrets via
.kamal/secrets. - Shell & Drush aliases (e.g.,
kamal drush).
Configuration Management:
- Drupal config synchronization ready (YAML under
config/sync). - Export/import with Drush (
drush cex/drush cim).
Security & Performance:
- Opcache enabled in production (see
PHP_OPCACHE_ENABLE=1). - Non-root runtime (runs as
www-data). - Slim Alpine base images.
Extensible:
- Easy to add accessories (e.g., Redis, DB, search) via Kamal.
- Env‑var driven PHP & Nginx tuning (see Dockerfile).
Install globally:
- Docker (Desktop or CLI)
- Ruby + Kamal gem (
gem install kamal) - A container registry account (Docker Hub, GHCR, etc.)
- A server (key-based SSH reachable).
- A DNS A record pointing to the server.
git clone https://github.com/your-org/kamal-drupal.git
cd kamal-drupalKamal manages secrets under .kamal/. Don’t commit plain text secrets.
Inject secrets at deploy time using one or both methods described below.
If you have to use plain-text secrets, encrypt the secrets file (e.g., with git‑crypt) before committing into version control.
Reference password manager entries in .kamal/secrets instead of raw values.
See example in .kamal/secrets.
- Use
.env.exampleas a template:
cp .env.example .env- Fill values, then export to your shell so Kamal can read them:
set -a; source .env; set +aLocal is for demonstration only and often needs extra tweaking. Prefer a VPS for dev/staging unless necessary.
Add to /etc/hosts for friendly domain:
127.0.0.1 nara.localhost
Build & start locally using the local deploy config:
kamal setup -d local
kamal deploy -d localEnsure DNS for the host in config/deploy.yml (e.g. nara.example.com) points to your server.
kamal setup
kamal deployDefined under env.clear & env.secret in config/deploy*.yml.
Secrets are referenced by name and pulled from .kamal/secrets at deploy time.
Persistent user content:
prod_kamal_drupal_files:/var/www/html/web/sites/default/files
local_kamal_drupal_files:/var/www/html/web/sites/default/files
Back up these volumes for disaster recovery.
Reachable as nara-redis. Redis caching is enabled in settings.kamal.php.
Post‑deploy runs drush deploy to update the DB, import config, and clear caches.
- Code change (e.g. update
composer.json). - Commit & push.
kamal deploy(build, push, update, health check).
Rollback:
kamal app container -p
kamal rollback <image_version_id>Shell into running container:
kamal shell- Kamal docs: https://kamal-deploy.org
- Serversideup PHP image: https://serversideup.net/open-source/docker-php/
- Drush: https://www.drush.org
- Drupal User Guide: https://www.drupal.org/docs/user_guide/en/index.html