So I decided to start Site Monki blog where I will be sharing on updates, announcements from Site Monki product and how-tos around web monitoring, performance and security. I think beyond the application, this content will add more value to Site Monki users.
I decided that the product blog should be a subdirectory under the sitemonki domain at sitemonki.com/blog. The URL structure has direct benefits in SEO but also I don’t have to create a subdomain just to run a blog. I have decided to go with WordPress because it’s a really fantastic CMS I have used for years.
Running sitemonki.com/blog means I have to run the blog on the same server as the Site Monki App. The main App is already on Docker containers, so I thought it wise to run WordPress on Docker containers too. This way, I don’t really change anything on the host server. Plus I have the added benefit of easily deploying, backing up and migrating both services easily when they are containerized.
First thing we need is a reverse proxy. This will route HTTP requests from web browser to corresponding services. Nginx is an excellent choice.
NGINX configuration for reverse proxying is quite easy to follow and you can read more on the official site but the part we are interested in is this;
# proxy configures proxy_set_header X-Real-IP $remote_addr; proxy_set_header HOST $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-HTTPS-Protocol $ssl_protocol; proxy_set_header X-NginX-Proxy true; # wordpress service location /blog { proxy_pass http://127.0.0.1:5050; }
We are really forwarding the remote IP, hostname, http protocol scheme (http or https) to the WordPress container which exposes port 5050. Nginx will reverse proxies all requests to Apache running inside the WordPress container we shall talk about shortly.
Now comes the interesting part; running WordPress as a container. I assume you already have some basic knowledge of Docker and how to install it. If you don’t, then Docker website has some really good documentation you can follow.
I use docker-compose to define services we need to run WordPress. First is the database service which we run from Mysql 5.7 image. I run a healthcheck to ensure that MySQL container is running before other services that depend on it start. Without this check, WordPress will start and complain that it can’t connect to the database. The MySQL container is attached to a docker named volume sm_blog_mysql_data so we don’t lose our data on container rebuilds.
Then I also use the official WordPress container. The default tag comes with PHP 7.1 and Apache. We define WordPress Host, User, Password and DB name as environment variables. More variables are supported and you can find out more on the image page on docker hub.
Also notice that I am syncing the whole wordpress folder from the host server at /home/dave/blog/ to the wordpress container at /var/www/html/blog. This is because containers are ephemeral which means data is lost once the container is rebuilt or deleted. To prevent that and enable easy changes to the wordpress site, I use Docker unnamed volume which you can read about here.
docker-compose.yml file below defines all these services. All I have to do now is run “docker-compose up” command to bring up the site which is accessible at https://sitemonki.com/blog.
version: '2.1' services: wordpress: image: wordpress restart: always ports: - 5050:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: example WORDPRESS_DB_PASSWORD: example WORDPRESS_DB_NAME: example volumes: - /home/dave/blog/:/var/www/html/blog depends_on: db: condition: service_healthy db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: example MYSQL_USER: example MYSQL_PASSWORD: example MYSQL_RANDOM_ROOT_PASSWORD: '1' healthcheck: test: ["CMD", "mysqladmin", "-u$MYSQL_USER", "-p$MYSQL_PASSWORD", "ping", "-h", "localhost"] timeout: 20s retries: 10 volumes: - sm_blog_mysql_data:/var/lib/mysql phpmyadmin: image: phpmyadmin/phpmyadmin ports: - 8282:80 restart: always environment: MYSQL_USERNAME: example MYSQL_ROOT_PASSWORD: example PMA_HOST: db PMA_PORT: 3306 PMA_ARBITRARY: 1 volumes: - /sessions depends_on: db: condition: service_healthy volumes: sm_blog_mysql_data:
Bonus but optional container is phpmyadmin which I use to view, create and delete records on the wordpress database. I Simply have to open 8282, the port it’s running on via the firewall and access it as sitemonki.com:8282.
So that’s it. If I choose to move the site to another host, I simply have to git pull the codebase from github or wherever and then run “docker-compose up” after install Nginx on the host server. That’s really a breeze and that’s the advantage of Docker containers.