Run multiple WordPress containers with docker on a single machine

By | March 3, 2019

I’m hosting my 10+ year old blog and another two family blogs on a Windows machine on Azure for many years. It’s running with WIMP (Windows, IIS, MySQL, PHP) Stack. Windows machine is costly and hard to maintain ( Windows updates 🙂 ). After some time, because it’s mysql and php, and deployed in some folder which I almost forgot, I am a little bit fear to touch them so just let them running, for years.

Recently I work a lot with docker and I believe docker will be the deployment standard (at least web application). I finally migrate all the blogs to a Linux machine with docker.

The migration experience was quite smooth and simple, here are the steps:

Backup

  • Export all the data from old hosting, save to some folder for later import.

Infrastructure Preparation

  1. Create one GNU/Linux machine (I use Ubuntu).
  2. Install docker. You can install with official script: https://github.com/docker/docker-install
  3. Install docker-compose (Compose is a tool for defining and running multi-container Docker applications): https://docs.docker.com/compose/install/

Environment Design

Since I have multiple blogs to host on a single machine, a reverse proxy is needed to forward different domain request to different upstream containers. I chose Nginx, it’s quite easy to configure.

I have 3 blogs (let’s say blog1, blog2, blog3) so there will be 5 containers:

  1. CONTAINER1: mysql
  2. CONTAINER2: nginx
  3. CONTAINER3: jinweijie
  4. CONTAINER4: jinweijie-blog1
  5. CONTAINER5: jinweijie-blog2

Environment Diagram:

Deployment

1. Write an nginx.conf

events { worker_connections 1024; }

http {
    # this part is www redirect
    server {
      server_name jinweijie.com;

      listen 80;
      return 301 http://www.jinweijie.com$request_uri;
    }


    server {
        server_name www.jinweijie.com;

        listen 80;
        location / {
            proxy_set_header   Host $host;
            proxy_pass http://jinweijie:80;
        }
    }

    server {
      server_name jinweijie-blog1.com;

      listen 80;
      return 301 http://www.jinweijie-blog1.com$request_uri;
    }


    server {
        server_name www.jinweijie-blog1.com;

        listen 80;
        location / {
            proxy_set_header   Host $host;
            proxy_pass http://jinweijie-blog1:80;
        }
    }

    server {
      server_name jinweijie-blog2.com;

      listen 80;
      return 301 http://www.jinweijie-blog2.com$request_uri;
    }


    server {
        server_name www.jinweijie-blog2.com;

        listen 80;
        location / {
            proxy_set_header   Host $host;
            proxy_pass http://jinweijie-blog2:80;
        }
    }
}

2. Write the Dockerfile for Nginx, simple, just use the official Nginx docker image and copy the nginx.conf

FROM nginx AS runtime-nginx
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf

3. Write the docker-compose.yml

version: "3.7"
services:
  site-db:
    image: mysql:5.7
    volumes:
      - /home/ubuntu/sites/mysql:/var/lib/mysql
    networks:
      - site-net
    environment:
      MYSQL_ROOT_PASSWORD: [YOUR_DB_PASSWORD]
      MYSQL_USER: [YOUR_DB_USER]
      MYSQL_PASSWORD: [YOUR_DB_PASSWORD]
    restart: always
    ports: 
      - 3306:3306
  nginx:
    build:
      context: .
      target: runtime-nginx
      dockerfile: nginx/Dockerfile
    image: jinweijiedocker/personal-sites-nginx
    depends_on:
      - jinweijie
      - jinweijie-blog1
      - jinweijie-blog2
    networks:
      - site-net
    ports:
      - "80:80"
  jinweijie:
    depends_on:
       - site-db
    image: wordpress:5.0
    networks:
      - site-net
    restart: always
    environment:
      WORDPRESS_DB_NAME: jinweijie
      WORDPRESS_DB_HOST: site-db:3306
      WORDPRESS_DB_USER: [YOUR_DB_USER]
      WORDPRESS_DB_PASSWORD: [YOUR_DB_PASSWORD]
    working_dir: /var/www/html
    volumes:
      - /home/ubuntu/sites/jinweijie:/var/www/html
  jinweijie-blog1:
    depends_on:
       - site-db
    image: wordpress:5.0
    networks:
      - site-net
    restart: always
    environment:
      WORDPRESS_DB_NAME: jinweijie-blog1
      WORDPRESS_DB_HOST: site-db:3306
      WORDPRESS_DB_USER: [YOUR_DB_USER]
      WORDPRESS_DB_PASSWORD: [YOUR_DB_PASSWORD]
    working_dir: /var/www/html
    volumes:
      - /home/ubuntu/sites/jinweijie-blog1:/var/www/html
  jinweijie-blog2:
    depends_on:
       - site-db
    image: wordpress:5.0
    networks:
      - site-net
    restart: always
    environment:
      WORDPRESS_DB_NAME: jinweijie-blog2
      WORDPRESS_DB_HOST: site-db:3306
      WORDPRESS_DB_USER: [YOUR_DB_USER]
      WORDPRESS_DB_PASSWORD: [YOUR_DB_PASSWORD]
    working_dir: /var/www/html
    volumes:
      - /home/ubuntu/sites/jinweijie-blog2:/var/www/html
networks:
  site-net:
    driver: bridge

4. Run the command to spin up the whole environment:

sudo docker-compose up -d

5. Import the old backup to new WordPress environment.

That’s it. Hope it helps if you are also trying to use docker to deployment some applications. 🙂