Containerised Hosting [3/3]: Wordpress

Infrastructure Sep 25, 2020

Hello Everybody! Tansanrao here, Welcome to part 3 of the Containerised Hosting series, today we will be setting up Wordpress to run as a separate stack.

Step 1 - Create a docker compose file

version: "3.3"

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes:
      - mysql:/var/lib/mysql
    command: "--default-authentication-plugin=mysql_native_password"
    networks:
      - private

  wordpress:
    depends_on:
      - mysql
    container_name: wordpress
    restart: unless-stopped
    image: wordpress:5.5.0-php7.4-apache
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=mysql:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    labels:
      - traefik.enable=true
      - traefik.http.middlewares.redirect-websecure.redirectscheme.scheme=https
      - traefik.http.routers.wordpress-web.rule=Host(`example.com`)
      - traefik.http.routers.wordpress-web.entrypoints=web
      - traefik.http.routers.wordpress-web.middlewares=redirect-websecure
      - traefik.http.routers.wordpress-websecure.entrypoints=websecure
      - traefik.http.routers.wordpress-websecure.rule=Host(`example.com`)
      - traefik.tags=traefik-public
      - traefik.docker.network=traefik-public
      - traefik.http.routers.wordpress-websecure.tls=true
      - traefik.http.routers.wordpress-websecure.tls.certresolver=myresolver
    volumes:
      - wordpress:/var/www/html/wp-content
      - ./upload.ini:/usr/local/etc/php/conf.d/uploads.ini
    networks:
      - private
      - traefik-public

volumes:
  wordpress:
  mysql:

networks:
  private:
    driver: bridge
  traefik-public:
    external: true

In the above docker-compose file, we are defining 4 major things, The Database, The Wordpress Install, Persistent Volumes for the 2, and networks for the stack.

We first create the mysql service using the image mysql:8.0. We set the container name, set a restart policy to auto-restart the container unless manually stopped, we tell it to load environment variables from a file called .env, and we assign the persistent volume mysql as shown mysql:/var/lib/mysql. We also pass the command flag "--default-authentication-plugin=mysql_native_password" to force mysql 8.0 to use the older password scheme to maintain compatibility with mysql 5 clients.

Similarly we define the wordpress service, we attach the volume wordpress to wordpress:/var/www/html/wp-content to provide persistence for uploaded content. We also pass in a custom upload.ini file to configure php like so ./upload.ini:/usr/local/etc/php/conf.d/uploads.ini (more on this later).

The Traefik labels attached are explained in Part 2 of this series here.

We then define the required volumes and networks at the end of the file.

Step 2 - Create a .env file

Create a file called .env in the same directory as the docker-compose file

nano .env

Enter the following and make sure you change the passwords

MYSQL_ROOT_PASSWORD=ghost
MYSQL_USER=ghost
MYSQL_PASSWORD=ghost

This file is used to pass on the environment variables without adding credentials in the GitHub repo.

Step 3 - Create upload.ini to override php

Create a file called upload.ini in the same directory as the docker-compose file

nano upload.ini

Enter the following:

file_uploads = On
memory_limit = 512M
upload_max_filesize = 512M
post_max_size = 512M
max_execution_time = 600

This allows Wordpress to accept file uploads up to 500mb in size, and allows php execution to continue for 600 seconds before being killed.

And that’s it!

docker-compose up -d

And you are good to go!

As always, You can refer the repository here for the entire structure and final state of each file.

Follow me on Twitter & Instagram for behind the scenes and updates.

Tags

Tanuj Ravi Rao

99% of the time my brain is thinking blah, meh, why, huh, WTF, food, and computers. The other 1% I’m usually asleep.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.