Caveats First

NGINX Proxy Manager (NPM) is running in its own docker-compose file (or “stack”) in portainer. I could not get it to use the hosts’s local IP to connect to containers running in different stacks. I therefore made these changes:

  • I added a custom network according to the NPM documentation, stopped the NPM stack completely, and started it again. Just reloading the stack in Portainer does not change the network
  • I put all the other containers in the same network. I just added the “network” portion to the bottom of the compose file
  • Use the container port (the port number to the right) and the “service” name in your docker compose file as the host name in NPM

NPM docker-compose

version: "3"
services:
  nginxproxymanager:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
    environment:
      DISABLE_IPV6: 'true'
    volumes:
      - /opt/nginxproxymanager:/data
      - /opt/nginxproxymanager:/etc/letsencrypt
networks:
  default:
    external: true
    name: fornginxrp

Custom NodeJS image docker-compose

version: "3"
services:
  nodejs_webhook:
    image: "nodejs_webhook"
    restart: unless-stopped
    ports:
      - "3020:3000"
networks:
  default:
    external: true
    name: fornginxrp

Password Pusher docker-compose

version: '3'
services:
  passwordpusher:
    image: docker.io/pglombardo/pwpush-ephemeral:latest
    restart: unless-stopped
    ports:
      - "5100:5100"
networks:
  default:
    external: true
    name: fornginxrp

Take Note:

  • When adding a proxy host, you must use the docker port (the port number to the right) because you are accessing the container from within the same bridge network. The external port number (the one to the left) will be used when you use the host IP or the external facing IP.
  • When telling NPM to run in network_mode:host it will not work because it references the database by service name (db). When you add an external database or change it to reference the IP of the database only then will it work.
  • NPM uses port 3000 for I THINK letsencrypt/certbot, so try not to use this port number

Then in NPM’s proxy hosts, you can use the docker-compose service name as the host name:

proxy hosts

Getting SSL to work

I would strongly recommend you use cloudflare as it makes it so much easier. Add your domain (it can be a wildcard) then choose Cloudflare under DNS provider:

setting up ssl
Log into your Cloudflare account and generate an API key that has the “Zone Edit” permissions. Add your domain names (Zones) to the API key or just leave it blank to add all your zones
cloudflare ZT API key
You will get the API key which you then copy and past into the highlighted section in the above screenshot.

It should take about a minute or 2 after you click save for the cert to be generated.

Securing the NPM admin interface

  • You will add a proxy host for your NPM admin interface just like you would any other site:
  • Create a DNS record in Cloudflare first (or whoever manages your domain), and use the service name in your docker-compose file as the hostname.
  • Then in the SSL tab just select your wildcard certificate.
  • Lastly, it is a good idea to close port 81 on your host so that the admin interface cannot be accessed using your host’s public IP address and port 81
  • Cloudflare tunnel: You can take it one step further and add a Cloudflare tunnel for this URL and lock it down even further.
edit proxy host