Skip to content

Instantly share code, notes, and snippets.

@nielsmaerten
Last active February 28, 2020 15:53
Show Gist options
  • Save nielsmaerten/d4a12295a5eb280db88853d24c5c74a4 to your computer and use it in GitHub Desktop.
Save nielsmaerten/d4a12295a5eb280db88853d24c5c74a4 to your computer and use it in GitHub Desktop.
Blog Ruben Foquet

Wordpress (with full HTTPS) on Docker

Instuctions and files to set up Wordpress on a simple Docker host.
Wordpress sits behind a HTTPS reverse proxy (nginx) which can be signed by Let's Encrypt.

1. Spin up a new VM on Google Compute Engine:

  • start with a micro instance, we can always increase it later **
  • use Container Optimized OS, and a 10GB disk
  • no need to reserve a static IP, we will use DDNS instead
  • enable deletion protection

2. Connect to the VM using SSH

  • to install docker-compose, run the commands in docker-compose-setup.sh
  • git clone this gist into a folder in the home dir

3. Create a backup schedule

  • use Snapshots to create a backup every night

4. Configure settings

  • edit .env
  • for instructions on creating a Cloudflare API key, check docs of oznu/cloudflare-ddns

5. Spin up the containers

  • docker-compose up [-d]

6. Login to phpmyadmin

  • create a new user 'wordpress' with a secure password

7. Secure Database

  • connect to the mariadb container using docker exec -it db bash
  • run the secure installation script in usr/bin/
    • remote login should still be allowed.
    • do not switch to unix_socket auth

8. Install wordpress

  • you can now visit wordpress over HTTPS and complete the setup
  • when connecting to the db, use these settings:
    • server: db (internal docker hostname)
    • password: cf step 6
    • username & database: wordpress

9. Configure wordpress to work with https proxy

  • after completing the installation, edit wp-config.php in the wordpress mount dir
  • add this line to tell wordpress it's sitting behind an HTTPS proxy:
    if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) { $_SERVER['HTTPS']='on'; }
  • also make sure the configured siteurl starts with https.
    you can either hardcode this in wp-config.php, or set it through the wordpress dashboard (Settings -> General).
    failure to complete this step will result in HTTPS mixed content errors and/or redirect loops.

10. A few notes concerning micro instances **

  • This configuration can run on a Micro (free) GCP instance, but some precautions are needed. Otherwise it will just exhaust rescources without being able to even start
  • Set restart policy of all container to 'no'
  • Use the startup-script to start the containers when the machine boots up
  • Do not use Autoheal
  • Make sure all containers are stable before starting https-portal. Otherwise that one will go into a reboot loop, locking up all resources. And since other containers won't be able to start, you'll have yourself a nice deadlock.
COMPOSE_PROJECT_NAME=ruben-blog
## MARIADB
# On Windows, you'll need to change this to use a docker volume
MARIADB_MOUNT=./mnt/mariadb
MYSQL_ROOT_PASSWORD=set a secure password here!
# CLOUDFLARE DOMAINS
DOMAIN=
WORDPRESS_SUBDOMAIN=
PHPMYADMIN_SUBDOMAIN=
CLOUDFLARE_API_KEY=
mnt/
node_modules/
.tmp/
#!/bin/sh
# From: https://cloud.google.com/community/tutorials/docker-compose-on-container-optimized-os
# Add alias for docker-compose that runs the tool inside a container
echo alias docker-compose="'"'docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD:$PWD" -w="$PWD" docker/compose:1.24.0'"'" >> ~/.bashrc
# Reload to make the alias available
source ~/.bashrc
version: "3.1"
volumes:
mariadb: null
services:
db:
image: "mariadb:10.4.12-bionic"
container_name: mariadb
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
volumes:
- "${MARIADB_MOUNT}:/var/lib/mysql"
healthcheck:
test: ["CMD", "mysqladmin", "ping"]
phpmyadmin:
image: "phpmyadmin/phpmyadmin:5.0"
container_name: phpmyadmin
restart: unless-stopped
depends_on:
- db
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
wordpress:
image: "wordpress:5.3.2-php7.4-apache"
container_name: wordpress
restart: unless-stopped
volumes:
- "./mnt/wordpress:/var/www/html"
- "./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini"
depends_on:
- db
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
https-portal:
image: steveltn/https-portal:1.8.1
container_name: https-portal
ports:
- "80:80"
- "443:443"
restart: unless-stopped
depends_on:
- wordpress
- phpmyadmin
- wp-cloudflare-ddns
- db-cloudflare-ddns
environment:
CLIENT_MAX_BODY_SIZE: 99M
DOMAINS: "${WORDPRESS_SUBDOMAIN}.${DOMAIN} -> http://wordpress:80, ${PHPMYADMIN_SUBDOMAIN}.${DOMAIN} -> http://phpmyadmin:80"
STAGE: local
wp-cloudflare-ddns:
image: oznu/cloudflare-ddns
restart: unless-stopped
container_name: ddns-wordpress
environment:
- API_KEY=${CLOUDFLARE_API_KEY}
- ZONE=${DOMAIN}
- SUBDOMAIN=${WORDPRESS_SUBDOMAIN}
- PROXIED=true
db-cloudflare-ddns:
image: oznu/cloudflare-ddns
restart: unless-stopped
container_name: ddns-database
environment:
- API_KEY=${CLOUDFLARE_API_KEY}
- ZONE=${DOMAIN}
- SUBDOMAIN=${PHPMYADMIN_SUBDOMAIN}
- PROXIED=true
autoheal:
image: willfarrell/autoheal:v0.7.0
container_name: autoheal
restart: unless-stopped
depends_on:
- wordpress
- phpmyadmin
- db
volumes:
- /var/run/docker.sock:/var/run/docker.sock
#!/bin/bash
# Copy this script into a custom metadata field named 'startup-script'
# of the VM that will run this project
# Note that this entire script is optional, and only needed if the restart policy of some containers is set to 'no'.
# This script is handy on 'slow' servers that have trouble starting all containers at once.
# First, shut down all containers so we can start clean
docker kill https-portal
docker kill autoheal
docker stop wordpress
docker stop mariadb
docker stop phpmyadmin
docker stop ddns-wordpress
docker stop ddns-database
# Start containers that have no dependencies on others
docker container start phpmyadmin wordpress mariadb
sleep 3m
# Now start Cloudflare DDNS
docker container start ddns-wordpress ddns-database
sleep 1m
# Finally start https-portal
# It's important this one is started last, because it will go into a reboot loop otherwise, locking up all resources!
docker container start https-portal
# Uploads config for PHP
# Will be mapped to specific files inside wordpress and phpmyadmin containers
file_uploads = On
memory_limit = 500M
upload_max_filesize = 90M
post_max_size = 95M
max_execution_time = 3000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment