Docker-Machine + Docker-Compose + SSL (通过Nginx和Certbot使用Let's Encrypt)

5

我正在尝试为通过Docker Machine(DigitalOcean)部署的Nginx添加自动TLS/SSL终止。

我发现了一些很好的资源[humankode/how-to-set-up..., medium/nginx-and-lets-encrypt...],介绍了如何通过docker-compose实现它,但都是从服务器的角度进行说明。我真的想避免这种情况。我希望能够在本地完成所有工作,将其捆绑在一起并发送出去。或者,甚至可以在没有任何ssh的情况下远程执行它。

几次尝试失败了,但感觉离成功很近。主要障碍似乎在于文件/卷。按照 medium/nginx-and-lets-encrypt... 指南,我在保存 OpenSSL privkey.pem 时遇到了问题。另一个教程 (humankode),据我所知,所有操作都在服务器上进行,那里就有卷。

我最近的尝试是通过 DigitalOcean 教程 在机器上设置证书,然后尝试在我的 docker-compose 构建中包含它们。没有成功。

进行了许多修改,但我的设置与以下类似:

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;
1个回答

1
我需要进一步了解您所收到的错误细节,但基本上您的配置是更或多或少正常的。我在卷部分看到可能存在的错误。但是,因为您提出了几个有趣的问题,所以我们需要逐步进行。
  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.

如果您希望采用另一种更动态的解决方案,可以自动包含 https,您可以查看如何使用nginx作为反向代理的stackoverflow答案以便简化部署。还提供了一个docker compose ELK部署示例

没有错误,只是尝试了一些不同的方法,但没有成功。最终,我进行了手动引导,即登陆远程主机,使用scp工具复制凭据并把它们放入docker中(https://personalprogress.site)。但这仅仅是许多项目中的一个,我希望避免每次都这样做。你提供的另一种方法很有趣,但我不想把各个项目耦合在一起。我希望有自动获取凭证的方式。此外,我还想将Let's Encrypt证书存储在某个地方,并不想将其放入GitHub中。 - Dawid Laszuk
是的,有一种自动化的方式。Let's Encrypt已经与nginx集成,包括更新过程。在几天内,我将编辑答案并提供1)的自动化解决方案。 - Carlos Cavero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接