Sign inSign up

dpal/docker-nginx-letsencrypt-proxy

By dpal

Updated over 6 years ago

Quick & easy HTTPS reverse proxy for your Docker services.

Image
0

1.8K

dpal/docker-nginx-letsencrypt-proxy repository overview

docker-nginx-letsencrypt-proxy

This repository contains the Dockerfile of the dpal/docker-nginx-letsencrypt-proxy image.

Quick & easy HTTPS reverse proxy for your Docker services. Publish each of your Docker services and secure them with SSL certificates.

Let's assume you have a multi-container Docker application system, that consists of an api, a website, and admin interfaces for database and for content management. You may have the following network by default in your docker-compose.yml:

  • api:3000
  • dbadmin:9000
  • web:80
  • webadmin:8080

With this dpal/docker-nginx-letsencrypt-proxy image you can easly set up an NGINX reverse proxy and generate SSL certificates with certbot for your domains or subdomains, so that you can access these virtual hosts via a secure HTTPS connection. For example with yourdomain.com:

Usage

Requirements

Before running a docker image, please ensure:

  • You have a domain registered
  • DNS is configured properly (e.g. "A" records are set to your public IP)
  • Your host machine is available from the internet
Params

You can use the following environment variables:

  • EMAIL - Your email address for certbot (Let's encrypt)
  • SERVICE_HOST_1 - Public virtual host e.g. api.yourdomain.com
  • SERVICE_ADDRESS_1 - Internal address of Docker service e.g. api
  • SERVICE_PORT_1 - Internal port of your Docker service e.g. 3000 ... You can define as many service you want:
  • SERVICE_HOST_N - Nth host
  • SERVICE_ADDRESS_N - Nth internal address
  • SERVICE_PORT_N - Nth internal port

It is possible to use custom nginx .conf file mounted as volume (e.g. -v ./custom.com.conf:/etc/nginx/conf.d/api.yourdomain.com.conf). SERVICE_ADDRESS_N and SERVICE_PORT_N propeties are not required in that case, you should only specify host name (SERVICE_HOST_N).

Examples
1. Proxy services from a docker network

Here's a simple docker-compose.yml to try this image with your domain. service1 and service2 are dummy services running in docker network.


version: '3.7'
services:

  nginx: 
    image: dpal/docker-nginx-letsencrypt-proxy:latest
    container_name: nginx
    environment:
      - [email protected]
      - SERVICE_HOST_1=api1.yourdomain.com
      - SERVICE_ADDRESS_1=service1
      - SERVICE_PORT_1=3001
      - SERVICE_HOST_2=api2.yourdomain.com
      - SERVICE_ADDRESS_2=service2
      - SERVICE_PORT_2=3002
    volumes:
      - ./data/nginx/error.log:/etc/nginx/error_log.log
      - ./data/nginx/cache/:/etc/nginx/cache
    ports:
      - 80:80
      - 443:443
    expose:
      - "80"
      - "443"
    networks:
      - api-network

  service1: 
    image: node:alpine
    container_name: service1
    ports:
      - 3001:3001
    command:  >
      sh -c "echo 'var h=require(\"http\"),s=h.createServer(function(e,r){r.writeHead(200),r.end(\"api1\")});s.listen(3001);' > index.js && 
             node index.js"
    networks:
      - api-network 

  service2: 
    image: node:alpine
    container_name: service2
    ports:
      - 3002:3002
    command:  >
      sh -c "echo 'var h=require(\"http\"),s=h.createServer(function(e,r){r.writeHead(200),r.end(\"api2\")});s.listen(3002);' > index.js && 
             node index.js"
    networks:
      - api-network 

networks:
  api-network:
    driver: bridge

2. Proxy services with custom nginx configuration

Same as above but using a custom nginx configuration.


version: '3.7'
services:

  nginx: 
    image: dpal/docker-nginx-letsencrypt-proxy:latest
    container_name: nginx
    environment:
      - [email protected]
      - SERVICE_HOST_3=api3.yourdomain.com
    volumes:
      - ./data/nginx/error.log:/etc/nginx/error_log.log
      - ./data/nginx/cache/:/etc/nginx/cache
      - ./custom.com.conf:/etc/nginx/conf.d/api3.yourdomain.com.conf
    ports:
      - 80:80
      - 443:443
    expose:
      - "80"
      - "443"
    networks:
      - api-network

networks:
  api-network:
    driver: bridge

3. Proxy services from host network

docker-compose.yml to serve localhost:3001 and localhost:3002 services from your host network.


version: '3.7'
services:

  nginx: 
    image: dpal/docker-nginx-letsencrypt-proxy:latest
    container_name: nginx
    environment:
      - [email protected]
      - SERVICE_HOST_1=api1.yourdomain.com
      - SERVICE_ADDRESS_1=localhost
      - SERVICE_PORT_1=3001
      - SERVICE_HOST_2=api2.yourdomain.com
      - SERVICE_ADDRESS_2=localhost
      - SERVICE_PORT_2=3002
    volumes:
      - ./data/nginx/error.log:/etc/nginx/error_log.log
      - ./data/nginx/cache/:/etc/nginx/cache
    expose:
      - "80"
      - "443"
    network_mode: host

4. Proxy services from host network with docker run

Pull image from Docker Hub:

docker pull dpal/docker-nginx-letsencrypt-proxy:latest

Or build from GitHub:

docker build -t dpal/docker-nginx-letsencrypt-proxy github.com/paldom/docker-nginx-letsencrypt-proxy

Run image with docker run instead of docker-compose:

docker run --network host --expose=80 --expose=443 \
  -e [email protected] \
  -e SERVICE_HOST_1=api1.yourdomain.com \
  -e SERVICE_ADDRESS_1=localhost \
  -e SERVICE_PORT_1=3001 \
  -e SERVICE_HOST_2=api2.yourdomain.com \
  -e SERVICE_ADDRESS_2=localhost \
  -e SERVICE_PORT_2=3002 \
  dpal/docker-nginx-letsencrypt-proxy:latest

NGINX

Currently the following nginx configuration is used by default for each virtual host. Some parts are managed by certbot automatically.


server {
    server_name example.com;
    location / {
        proxy_pass "http://0.0.0.0:0000";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_cache_bypass $http_upgrade;
        proxy_http_version 1.1;
        proxy_set_header Connection keep-alive;
        proxy_redirect off;
    }
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
    listen 80;
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}


A possible content for ./custom.com.conf file in example 2. (Proxy services with custom nginx configuration).


server {
    server_name api3.example.com;
    location / {
      proxy_pass http://service1:3001;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
      proxy_set_header Host $host;
      proxy_cache_bypass $http_upgrade;
    }
    location ^~ /api {
      rewrite ^/api/(.*)$ /$1 break;
      proxy_pass http://service2:3002;
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
    listen 80;
}

Tag summary

Content type

Image

Digest

Size

110.5 MB

Last updated

over 6 years ago

docker pull dpal/docker-nginx-letsencrypt-proxy