Before Spring Festival, I saw that THE SERVER push function of HTTP/2 had been added to Nginx and WANTED to try it out.

Just these days, I was learning about Docker, and IT occurred to me that I could use Nginx containers. In case anything gets messed up, delete it and restart the container.

Here is how I set up the Nginx container and how TO add SSL certificates. You’ll see new features Docker uses to test software that are really handy and worth learning. If you don’t already know How to use Docker, you can start with The Introduction to Docker tutorial, which is very simple and can be learned in less than half an hour.

HTTP service

The main purpose of Nginx is to build a Web Server. With containers, the server is set up with a single command, no configuration at all.

$docker container run \ -d \ -p 127.0.0.2:8080:80 \ --rm \ --name mynginx \ nginxCopy the code

Download and run the official Nginx image. The default version is latest, currently 1.13.9. If you have a previous version installed on your machine, delete it and reinstall it, as server push is only supported in 1.13.9.

The following table describes the meanings of parameters in the preceding command.

  • -d: Runs in the background
  • -p: the container80Port mapping to127.0.0.2:8080
  • --rm: Automatically deletes container files after the container stops running
  • --name: The container name ismynginx

If no errors are reported, you can open your browser and access 127.0.0.2:8080. Normally, the Nginx welcome page is displayed.

Then, terminate the container, and the container file will be deleted automatically due to the –rm argument.


$ docker container stop mynginx
Copy the code

2. Map the web directory

The web files are in the container and cannot be modified directly, which is obviously inconvenient. The next step is to map /usr/share/nginx/html to the local directory where the web files reside.

First, create a directory and go to it.


$ mkdir nginx-docker-demo
$ cd nginx-docker-demo
Copy the code

Then, create a new HTML subdirectory.


$ mkdir html
Copy the code

In this subdirectory, place an index.html file with the following contents.


<h1>Hello World</h1>
Copy the code

You can then map this subdirectory, HTML, to the container’s web file directory, /usr/share/nginx/html.

$docker container run \ -d \ -p 127.0.0.2:8080:80 \ --rm \ --name mynginx \ --volume "$PWD/ HTML ":/usr/share/nginx/ HTML \ nginxCopy the code

Open your browser, access 127.0.0.2:8080, and you should see Hello World.

Copy the configuration

It is not enough to modify the web file, but also to modify the Nginx configuration file, otherwise SSL support will not be added later.

First, copy the Nginx configuration file from the container to the local directory.


$ docker container cp mynginx:/etc/nginx .
Copy the code

Copy /etc/nginx from mynginx to the current directory. Don’t miss that last point.

When the execution is complete, the current directory should have an additional nginx subdirectory. Then, rename the subdirectory to conf.


$ mv nginx conf
Copy the code

You can now terminate the container.


$ docker container stop mynginx
Copy the code

4. Map configuration directories

Restart a new container, this time mapping not only the web directory, but also the configuration directory.


$ docker container run \
  --rm \
  --name mynginx \
  --volume "$PWD/html":/usr/share/nginx/html \
  --volume "$PWD/conf":/etc/nginx \
  -p 127.0.0.2:8080:80 \
  -d \
  nginx
Copy the code

In the preceding code, –volume “$PWD/conf”:/etc/nginx maps the configuration directory /etc/nginx to the local conf subdirectory.

If a web page is displayed on a browser visiting 127.0.0.2:8080, the local configuration takes effect. At this point, you can terminate the container.


$ docker container stop mynginx
Copy the code

Self-signed certificates

Now to add HTTPS support to the container, the first thing to do is generate the private key and certificate. Formal certificates require the signature of a certificate authority (CA). For testing purposes, a self-signed certificate will do the job.

Below, I refer to a tutorial from DigitalOcean. First, make sure OpenSSL is installed on your machine, and then execute the following command.


$ sudo openssl req \
  -x509 \
  -nodes \
  -days 365 \
  -newkey rsa:2048 \
  -keyout example.key \
  -out example.crt
Copy the code

The following table describes the meanings of parameters in the preceding command.

  • req: Processes certificate signing requests.
  • -x509: Generates a self-signed certificate.
  • -nodes: Skip the password for the certificate so that Nginx can open the certificate directly.
  • -days 365: Certificate is valid for one year.
  • -newkey rsa:2048: Generates a new private key using 2048-bit RSA.
  • -keyout: The newly generated private key file is in the current directoryexample.key.
  • -out: The newly generated certificate file is in the current directoryexample.crt.

When executed, the command line pops up with a bunch of questions for you to answer, such as what country you are in, your Email address, and so on.

One of the most important questions is the Common Name, which normally would be a domain Name, instead of 127.0.0.2.


Common Name (e.g. server FQDN or YOUR name) []:127.0.0.2
Copy the code

After answering the question, you should have two more files in your current directory: example.key and example.crt.

Create a subdirectory certs under the conf directory and add the two files to this subdirectory.


$ mkdir conf/certs
$ mv example.crt example.key conf/certs
Copy the code

HTTPS configuration

With the private key and certificate, you can open HTTPS for Nginx.

First, open the conf/conf.d/default.conf file and add the following configuration at the end.

server { listen 443 ssl http2; server_name localhost; ssl on; ssl_certificate /etc/nginx/certs/example.crt; ssl_certificate_key /etc/nginx/certs/example.key; ssl_session_timeout 5m; ssl_ciphers HIGH:! aNULL:! MD5; Ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { root /usr/share/nginx/html; index index.html index.htm; }}Copy the code

Then, start a new Nginx container.

$ docker container run \ --rm \ --name mynginx \ --volume "$PWD/html":/usr/share/nginx/html \ --volume "$PWD/conf":/etc/nginx \ -p 127.0.0.2:8080:80 \ -p 127.0.0.2:8081:443 \ -d \ nginx ":/etc/nginx \ -p 127.0.0.2:8081:443 \ -d \ nginxCopy the code

In the above command, not only port 80 of the container is mapped, but also port 443, which is the exclusive port of HTTPS.

Open your browser and visit https://127.0.0.2:8081/. Because you are using a self-signed certificate, the browser will tell you that it is not secure. Leave it alone, choose to continue, and you should see Hello World.

At this point, HTTPS support for Nginx containers is ready. With this container in hand, in the next article, I’ll experiment with the Server push functionality of HTTP/2.

7. Reference links

  • Tips for deploying nginx(official image) with docker, by Mario Ponticello
  • How To Run Nginx in a Docker Container on Ubuntu 14.04, by Thomas Taege
  • Official Docker Library docs, by Docker
  • How To Create a self-signed SSL Certificate for Nginx in Ubuntu 16.04 by Justin Ellingwood

(after)