Using nginx as reverse proxy (for containered Ghost)

In some cases it might be a good idea to use a reverse proxy in front of a web application. Nginx is a very common solution for this scenario these days. As I started with containers for some of my playgrounds, I decided to go this route.

Container security

When looking around to implement a nginx in front of a Docker web application, in most cases nginx itself is also a Docker container.
In my eyes Docker containers have a huge disadvantage. To get updated software (at least security related) into production, you have to hope that your container image is well maintained or you have to care about it yourself. If this not the case, you might worry.
As long as you don't have container solutions deployed in large scale (and make use of automatically rebuilding and deploying your container images) I would recommend to keep the footprint of your containered applications as small as possible from security point of view.

So I decided to run my nginx on the same system where the Docker web applications are living, but you can also have it placed on a system in front of your container systems. Updates are supplied via usual Distribution security updates.

Installing nginx

# aptitude install nginx

I don't will advise you on the usual steps about setting up nginx, but will focus on things required to proxy into your container web application.

Configuration of nginx

As our Docker container for Ghost exposes port 2368, we need to define our upstream server. I've done that in conf.d/docker-ghost.conf.

upstream docker-ghost {
  server localhost:2368;

The vHost configuration can be taken into /etc/nginx/nginx.conf but I would recommend to use a config file in /etc/nginx/sites-available/ instead.

server {
  listen 80;

  include /etc/nginx/snippets/ghost_vhost.conf;

  location / {
    proxy_pass                          http://docker-ghost;
    proxy_set_header  Host              $http_host;   # required for docker client's sake
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_read_timeout                  900;

Let's enable the configuration and reload nginx:

# ln -s ../sites-available/ghost.conf /etc/nginx/sites-enabled/ghost.conf && \
 service nginx configtest && service nginx reload

Going further

This is a very basic configuration. You might think about delivering static content (like images) directly from your Docker data volume, caching and maybe encryption.