Add Free SSL to Existing WordPress Site with Docker and Let’s Encrypt

综合编程 2016-06-24

Google announced that they use HTTPS as a ranking signal on 2014 , and it becomes more standard in their search result. Therefore, I decide to use HTTPS also for this blog; and it looks pretty too for having a green lock icon on the browser. I’m a Docker devotee, so I’ll show you how to do it by using Docker.

1. Install Docker on the server

I’m using Ubuntu 16.04 on my Digital Ocean droplet. So, you can follow Docker official installation guide for Ubuntu on their documentation page here .

2. Run Let’s Encrypt companion for Nginx proxy container

Before running this container, I will shortly explain what Let’s Encrypt is, in case you never heard it. Taken from its website, it is a free, automated, and open certificate authority (CA), run for the public’s benefit. Let’s Encrypt is a service provided by the Internet Security Research Group (ISRG) . Hence, we don’t need to buy and manually renew the SSL certificate anymore.

I assume you are at the home folder (/home/user/). You should create a directory for storing the certificates.

/home/user/:$ mkdir certs

Then, you will run Nginx as the proxy server for our WordPress container. I’m using Nginx proxy image which is maintained by jwilder .

/home/user/:$ docker run -d -p 80:80 -p 443:443 
  --name nginx-proxy 
  -v /home/user/certs:/etc/nginx/certs:ro 
  -v /etc/nginx/vhost.d 
  -v /usr/share/nginx/html 
  -v /var/run/docker.sock:/tmp/docker.sock:ro 

If you look the command above, 3 writable volumes are declared:

  • /etc/nginx/certs is for creating and renewing Let’s Encrypt certificates
  • /etc/nginx/vhost.d is for changing the configuration of vhosts, and it’s needed by Let’s Encrypt
  • /usr/share/nginx/html is for writing challenge files, so Let’s Encrypt can verify your domain.

After the Nginx proxy container is running, you will run Let’s Encrypt container to create and renew the certificate for each domain that you want to add the SSL certificate. I will use the Let’s Encrypt image which is maintained by JrCs .

/home/user/:$ docker run -d 
  -v /home/user/certs:/etc/nginx/certs:rw 
  --volumes-from nginx-proxy 
  -v /var/run/docker.sock:/var/run/docker.sock:ro 

Ensure those 2 containers are running by using docker ps command. Then you can start any containers to be proxified with https connection by using this command:

/home/user/:$ docker run -e "" 
  -e "," 
  -e "" 
  ... # put the rest of the necessary settings here

The LETSENCRYPT_HOST and LETSENCRYPT_EMAIL are necessary, so Let’s Encrypt service can automatically create and renew valid certificate for each virtual host.

3. Install MySQL database

I’m using MySQL official image . I’m storing the MySQL data in host directory to prevent data loss when the container restart or die.

/home/user/:$ mkdir data
/home/user/:$ docker run --name wp_mysql 
  -v /home/user/data:/var/lib/mysql 
  -e MYSQL_ROOT_PASSWORD=my-secret-pw 
  -e MYSQL_USER=my-user 
  -e MYSQL_USER_PASSWORD=my-password 
  -e MYSQL_DATABASE=wordpress -d mysql:latest

For my case, I’m importing my MySQL dump from the old WordPress setup to the MySQL container.

/home/user/:$ docker exec -i wp_mysql mysql -umy-user -pmy-password wordpress < dump.sql

4. Containerize the Old WordPress Setup

I’m not using WordPress official image since this is an existing blog, not a new one. So, I re-arrange my WordPress directory structure before containerizing it. Here is the structure.

| src (for wp-content, wp-include, and the entire WordPress files)
| Dockerfile

This is my Dockerfile. I’m using PHP7 Apache as a base image.

FROM php:7-apache
MAINTAINER Asep Bagja Priandana <>
RUN a2enmod rewrite expires
# install the PHP extensions we need
RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev && rm -rf /var/lib/apt/lists/* 
	&& docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr 
	&& docker-php-ext-install gd mysqli opcache
# set recommended PHP.ini settings
# see
RUN { 
		echo 'opcache.memory_consumption=128'; 
		echo 'opcache.interned_strings_buffer=8'; 
		echo 'opcache.max_accelerated_files=4000'; 
		echo 'opcache.revalidate_freq=60'; 
		echo 'opcache.fast_shutdown=1'; 
		echo 'opcache.enable_cli=1'; 
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
COPY src/ /var/www/html/

Then modify the existing wp-config.php .

// Don't hardcode your DB setting. Instead use environment variable.
/** The name of the database for WordPress */
define('DB_NAME', getenv('WORDPRESS_DB_NAME'));
/** MySQL database username */
define('DB_USER', getenv('WORDPRESS_DB_USER'));
/** MySQL database password */
/** MySQL hostname */
define('DB_HOST', getenv('WORDPRESS_DB_HOST'));
// Add these 2 lines, because we are running the Apache behind Nginx proxy
// Otherwise you will get infinite redirect
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')

Now, you can build your custom WordPress image.

/home/user/:$ docker build -t user/my_wordpress .

5. Run the WordPress Image

Let’s run the newly created image.

/home/user/:$ docker run --name my_wordpress 
  --link wp_mysql:mysql 
  -e WORDPRESS_DB_USER=my-user 
  -e WORDPRESS_DB_PASSWORD=my-password 
  -e WORDPRESS_DB_NAME=wordpress 
  -e "" 
  -e "," 
  -e "" -d user/my_wordpress

Be careful, WORDPRESS_DB_HOST is your MySQL container’s IP address.

6. Pointing your domain to the host

Now you can open your DNS manager and point the A record to your host IP and make www CNAME record with @ value. After the DNS propagation has completed and everything is correctly configured, you can access your website and see the little green lock icon on your browser.

7. The last is configuring the URL inside your wp-admin

Login to your WordPress dashboard then goes to Settings > General. Replace the http with https.

Voila, now your WordPress site has ben secured and Google will love it.

Tags:docker, ssl , wordpress

责编内容by:Asep Bagja Priandana (源链)。感谢您的支持!


Your Serverless Raspberry Pi Cluster with Docker This blog post will show you how to create your own Serverless Raspberry Pi cluster with Docker and the OpenFaaS framework. People often ask me wh...
使用 Systemd 自动续期 Let’s Encrypt 证书... 今早发现Melisandre 官网的 Let’s Encrypt 证书过期了,可是明明记得自己之前是配置了自动续期的啊。经过一番排查发现,原来之前使用的 certbot 官网推荐的 autorenew 方式,证书是刷新了,但是由于 nginx 没有重启,所以新证书没有生效。那准备改为使用 Syst...
Docker: Multi-Stage Builds This is part of a series of articles describing how the AtSea Shop application was built using enterprise development tools and Docker. In the previou...
20 Best Selling WordPress Themes to Spice Up Your ... Herman Melville said that it is better to fail in originality than to succeed in imitation. I absolutely agree! That’s why I would like to pay attenti...
Deploying microservices in a Docker container I already spoke about docker containers . This is a quick tutorial (my github sample code ) about a new way of deploying (micro) services and ap...