Rasend schnell: Wordpress mit nginx auf Docker


Docker erfreut sich als Containerisierungsplattform immer größerer Beliebtheit und revolutioniert die Art und Weise, wie Anwendungen entwickelt und bereitgestellt werden. Seine weitverbreitete Akzeptanz wird durch die Geschwindigkeit vorangetrieben, die es in den Entwicklungslebenszyklus bringt. Mit dem folgenden Befehl können Sie einen funktionierenden WordPress-Container ausführen:

docker run wordpress:latest

Die Vorteile von Docker liegen in der Fähigkeit, Anwendungen und ihre Abhängigkeiten zu isolieren. Gewährleistung einer konsistenten Bereitstellung in verschiedenen Umgebungen. Dieser Ansatz verbessert die Portabilität, Skalierbarkeit und Ressourceneffizienz und bietet Entwicklern gleichzeitig eine zuverlässige und reproduzierbare Plattform für eine einfache Zusammenarbeit.

Diese Einführung dient als Ausgangspunkt für eine WordPress-Site mit einer einzelnen Instanz.

Anpassen des ofiziellen Images

Ausgangspunkt sind die Dateien aus dem offiziellen github repository. Im Ordner „latest/php8.2/fpm“ finden wir die Docker-Datei, den Docker-Entrypoint und die WordPress-Konfiguration. Letzteres ändern wir, um den wp-cron aus Leistungsgründen zu deaktivieren:

...
/_ That's all, stop editing! Happy publishing. _/
define( 'WP_DISABLE_CRON', true );
...

Erstellen unseres individuellen Imagees

Wir erstellen und taggen das Image mit dem Befehl:

docker build --no-cache -t lemsit/wordpress -f Dockerfile wordpress

NGINX-Konfiguration

Als nächstes müssen wir NGINX so konfigurieren, dass alle Anfragen an den WordPress-Container weitergeleitet werden. Die Konfiguration basiert auf dem 10up WordPress-Server-Configs GitHub repository.

Microcaching

Unter Microcaching versteht man eine Technik, bei der kleine Mengen dynamischer Inhalte für einen sehr kurzen Zeitraum zwischengespeichert werden. Die Idee besteht darin, dynamische Inhalte für einen kurzen Zeitraum, typischerweise einige Millisekunden, zwischenzuspeichern. um nachfolgende Anfragen zu bedienen, ohne den Backend-Server zu erreichen. Dies unterscheidet sich vom herkömmlichen Caching, bei dem statische Inhalte typischerweise für längere Zeiträume zwischengespeichert werden.

In der nginx.conf erstellen wir einen Abschnitt für den Microcache:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
user www-data;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    # Microcaching
    fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=microcache:20m inactive=60m max_size=200m;
    fastcgi_cache_key "$scheme://$host$request_uri";
    fastcgi_ignore_headers Cache-Control Expires;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    server_names_hash_bucket_size 64;

    include /etc/nginx/conf.d/*.conf;

}

nginx-wordpress.conf

Als nächstes benötigen wir eine Serverkonfiguration für NGINX, um unsere Anfrage an den WordPress-Container weiterzuleiten. Dies geschieht in Zeile 40:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
server {
listen 80 default_server;
server_name www.lemsit.de lemsit.de lemsit_wordpress;
root /var/www/html;
index index.php;

        error_log  /var/log/nginx/error.log;
        access_log /var/log/nginx/access.log;

        if (!-e $request_filename) {
                rewrite /wp-admin$ $scheme://$host$uri/ permanent;
                rewrite ^(/[^/]+)?(/wp-.*) $2 last;
                rewrite ^(/[^/]+)?(/.*\.php) $2 last;
        }

        location / {
                try_files $uri $uri/ /index.php?$args ;
        }

        # Microcaching
        #Cache everything by default
        set $no_cache 0;

        #Don't cache logged in users or commenters
        if ( $http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
                set $no_cache 1;
        }

        #Don't cache the following URLs
        if ($request_uri ~* "/(wp-admin/|wp-login.php)")
        {
                set $no_cache 1;
        }
        # /end Microcaching

       location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

                include /etc/nginx/fastcgi_params;

                # If using a socket...
                #fastcgi_pass unix:/tmp/php-fpm.sock;;
                # If using TCP/IP...
                fastcgi_pass wordpress:9000;

                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

                # Microcaching
                #matches keys_zone in fastcgi_cache_path
                fastcgi_cache microcache;

                #don't serve pages defined earlier
                fastcgi_cache_bypass $no_cache;

                #don't cache pages defined earlier
                fastcgi_no_cache $no_cache;

                #defines the default cache time
                fastcgi_cache_valid any 60s;

                #unsure what the impacts of this variable is
                fastcgi_max_temp_file_size 2M;

                #Use stale cache items while updating in the background
                fastcgi_cache_use_stale updating error timeout invalid_header http_500;
                fastcgi_cache_lock on;
                fastcgi_cache_lock_timeout 10s;

                add_header X-Cache $upstream_cache_status;
                # /end Microcaching
        }

        # Set expires time for browser caching for media files
        location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
                access_log off; log_not_found off; expires max;
        }

        # Set expires time for js and css files
        location ~* \.(js|css)$ {
                expires 24h;
                add_header Pragma public;
                add_header Cache-Control "public";
                log_not_found off;
        }

        # Block serving of hidden files
        location ~ /\. { deny  all; access_log off; log_not_found off; }

        # This should match upload_max_filesize in php.ini
        client_max_body_size 20M;

}

Bauen des Stacks

Um unser Image mit Docker Compose oder Docker Swarm ausführen zu können, müssen wir unsere docker-compose.yaml erstellen. Wir müssen 4 Dienste definieren:

  • MariaDB
  • NGINX
  • WordPress
  • cron
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: "3.8"

services:
mariadb:
image: mariadb:latest
restart: always
environment: - MARIADB_ROOT_PASSWORD=secret - MARIADB_DATABASE=wordpress - MARIADB_USER=wordpress - MARIADB_PASSWORD=secret
volumes: - /srv/mariadb/:/var/lib/mysql

wordpress:
image: lemsit/wordpress
restart: always
environment: - WORDPRESS_DB_HOST=mariadb:3306 - WORDPRESS_DB_USER=wordpress - WORDPRESS_DB_PASSWORD=secret - WORDPRESS_DB_NAME=wordpress
volumes: - /srv/wordpress/:/var/www/html

nginx:
image: nginx:latest
ports: - 80:80
volumes: - /srv/docker/nginx.conf:/etc/nginx/nginx.conf - /srv/docker/nginx-wordpress.conf:/etc/nginx/conf.d/default.conf - /srv/wordpress/:/var/www/html

cron:
image: alpine:3.18
command: crond -f -d 8
volumes: - "/srv/docker/crontab:/etc/crontabs/root:z"

Ausführen

Endlich kommt der magischen Moment. Zum Starten des Stapels muss Folgendes ausgeführt werden:

docker compose up

Zum Stoppen:

docker compose down

Das Ergebnis kann auf localhost:80 begutachtet werden.

Wordpress Installer

Abschließende Gedanken

Wie in der Einleitung erwähnt, sollte dieses Setup als Beispiel betrachtet werden, um ein leicht optimiertes WordPress auf Docker mit NGINX auszuführen. Es ist nicht für einen Produktionsstandort gedacht, da es wichtige Aspekte der Sicherung Ihres Datenverkehrs mit TLS nicht abdeckt oder zur Gewährleistung der Ausfallsicherheit in einem Cluster ausgeführt werden.