The Hotel Hero

Notes by a Sysadmin


Cluster | Philosophy | Stack

Nginx reverse proxy

April 16, 2021 | Cluster

Using jwilders configuration. Go to you project directory and create one directory (atleast), "conf.d" and maybe "html". Create a docker-compose.yml in the directory to (remember to change to the right path). Of cause you also need to figure out if you are running nginx on one or several nodes, in regard to storage and deployment settings. But, this is a basic setup on a one node Swarm "cluster". 

version: "3.8"

services:
  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - vhost:/etc/nginx/vhost.d
      - certs:/etc/nginx/certs
      - /home/rune79/swarm/nginx/html:/usr/share/nginx/html
      - dhparam:/etc/nginx/dhparam
      - /home/rune79/swarm/nginx/conf.d:/etc/nginx/conf.d
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /home/rune79/swarm/nginx/nginx.tmpl:/app/nginx.tmpl:ro  # <=== Add this line to your service.
    networks:
      - nginx-proxy
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"

  ssl-generator:
    image: jrcs/letsencrypt-nginx-proxy-companion
    depends_on:
      - "nginx-proxy"
    environment:
      - NGINX_PROXY_CONTAINER=nginx-proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - vhost:/etc/nginx/vhost.d
      - certs:/etc/nginx/certs:rw
      - dhparam:/etc/nginx/dhparam
      - /home/rune79/swarm/nginx/conf.d:/etc/nginx/conf.d
      - /home/rune79/swarm/nginx/html:/usr/share/nginx/html
    networks:
      - nginx-proxy

networks:
  nginx-proxy:

volumes:
  certs:
  vhost:
  dhparam:

In Swarm figure out the name of the network "docker network ls", and use the overlay network in your deploments:

version: '3.8'

services:
    whoami:
      image: jwilder/whoami
      expose:
        - "8000"
      environment:
        - VIRTUAL_PORT=8000 
        - LETSENCRYPT_HOST=sub.domain.com
        - VIRTUAL_HOST=sub.domain.com
      network:
        - nginx-stack_nginx-proxy

networks:
  nginx-stack_nginx-proxy:
    external: true

On Swarm

When having several nodes and replicas, we want Swarm to do the load balancing, and prevent Nginx to proxy the same ip or container.

Download the default nginx.tmpl and change the following section:

{{ define "upstream" }}
  server {{ index .Container.Labels "com.docker.swarm.service.name" }}:{{ .Address.Port }};
#   {{ if .Address }}
#       {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}}
#       {{ if and .Container.Node.ID .Address.HostPort }}
#           # {{ .Container.Node.Name }}/{{ .Container.Name }}
#           server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }};
#       {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}}
#       {{ else if .Network }}
#           # {{ .Container.Name }}
#           server {{ .Network.IP }}:{{ .Address.Port }};
#       {{ end }}
#   {{ else if .Network }}
#       # {{ .Container.Name }}
#       {{ if .Network.IP }}
#           #server {{ .Network.IP }} down;
#       {{ else }}
#           server 127.0.0.1 down;
#       {{ end }}
#   {{ end }}
{{ end }}

Making static changes to a specific api/app

if you plan to incorporate aditional features then edit the nginx.tmpl file, and use some kind of include. So, that you can keep changes after updates. ex.:

In the bottom of the template file add the "## added for include additional" section below.

         {{ end }}
                {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }}
                include {{ printf "/etc/nginx/vhost.d/%s_location" $host}};
                {{ else if (exists "/etc/nginx/vhost.d/default_location") }}
                include /etc/nginx/vhost.d/default_location;
                {{ end }}
        }
        ## added for include additional
        {{ if (exists (printf "/etc/nginx/conf.d/%s" $host)) }}
        include {{ (printf "/etc/nginx/conf.d/%s" $host) }};
        {{ end }}
        ## end

}

  

then if you create a file in "conf.d" called "sub.domain.com" it will be included.


About

I'm a Sysadmin, network manager and cyber security entusiast. The main purpose of this public "notebook" is for referencing repetitive tasks, but it might as well come in handy to others. Windows can not be supported! But all other OS compliant with the POSIX-standard can (with minor adjustments) apply the configs on the site. It is Mac OSX, RHEL and all the Fedora based distros and Debian based (several 100's of OS's), all the BSD distros, Solaris, AIX and HP-UX.

Links