Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

docker-machine + docker-compose + ssl (lets encrypt through nginx & certbot)

I'm trying to add automatic TLS/SSL termination to an Nginx in a docker-compose deployed through the docker-machine (DigitalOcean).

I found a few nice resources [humankode/how-to-set-up..., medium/nginx-and-lets-encrypt...] on how to do it through the docker-compose but they both are saying from the perspective of being on the server. I really want to avoid that. I'd love to do it locally, on my laptop, bundle it all together, and send it off. Or, even do it remotely without doing any ssh.

A few attempts failed but it feels like they were close. The main obstacle seems to be with files/volumes. Following the medium/nginx-and-lets-encrytp... guide I'm having problems with saving OpenSSL privkey.pem. The other tutorial (humankode), to me knowledge, does everything on the server and that's where the volumes live.

My latest attempt was to set up certificates on the machine through the DigitalOcean tutorial and try to include these through in my docker-compose build. No luck.

There were many modifications but my settings are similar to:

docker-compose.yml

version: '3.7'

services:
  nginx:
    image: nginx:1.15.9-alpine
    container_name: nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    restart: always
    volumes:
      - /etc/letsencrypt
      - /var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"

  certbot:
    image: certbot/certbot
    restart: unless-stopped
    volumes:
      - "/etc/letsencrypt"
      - "/var/www/certbot"
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

nginx/Dockerfile

FROM nginx:1.15.9-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY prod.conf /etc/nginx/conf.d/

nginx/conf.d

# PRODUCTION
server {
    listen 80;
    listen [::]:80;
    server_name example.site;

    location ~ /.well-known/acme-challenge {
        allow all;
        root /usr/share/nginx/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name example.site;

    ssl_certificate /etc/letsencrypt/live/example.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.site/privkey.pem;

    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
like image 729
Dawid Laszuk Avatar asked Nov 06 '22 13:11

Dawid Laszuk


1 Answers

I would need further details on errors you are receiving, but basically everything is more or less ok in your configuration. I see a possible error in the volumes part. But step by step because you are asking a couple of interesting questions:

  1. You can test everything locally but I am afraid (or I could not find the way) that you cannot do it with Let's encrypt automatically because certbot find a suitable available domain in the internet (so locally is unreachable). What I did is to generate the certificates (I have validated ones) and then modify the hosts on your machine with the domain pointing to localhost (or Docker toolbox IP in the case of Windows) you are selecting with valid certificates. It is a workaround but it can work.

  2. In the Medium example, volumes are created as host volumes for both containers:

     volumes:
        - ./data/certbot/conf:/etc/letsencrypt
        - ./data/certbot/www:/var/www/certbot
    

    This means that the certificates must be placed in the folder ./data/certbot/conf or /path/to/host of the docker host machine and they are mapped to /etc/letsencrypt folder in the container. You are using anonymous volumes (I had problems in the past when I use them). Check this stackoverflow question for further explanation about the type of volumes.

Finally if you prefer another more dynamic solution which automatically includes https you can check an stackoverflow answer on how to use nginx as reverse proxy in order to ease your deployment. There is also available a docker compose ELK deployment example

like image 92
Carlos Cavero Avatar answered Nov 13 '22 17:11

Carlos Cavero