15th July 2024
When you setup a compose project, or perhaps you have multiple projects on the same docker node, you may end up with multiple services that is listening on port 80 or 443. This needs to be solved by either:
Translate port 443 to some other port. However, this may requires firewall openings and users to specify port number in the browser.
Use a reverse-proxy container.
Some of you might have read my post on how to setup HAproxy in pfSense to perform basic reverse-proxy functions. That post has some complementary information about what a Reverse-proxy is used for.
However, this picture here should explain what I’m trying to accomplish:
Explanation:
HTTP requests going to nginx1.bastuklubben.online will be forwarded by the caddy container to the nginx1 container
HTTP requests going to nginx2.bastuklubben.online will be forwarded by the caddy container to the nginx2 container
Note: For HTTPS traffic it gets a bit more complicated due to SSL offloading. That requires a more real-life example.
Services involved
Caddy
Caddy is more than a revere-proxy. It’s a modern web-server and I’m interested in using it as the underlying web-frontend for an upcoming compose project. It can also do load-balancing with multiple containers as explained by Trevor Sullivan on CBT Nuggets.
Caddy Docs: https://caddyserver.com/docs/
nginx
nginx is a famous webserver frontend. These containers are used to verify that the reverse-proxy function is working as intended.
Configuration
Setting up the working directory
Step 1: Create a working directory
First you need to create a working directory that contains all related files. Personally, I use the /var/local/ directory for my docker compose projects
wl@sauna-nms:~$ cd /var/local
wl@sauna-nms:/var/local$ sudo mkdir bastuklubben.online
wl@sauna-nms:/var/local$ sudo chown -R wl:wl bastuklubben.online
wl@sauna-nms:/var/local$ cd bastuklubben.online
wl@sauna-nms:/var/local/bastuklubben.online$ mkdir reverse-proxy-test
wl@sauna-nms:/var/local/bastuklubben.online$ cd reverse-proxy-test/
wl@sauna-nms:/var/local/bastuklubben.online/reverse-proxy-test$
Step 2: create related files for the docker compose file
These are files and directories referenced by the compose file:
$ mkdir caddy
$ mkdir nginx
Nginx Settings
nano nginx/nginx1.index.html
This is basically the default index.html file. The only thing that is edited is the heading, so we know which container we have connected to:
...
<h1>Welcome to nginx example 1!</h1>
...
Do the same for nginx2.index.html
.
$ nano nginx/nginx2.index.html
...
<h1>Welcome to nginx example 2!</h1>
...
Note: I had a bug where i pasted in the whole default index.html file and found out that <style> made some weird things to the substack editor:
Caddy Settings
Create the caddyfile:
nano caddy/Caddyfile
# Example Webserver 1
nginx1.bastuklubben.online:80 {
reverse_proxy nginx1:80
}
# Example Webserver 2
nginx2.bastuklubben.online:80 {
reverse_proxy nginx2:80
}
Optional: Environment variables
Optionally create a .env
file. I’m using it only for changing the default project name:
nano .env
COMPOSE_PROJECT_NAME=sauna
Summary
These files should be existing:
wl@sauna-nms:/var/local/bastuklubben.online$ tree -a reverse-proxy-test/
reverse-proxy-test/
├── caddy
│  └── Caddyfile
├── .env
└── nginx
├── nginx1.index.html
└── nginx2.index.html
Step 3: Create the Docker Compose file
nano compose.yml
services:
nginx1:
image: nginx
volumes:
- ./nginx/nginx1.index.html:/usr/share/nginx/html/index.html
hostname: nginx1.bastuklubben.online
networks:
nms:
nginx2:
image: nginx
volumes:
- ./nginx/nginx2.index.html:/usr/share/nginx/html/index.html
hostname: nginx2.bastuklubben.online
networks:
nms:
caddy:
image: caddy
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
ports:
- 80:80
networks:
nms:
networks:
nms:
enable_ipv6: true
Step 4: Create dns records
You need to create dns records for your nginx containers. If you don’t want to clutter up your DNS server with lab records, A simple way to do that on your host machine is to edit the /etc/hosts file. (assuming you are running linux. Similar file exist on Windows).
sudo nano /etc/hosts
Add this section somewhere inside the file:
# Temp hosts
2001:DB8:0:A010::E nginx1.bastuklubben.online nginx2.bastuklubben.online
Verification
After you have started the compose project, you should be able to browse your webservers when you use those records:
$ docker compose up -d
[+] Running 4/4
✔ Network sauna_nms Created 0.2s
✔ Container sauna-caddy-1 Started 1.9s
✔ Container sauna-nginx2-1 Started 1.6s
✔ Container sauna-nginx1-1 Started 2.1s
Conclusion
This demonstrated how to setup basic reverse-proxy function with Caddy. Now replace those dummy nginx containers with something useful.