Overview
These are notes from setting up WordPress with Docker. Nginx is already running on the host side, and an SSL certificate has already been obtained, so WordPress will ride on that setup too.
Related Past Articles
- Connect with PPPoE on Ubuntu 19.10 and open ports.
- [RaspberryPi] I switched from Docomo Hikari to Nuro Hikari, so I stopped using PPPoE and changed to normal port forwarding
- [Raspberry Pi 4] Headless installation of Ubuntu 20.10. How to install without a keyboard or display
- [Raspberry Pi 4] Install Nginx and obtain an SSL server certificate from Let's Encrypt
- [Raspberry Pi 4] Build a mail server with Docker.
- [Raspberry Pi 4] Run WordPress with Docker. ★ You are here
Environment Tested
Raspberry Pi 4 Ubuntu 20.10 (arm64)
$ nginx -v
nginx version: nginx/1.18.0 (Ubuntu)
$ docker –version
Docker version 20.10.2, build 2291f61
$ docker-compose –version
docker-compose version 1.25.0, build unknown
For the WordPress container, I use the Official Image.
The Raspberry Pi that runs WordPress already has ports 80 and 443 open and already has an SSL certificate.
docker-compose.yml
Create docker-compose.yml based on the official site. There was no MySQL 5.7 image for the Raspberry Pi architecture (arm64), so I tried using mysql/mysql-server:latest (MySQL 8.0) as the DB image.
version: '3.1'
services:
wordpress:
image: wordpress
restart: always
ports:
- 127.0.0.1:8080:80 # 8080 が外部に公開されないように 127.0.0.1を追記しています
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wp
volumes:
# - wordpress:/var/www/html
- ./html:/var/www/html
# - ./php.ini:/usr/local/etc/php/php.ini
depends_on:
- db
db:
image: mysql/mysql-server:latest # MySQLのImageを変更
# image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_RANDOM_ROOT_PASSWORD: '1'
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
MYSQL_DATABASE: wp
volumes:
- db:/var/lib/mysql
volumes:
db:
wordpress:
I wanted to edit plugins and themes directly in Emacs, so for convenience I bind-mounted the html folder on the host side, but normally leaving it as a volume is fine. That part is up to your preference.
Start WordPress
Run docker-compose to start the containers.
# コンテナを起動
$ docker-compose up -dAfter it starts, it is bound to port 8080 on the host.
Nginx Settings
Edit /etc/nginx/sites-available/default and expose WordPress externally on ports 80 and 443.
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
Default server configuration
server {
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name nosubject.io;
client_max_body_size 512M;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/nosubject.io/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/nosubject.io/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}Virtual Host configuration for example.com
You can move that to a different file under sites-available/ and symlink that
to sites-enabled/ to enable it.
#server {
listen 80;
listen [::]:80;
server_name example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
#}
server {
if ($host = nosubject.io) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name nosubject.io;</span>
return 404; # managed by Certbot
}
Restart Nginx
Restart it to apply the settings.
$ sudo systemctl restart nginxWordPress is now visible from outside at /. Certbot adds settings that redirect HTTP connections to HTTPS, so also check that the http -> https redirect works correctly.
Summary
I was able to run both the mail server and WordPress with Docker. Since I am using the 8 GB RAM version of the Raspberry Pi 4, it looks like there is still plenty of headroom.
~$ free -h
total used free shared buff/cache available
Mem: 7.6Gi 1.1Gi 5.1Gi 78Mi 1.4Gi 6.4Gi
Swap: 0B 0B 0B

If a Pi 3 with 4 GB existed, that would probably be enough.