Table of Contents

Nginx as Reverse Proxy for Docker Containers

Important Notice:

This is an example for a Reverse Proxy. I will be using Traefik to Implementing HTTPS / SSL with Traefik on Docker Containers down the line. So use this guide if you want to keep to nginx, else I would recommend going with Traefik.


My setup for the docker env. is the same as described on my DokuWiki Docker Container Portable, even though this should have almost zero effect even if the system is different (yay, docker!).

The materials that I used to learn / troubleshoot / implement this setup:

Why use a Reverse-Proxy?

I will be using a Nginx Server as a Reverse Proxy, so that a) I can host multiple containers which need to be available in the same ports, b) I don't have to access the containers by memorizing ports therefore being able to use carlossousa.tech/wiki or wiki.carlossousa.tech instead of the port and c) easy expandability for new services / containers.

Requirements for Reverse Proxy with Nginx in a Docker Container

For Nginx as a Reverse Proxy inside Docker we only need 3 basic things:

  1. Mapping of the host ports to the container ports
  2. Mapping a config file to the default Nginx config file - /etc/nginx/nginx.conf
  3. A Nginx config

Sample Nginx Reverse Proxy - nginx.conf - configuration

A sample nginx reverse proxy config file - nginx.conf - would like something like this:

http {
  server {
    server_name your.server.url;
 
    location /yourService1 {
      proxy_pass http://localhost:80;
      rewrite ^/yourService1(.*)$ $1 break;
    }
 
    location /yourService2 {
      proxy_pass http://localhost:5000;
      rewrite ^/yourService1(.*)$ $1 break;
    }
  }
 
  server {
    server_name another.server.url;
 
    location /yourService1 {
      proxy_pass http://localhost:80;
      rewrite ^/yourService1(.*)$ $1 break;
    }
 
    location /yourService3 {
      proxy_pass http://localhost:5001;
      rewrite ^/yourService1(.*)$ $1 break;
    }
  }
}

A Nginx Reverse-Proxy sample docker-compose.yml

would be something like:

version: '3'
services:
  nginx:
    image: nginx:latest
    container_name: production_nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/error.log:/etc/nginx/error_log.log
      - ./nginx/cache/:/etc/nginx/cache
      - /etc/letsencrypt/:/etc/letsencrypt/
    ports:
      - 80:80
      - 443:443
 
  your_app_1:
    image: your_app_1_image:latest
    container_name: your_app_1
    expose:
      - "80"
 
  your_app_2:
    image: your_app_2_image:latest
    container_name: your_app_2
    expose:
      - "80"
 
  your_app_3:
    image: your_app_3_image:latest
    container_name: your_app_3
    expose:
      - "80"

Pratical Example

Making the Reverse Proxy

Let's go ahead and create our folder and create our 2 required files, the docker-compose.yml and the nginx.conf. Navigate to your desired folder and run:

mkdir nging-reverseproxy
touch docker-compose.yml
touch nginx.conf

Using your favourite method, deploy your docker-compose.yml setup. I will be using the good old 'nano'.

My configuration would be as follows:

version: '3'
volumes:
    dokuwiki_data:
        external: true
    dokuwiki_conf:
        external: true
    dokuwiki_lib-plugins:
        external: true
    dokuwiki_lib-tpl:
        external: true
    dokuwiki_logs:
        external: true
 
services:
    nginx:
        image: nginx:latest
        container_name: nginx_reverseproxy
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf
          - ./nginx/error.log:/etc/nginx/error_log.log
          - ./nginx/cache/:/etc/nginx/cache
          - /etc/letsencrypt/:/etc/letsencrypt/
        ports:
          - 80:80
          - 443:443
 
    dokuwiki:
        image: 'mprasil/dokuwiki'
        container_name: 'dokuwiki_zebra'
        expose:
            - '80'
        volumes:
            - dokuwiki_data:/dokuwiki/data
            - dokuwiki_conf:/dokuwiki/conf
            - dokuwiki_lib-plugins:/dokuwiki/lib/plugins
            - dokuwiki_lib-tpl:/dokuwiki/lib/tpl
            - dokuwiki_logs:/var/log

And now we edit the nginx.conf to point back to our DokuWiki. Note that I will already configure a sub-domain and a main domain, which at the moment would both point to the same container, but once we make Wordpress Homepage ToGo with Docker we can change just the service name and everything should work properly.

events {
 
}
 
http {
  #error_log /etc/nginx/error_log.log warn;
  client_max_body_size 20m;
 
  proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m;
 
  server {
    server_name wiki.carlossousa.tech;
 
    location / {
      include /etc/nginx/includes/proxy.conf;
      proxy_pass http://dokuwiki:80/;
    }
  }
 
  server {
    server_name carlossousa.tech;
 
    location / {
      include /etc/nginx/includes/proxy.conf;
      proxy_pass http://dokuwiki:80/;
    }
  }
}

And finally we will once again create a backup_to_tar.sh so we can backup our nginx Reverse Proxy setup:

#!/bin/bash
SOURCE_PATH="/home/docker-user/nginx-reverseproxy"
BACKUP_PATH="/home/docker-user/backups"
BACKUP_NAME="nginx-reverseproxy"
tar cvf "$BACKUP_PATH"/"$BACKUP_NAME"-$(date +"%Y-%m-%d-%H-%M").tar -C "$SOURCE_PATH" .