Kirby CMS 5 – Docker Installation (getestet & funktionsfähig)

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