Kirby CMS 5 – Docker Installation (getestet & funktionsfähig)
graffiti.bayerwald.social | PHP 8.4-FPM | ImageMagick | ohne Docker-Nginx
Architektur
Internet → Nginx (nativ, Port 443/SSL)
↓ FastCGI (127.0.0.1:9100)
Docker: PHP 8.4-FPM Container
↓ Volume
/opt/docker-apps/kirby/kirby-site/
Kein Nginx-Container notwendig. Host-Nginx kommuniziert direkt per FastCGI mit PHP-FPM.
Schritt 1: Verzeichnisstruktur anlegen
mkdir -p /opt/docker-apps/kirby/{kirby-site,docker,nginx-conf}
cd /opt/docker-apps/kirby
Schritt 2: Dockerfile
Datei: /opt/docker-apps/kirby/docker/Dockerfile
FROM php:8.4-fpm
RUN apt-get update && apt-get install -y \
imagemagick \
libmagickwand-dev \
libmagickcore-dev \
libzip-dev \
libpng-dev \
libjpeg-dev \
libwebp-dev \
libavif-dev \
libfreetype6-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
git \
curl \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd \
--with-freetype \
--with-jpeg \
--with-webp
RUN docker-php-ext-install \
gd \
zip \
mbstring \
xml \
opcache \
exif \
fileinfo
RUN pecl install imagick \
&& docker-php-ext-enable imagick
RUN echo "upload_max_filesize = 64M" >> /usr/local/etc/php/conf.d/kirby.ini \
&& echo "post_max_size = 64M" >> /usr/local/etc/php/conf.d/kirby.ini \
&& echo "memory_limit = 256M" >> /usr/local/etc/php/conf.d/kirby.ini \
&& echo "max_execution_time = 120" >> /usr/local/etc/php/conf.d/kirby.ini
RUN sed -i 's/<policy domain="coder" rights="none" pattern="PDF"/<policy domain="coder" rights="read|write" pattern="PDF"/' \
/etc/ImageMagick-6/policy.xml || true
WORKDIR /var/www/html
CMD ["php-fpm"]
Schritt 3: docker-compose.yml
Datei: /opt/docker-apps/kirby/docker-compose.yml
services:
php:
build:
context: ./docker
dockerfile: Dockerfile
container_name: kirby_php
restart: unless-stopped
volumes:
- ./kirby-site:/var/www/html
ports:
- "127.0.0.1:9100:9000"
user: "33:33"
Schritt 4: Kirby installieren
cd /opt/docker-apps/kirby
# Composer-Container nutzen, platform-check ignorieren
docker run --rm -v $(pwd)/kirby-site:/app composer:latest \
create-project getkirby/starterkit /app --stability=stable \
--ignore-platform-reqs
--ignore-platform-reqs ist nötig weil der Composer-Container nicht dasselbe PHP wie unser Container hat. Die Extensions sind im eigenen Dockerfile korrekt installiert.Schritt 5: Berechtigungen setzen
cd /opt/docker-apps/kirby
# Alles gehört www-data (UID/GID 33)
sudo chown -R 33:33 kirby-site/
sudo find kirby-site/ -type d -exec chmod 755 {} \;
sudo find kirby-site/ -type f -exec chmod 644 {} \;
# Schreibbare Verzeichnisse für PHP-FPM
sudo chmod -R 775 kirby-site/content/
sudo mkdir -p kirby-site/media/
sudo mkdir -p kirby-site/site/cache
sudo mkdir -p kirby-site/site/sessions
sudo chown -R 33:33 kirby-site/media/
sudo chown -R 33:33 kirby-site/site/cache/
sudo chown -R 33:33 kirby-site/site/sessions/
sudo chmod -R 775 kirby-site/media/
sudo chmod -R 775 kirby-site/site/cache/
sudo chmod -R 775 kirby-site/site/sessions/
Schritt 6: Kirby konfigurieren
sudo tee /opt/docker-apps/kirby/kirby-site/site/config/config.php << 'EOF'
<?php
return [
'url' => 'https://graffiti.bayerwald.social',
'thumbs' => [
'driver' => 'im',
'quality' => 85,
],
'debug' => false,
];
EOF
sudo chown 33:33 /opt/docker-apps/kirby/kirby-site/site/config/config.php
Schritt 7: Container bauen und starten
cd /opt/docker-apps/kirby
docker compose up -d --build
# Status prüfen
docker compose ps
docker compose logs php
Schritt 8: Host-Nginx konfigurieren
Datei: /etc/nginx/sites-available/graffiti.bayerwald.social
server {
listen 80;
server_name graffiti.bayerwald.social;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name graffiti.bayerwald.social;
ssl_certificate /etc/letsencrypt/live/graffiti.bayerwald.social/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/graffiti.bayerwald.social/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
root /opt/docker-apps/kirby/kirby-site;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9100;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
}
location ~ ^/(site|kirby|\.git) {
deny all;
return 404;
}
location ~ /\.ht {
deny all;
}
client_max_body_size 64M;
access_log /var/log/nginx/graffiti.bayerwald.social.access.log;
error_log /var/log/nginx/graffiti.bayerwald.social.error.log;
}
ln -s /etc/nginx/sites-available/graffiti.bayerwald.social \
/etc/nginx/sites-enabled/graffiti.bayerwald.social
nginx -t && systemctl reload nginx
Schritt 9: Panel einrichten
Panel-Installer einmalig aktivieren:
sudo tee /opt/docker-apps/kirby/kirby-site/site/config/config.php << 'EOF'
<?php
return [
'url' => 'https://graffiti.bayerwald.social',
'thumbs' => [
'driver' => 'im',
'quality' => 85,
],
'debug' => false,
'panel' => [
'install' => true,
],
];
EOF
sudo chown 33:33 /opt/docker-apps/kirby/kirby-site/site/config/config.php
https://graffiti.bayerwald.social/panel aufrufen → Admin-Account anlegen.
Danach sofort panel.install wieder entfernen:
sudo tee /opt/docker-apps/kirby/kirby-site/site/config/config.php << 'EOF'
<?php
return [
'url' => 'https://graffiti.bayerwald.social',
'thumbs' => [
'driver' => 'im',
'quality' => 85,
],
'debug' => false,
];
EOF
sudo chown 33:33 /opt/docker-apps/kirby/kirby-site/site/config/config.php
Verifizierung
# Container läuft?
docker compose ps
# Port gebunden?
ss -tlnp | grep 9100
# ImageMagick aktiv?
docker exec kirby_php php -r "echo extension_loaded('imagick') ? 'ImageMagick OK' : 'FEHLER'; echo PHP_EOL;"
# Kirby schreibt Thumbnails?
ls -la /opt/docker-apps/kirby/kirby-site/media/
Updates
Kirby updaten (neue Kirby-Version)
cd /opt/docker-apps/kirby
docker run --rm -v $(pwd)/kirby-site:/app composer:latest \
update --ignore-platform-reqs
# Berechtigungen nach Update korrigieren (Composer schreibt als root)
sudo chown -R 33:33 kirby-site/
PHP-Image aktualisieren (PHP 8.4.x Patch)
cd /opt/docker-apps/kirby
docker compose build --no-cache
docker compose up -d
Beides zusammen
cd /opt/docker-apps/kirby
docker run --rm -v $(pwd)/kirby-site:/app composer:latest \
update --ignore-platform-reqs
sudo chown -R 33:33 kirby-site/
docker compose build --no-cache
docker compose up -d
Stolperstellen (Lessons Learned)
| Problem | Ursache | Lösung |
|---|---|---|
| Bilder erscheinen nicht | media/ nicht beschreibbar |
chown 33:33 + chmod 775 auf media/ |
| 502 Bad Gateway | Nginx-Config noch Port 9000 statt 9100 | fastcgi_pass 127.0.0.1:9100 |
| Composer: ext-gd fehlt | Composer-Container ≠ PHP-Container | --ignore-platform-reqs |
| Permission denied beim Schreiben | Dateien gehören root nach Composer-Lauf | Immer sudo chown -R 33:33 nach Composer |
| Panel-Installer deaktiviert | Kirby-Sicherheitsfeature | panel.install => true temporär, danach entfernen |
| Kirby nutzt GD statt ImageMagick | thumbs.driver nicht gesetzt |
config.php mit 'driver' => 'im' |
Kirby 5.4.0 | PHP 8.4-FPM | ImageMagick | Docker Compose | Mai 2026