Contao ist ein Content Management System auf PHP-Basis. Die folgenden Hinweise sollen helfen, es mit Hilfe von Docker laufen zu lassen. Das Ergebnis sind 4 getrennte Container:
- PHP mit FPM-Schnittstelle zur Ausführung des Codes
- nginx zur Auslieferung der Webseiten und statischen Dateien
- MariaDB als Datenbank
- Adminer für den einfachen Zugriff auf die Datenbank
Als Voraussetzung habe ich Traefik installiert, um das Verteilen der Zugriffe auf die Container zu routen.
In der Datei Dockerfile-contao wird die PHP-Umgebung bereitgestellt. Zur Vereinfachung verwende ich die Drupal-Bereitstellung.
https://github.com/docker-library/drupal/blob/127ac213294bf7b623cb4cc7507ccd5c60dce082/10.3/php8.3/fpm-alpine3.20/Dockerfile
FROM php:8.3-fpm-alpine3.20
# install the PHP extensions we need
RUN set -eux; \
\
apk add --no-cache --virtual .build-deps \
coreutils \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev \
libwebp-dev \
libzip-dev \
git \
; \
\
docker-php-ext-configure gd \
--with-freetype \
--with-jpeg=/usr/include \
--with-webp \
; \
\
docker-php-ext-install -j "$(nproc)" \
gd \
opcache \
pdo_mysql \
zip \
; \
\
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-network --virtual .drupal-phpexts-rundeps $runDeps; \
apk del --no-network .build-deps
# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN { \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=60'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
RUN set -xe \
&& apk add --update icu \
&& apk add --no-cache --virtual .php-deps make \
&& apk add --no-cache --virtual .build-deps $PHPIZE_DEPS zlib-dev icu-dev \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl \
&& docker-php-ext-enable intl \
&& { find /usr/local/lib -type f -print0 | xargs -0r strip --strip-all -p 2>/dev/null || true; } \
&& apk del .build-deps \
&& rm -rf /tmp/* /usr/local/lib/php/doc/* /var/cache/apk/*
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/
ENV COMPOSER_ALLOW_SUPERUSER 1
WORKDIR /opt/contao
RUN set -eux; \
export COMPOSER_HOME="$(mktemp -d)"; \
composer create-project --no-interaction contao/managed-edition . 5.3; \
chown -R www-data:www-data var; \
# rmdir /var/www/html; \
# ln -sf /opt/contao/public /var/www/html; \
# delete composer cache
rm -rf "$COMPOSER_HOME"
RUN /bin/sh -c "echo php_admin_flag[log_errors] = on >> /usr/local/etc/php-fpm.d/docker.conf"
# vim:set ft=dockerfile:
Die Konfiguration des nginx-Webservers sorgt für die Übergabe aller Anfragen nach PHP-Dateien an den FPM-Prozess. Sonstige Dateien werden direkt ausgeliefert.
server {
server_name localhost;
root /opt/contao/public;
index index.php index.html index.htm;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
try_files $uri /index.php$is_args$args;
}
# Haupt Einstiegspunkt
location ~ ^/index\.php(/|$) {
# the exact FastCGI configuration depends on your environment
fastcgi_pass contao-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
# preview.php und contao-manager.phar.php auch zur Verarbeitung erlauben
location ~ ^/(preview|contao-manager\.phar)\.php(/|$) {
# the exact FastCGI configuration depends on your environment
fastcgi_pass contao-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
#return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
Die Bereitstellung aller Container erfolgt mit docker-compose.
services:
contao-fpm:
image: erikwegner/contao-fpm
build: ./fpm
depends_on:
- database
restart: "no"
volumes:
- ./contao:/opt/contao
labels:
- traefik.enabled=false
networks:
- default
web:
image: nginx:1
depends_on:
- contao-fpm
restart: "no"
volumes:
- ./contao:/opt/contao
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
labels:
- traefik.http.routers.contao.rule=Host(`contao.localhost`)
networks:
- default
- traefik
database:
image: mariadb:11
restart: "no"
environment:
- MARIADB_ROOT_PASSWORD=contao
- MARIADB_DATABASE=contao
- MARIADB_PASSWORD=contao
- MARIADB_USER=contao
volumes:
- ./db_data:/var/lib/mysql:rw
labels:
- traefik.enabled=false
networks:
- default
adminer:
image: adminer
restart: "no"
labels:
- traefik.http.routers.adminer-contao.rule=Host(`adminer-contao.localhost`)
networks:
- default
- traefik
networks:
traefik:
external: true
In der docker-compose-Datei wird das Verzeichnis ./contao dem Container-Verzeichnis /opt/contao zugeordnet. Damit die Inhalte am richtigen Platz landen, wird nach dem Starten der Container die Installation mittels composer wiederholt.
$ sudo chown 82:82 contao
$ docker compose exec -it -u www-data contao-fpm /bin/sh
$ export COMPOSER_HOME="$(mktemp -d)"
$ composer create-project --no-interaction contao/managed-edition . 5.3
$ php vendor/bin/contao-console contao:migrate
$ php vendor/bin/contao-console contao:user:create -u admin -p admin1 --email admin@localhost.local --name admin --language de --admin
Anschließend ist die Installationsseite von contao unter http://contao.localhost/contao/install erreichbar.
Das Image ist auch auf DockerHub zu finden.