[Raspberry Pi 4] Run WordPress with Docker

Docker

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
  1. Connect with PPPoE on Ubuntu 19.10 and open ports.
  2. [RaspberryPi] I switched from Docomo Hikari to Nuro Hikari, so I stopped using PPPoE and changed to normal port forwarding
  3. [Raspberry Pi 4] Headless installation of Ubuntu 20.10. How to install without a keyboard or display
  4. [Raspberry Pi 4] Install Nginx and obtain an SSL server certificate from Let's Encrypt
  5. [Raspberry Pi 4] Build a mail server with Docker.
  6. [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 -d

After 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 nginx

WordPress 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
me
Me

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