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