Setting up Docker containers with nginx to reverse proxy to multiple web servers

In this post I’ll show how to set up docker containers with nginx reverse proxying to 2 different web servers (apache and apache tomcat). All setup with one docker compose file. Very handy for running on one machine for development , to simulate what you might have running on multiple machines in your production environment.

This is abit of bare bones example, I’m not going to setup SSL or go into any rewrite rules in any great detail.

So with out further ado. We need 3 files:

docker-compose.yml

yoursites.conf ( nginx config, it doesn’t have to be called yoursites.conf, just something .conf)

Dockerfile ( not strictly needed I’ve added some bits handy for debugging )

Docker compose file

version: "3.7"

services:
  proxy-server:
    container_name: nginx-proxy
    build: .
    hostname: websitename.com # you can map this in hosts file
    image: nginx
    ports:
      - 8080:80
    volumes:
# nginx proxy config ( put the file yoursites.conf in this dir )      
       - ./nginx-config:/etc/nginx/conf.d
    restart: unless-stopped

    networks:
      - proxy-test-net
################# web server to proxy to ##############################
  web:
    container_name: webtest
# use this hostname internally for networking instead of the internal dynamic ip address    
    hostname: bobsgreatserver
    image: httpd:2.4
    ports:
########### as we're on the same docker network, nginx will connect on port 80    
      - 8082:80
    restart: unless-stopped
    networks:
      - proxy-test-net

  anotherweb:
    container_name: justanotherwebserver
    hostname: someotherserver
    image: tomcat
    ports:
########### network internally access on port 8080
      - 8084:8080
    restart: unless-stopped
    networks:
      - proxy-test-net      

networks:
  proxy-test-net:
    driver: bridge

Nginx config (yoursites.conf)

server {
  listen 80;
  listen [::]:80;

  server_name websitename.com;

  location / {
# use the internal network port (docker), and the hostname from the docker compose ( as internal ip address is dynamic and can change)
    proxy_pass http://bobsgreatserver:80;

  }location /tomcat {
    proxy_pass http://justanotherwebserver:8080;
  }
}

Dockerfile for nginx

With some stuff added to help debugging

FROM nginx
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]
RUN ["apt-get", "install", "-y", "iputils-ping"]
RUN ["apt-get", "install", "-y", "wget"]

So with all the above setup (and Docker installed of course).
Run this command on the cmd line:
docker compose up

Then hit the servers to see them, eg going to websitename.com will send you to apache server and going to websitename.com/tomcat, will send you to apache tomcat.

Leave a Comment