1 min read

Set up docker Wordpress behind docker NGINX with SSL

Working solution to run Wordpress using official Docker image. A step by step guide.
Set up docker Wordpress behind docker NGINX with SSL

Little short story

I launched my first EC2 instance about 3 years ago. All was runnig well until i had only PHP sites so every applications with the same environment needed. Later i started developing applications with heterogeneous environments, like Python, Go or simply Wordpress blogs.

And so? Docker was the way!

Intro

The intent of this post is to show how to set up an SSL secure Wordpress site using Docker.

I suppose that you have docker-compose installed in your server and bought a domain name that i will call yourdomain.com.

Wordpress Container

WORKSPACE/mywordpresssite/docker-compose.yml

version: '3'
services:
wp:
image: wordpress
ports:
- 9009:80
volumes:
- ./config/php.conf.uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
- ./wp-app:/var/www/html # Full wordpress project
#- ./plugin-name/trunk/:/var/www/html/wp-content/plugins/plugin-name # Plugin development
#- ./theme-name/trunk/:/var/www/html/wp-content/themes/theme-name # Theme development
environment:
WORDPRESS_DB_HOST: [DBHOST]:[DBPORT]
WORDPRESS_DB_NAME: [DBNAME]
WORDPRESS_DB_USER: [DBUSER]
WORDPRESS_DB_PASSWORD: [DBPASSWORD]

WORKSPACE/mywordpresssite/config/php.conf.uploads.ini

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

Correctly enable SSL

On the top of your WORKSPACE/mywordpresssite/wp-app/wp-config.php add these lines:

/**
* For WordPress, force the protocol scheme to be HTTPS
* when is_ssl() doesn't work, e.g. on a reverse proxied server
* where _SERVER['HTTPS'] and _SERVER['SERVER_PORT'] don't
* indicate that SSL is being used.
*/if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
$_SERVER['HTTPS'] = '1';
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
view raw wp-config.php hosted with ❤ by GitHub

(it avoids the redirects loop once the NGINX reverse proxy container is up)

Generate free SSL cert

Go to https://www.sslforfree.com/ and type your domain name. After that, you have to decide how to verifiy your domain (i generally do the manual verification).

Unzip the downloaded folder and upload ca_bundle.crt , certificate.crt and the private.key inside WORKSPACE/nginx/keys/yourdomain.com/ folder.

NGINX Container

WORKSPACE/nginx/docker-compose.yml

version: '3'
services:
nginx:
image: nginx:latest
container_name: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
#- ./.htpasswd:/etc/nginx/.htpasswd
- ./certs:/etc/nginx/certs
ports:
- 80:80
- 443:443

WORKSPACE/nginx/docker-compose.yml

worker_processes 2;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535;
# [ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx.error_log info;
events {
worker_connections 2000;
# use [ kqueue | epoll | /dev/poll | select | poll ];
# use kqueue;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
output_buffers 1 32k;
postpone_output 1460;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
send_lowat 12000;
keepalive_timeout 75 20;
#lingering_time 30;
#lingering_timeout 10;
#reset_timedout_connection on;
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/nginx/certs/yourdomain.com/certificate.crt;
ssl_certificate_key /etc/nginx/certs/yourdomain.com/private.key;
server_name www.yourdomain.com yourdomain.com;
client_max_body_size 500M ;
location / {
proxy_pass http://[YOURSERVERIP]:9009;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
#proxy_set_header X-Forwarded-Proto https;
#proxy_http_version 1.1;
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "upgrade";
#proxy_read_timeout 86400;
}
}
view raw nginx.conf hosted with ❤ by GitHub

Finally

We have only the last 2 things to do:

  • Update record A on your domain DNS zone in order to point to your server IP.
  • [Only if you are running on an Amazon EC2 istance] Add the 9009 port on Outgoing tab of the EC2 security group. Grant this port access only to your ec2 IPs.
Tweets by YBacciarini