====== Nginx as Reverse Proxy for Docker Containers ======
**Important Notice:**
This is an example for a Reverse Proxy. I will be using Traefik to [[engineering:computer_science:docker:application_guides:traefik_docker_https_ssl_for_containers|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 [[engineering:computer_science:docker:application_guides:docker_dokuwiki_portable|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:
* [[https://docs.docker.com/|https://docs.docker.com/]]
* [[https://www.domysee.com/blogposts/reverse-proxy-nginx-docker-compose|https://www.domysee.com/blogposts/reverse-proxy-nginx-docker-compose]]
===== 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:
- Mapping of the host ports to the container ports
- Mapping a config file to the default Nginx config file - /etc/nginx/nginx.conf
- 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 [[refractor_computer_science:docker:docker_wordpress_homepage_portable|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" .