This tutorial is going to go through how I create and install self signed SSL certificates for my nginx docker images
The set up
Assuming I start with dir following directory structure
- ssl-docker-nginx/
- nginx
- logs/
- my-site.com.access.log
- nginx.conf
- site/
- index.html
- docker-compose.yml
site/index.html looks like…
<html>
<head>
<title>My Site</title>
</head>
<body>
<h1>My Site</h1>
</body>
</html>
Nginx/nginx.conf looks like…
events {
worker_connections 4096; ## Default: 1024
}
http {
server {
listen 80;
server_name my-site.com;
root /usr/share/nginx/html/;
}
}
docker-compose.yml looks like…
version: '2'
services:
server:
image: nginx:1.15
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./site:/usr/share/nginx/html
ports:
- "8080:80"
I have the domain my-site.com
in my /etc/hosts
file looking like
0.0.0.0 my-site.com
Upon running …
docker-compose up -d
I should receive a webpage looking like the below when I hit http://my-site.com:8080/
in my browser
Now lets get to work
Lets get to work, we are going to do the following;
- Create a self signed SSL certificate
- Mount the self signed certificate and key into the docker image
- Configure nginx to serve my-site.com over https using the self signed certificate
- Party
Creating a self signed SSL certificate
To do this we will use the openssl program to generate a key/cert pair
openssl req -newkey rsa:2048 -nodes -keyout nginx/my-site.com.key -x509 -days 365 -out nginx/my-site.com.crt
You will have to fill in the following questions;
- Country Name (2 letter code)
- State or Province Name (full name)
- Locality Name (eg, city)
- Organization Name (eg, company)
- Organizational Unit Name (eg, section)
- Common Name (eg, fully qualified host name)
- Email Address
Once that is done you will have two new files in your nginx dir
- nginx/
- my-site.com.crt
- my-site.com.key
Mounting our new key/pair into our container
This will be accomplished via adding two additional volumes to docker-compose.yml
version: '2'
services:
server:
image: nginx:1.15
volumes:
- ./site:/usr/share/nginx/html
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/my-site.com.crt:/etc/nginx/my-site.com.crt # New Line!
- ./nginx/my-site.com.key:/etc/nginx/my-site.com.key # New Line!
ports:
- "8080:80"
Opening port 443 on our nginx container
A simple change to our docker-compose.yml
version: '2'
services:
server:
image: nginx:1.15
volumes:
- ./site:/usr/share/nginx/html
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/my-site.com.crt:/etc/nginx/my-site.com.crt
- ./nginx/my-site.com.key:/etc/nginx/my-site.com.key
ports:
- "8080:80"
- "443:443" # Hey docker start listening on 443, and redirect to 443
Configure nginx to serve my-site.com over https using the self signed certificate
Next we are going to configure nginx.conf to listen and server requests on port 443 using our new key/cert pair. This will require an update to the nginx/nginx.conf
file.
events {
worker_connections 4096; ## Default: 1024
}
http {
server {
listen 80;
server_name my-site.com;
root /usr/share/nginx/html;
}
server { # This new server will watch for traffic on 443
listen 443 ssl;
server_name my-site.com;
ssl_certificate /etc/nginx/my-site.com.crt;
ssl_certificate_key /etc/nginx/my-site.com.key;
root /usr/share/nginx/html;
}
}
Run docker-compose down && docker-compose up -d
and visithttps://my-site.com
to see the results, you will get a not secure certificate warning, tell your browser to accept and you should get something like
Getting your browser to trust your self signed certificate
This varies on your OS and browser, I would google for something like getting <browser-name> to accept self signed certificates on <your-os-here>
The complete codebase can be found here