目标
我想确保安装在我的主机上的SSL证书可以被运行在该机器上的Docker容器使用。
我的设置
虚拟机:我的虚拟机是一个运行Linux(Debian 11)的Google Cloud Compute Engine示例。到目前为止,我一直在这个虚拟机上运行我的网络应用程序(这也是安装SSL证书的地方)。
SSL证书:我已经使用LetsEncrypt在VM上安装了我的域的证书。这是一个成功的安装,这些文件存储在VM上的位置/root/etc/letsencrypt/live。我找不到下载它们的方法,因为它们受密码保护,我没有密码(我不知道当SSH进入我的VM时,sudo
使用什么密码)。
Docker:我正在迁移到Docker容器(从我当前的基本“直接在VM上运行它”设置)。我使用Docker编写文件,定义了所有服务(一个webapp和一个后端服务)。webapp将需要访问SSL证书。每个服务的Dockerfile非常基本-复制我的本地存储库,并具有运行时CMD<startup_script.sh>,它处理从GCP Secret Manager下载密钥并运行应用程序。我正在成功构建Docker镜像(在本地运行docker compose build
)。
Docker-compose:
version: '3.12'
services:
app:
build:
context: .
dockerfile: docker/app/Dockerfile
ports:
- "8000"
字符串
应用Dockerfile:
FROM python:3.12.0-bullseye
WORKDIR /home
COPY repo /home/repo
WORKDIR /home/repo
COPY /scripts/startup_script.sh /usr/local/bin
RUN chmod +x /usr/local/bin/startup_script.sh
CMD ["/usr/local/bin/startup_script.sh"]
型
启动脚本:
#!/bin/bash
#Download secrets
mkdir -p secrets
gcloud secrets versions access "latest" --secret=google_workspace_credentials --out-file=secrets/credentials.json
gcloud secrets versions access "latest" --secret=credentials_webapp --out-file=secrets/credentials_webapp
#Copy over the google workspace credentials
cp "$HOME"/secrets/credentials.json auth/credentials.json
cp "$HOME"/secrets/credentials_webapp auth/credentials_web.json
#Acquire SSL Certificate
...don't know what to do here
#Setup the runtime packages
pip install -r requirements.txt
#Run the programs
python3 app.py
型
我所尝试/考虑的
1.将证书复制到我的本地机器上,并使用它来构建docker镜像这不起作用,因为我需要一个密码来从VM复制证书,但我没有sudo的密码(我从来没有设置过,VM是由Google Compute Engine预构建的)。所以我被卡住了。我也认为将密钥存储在镜像本身可能有风险。
2.我读到过可以在容器本身上运行certbot,作为每次设置新SSL证书的设置脚本的一部分但这似乎是一个坏主意,因为1.如果它不成功,你永远不会知道2.你直接添加证书密钥到图像,这似乎是粗略的,3. LetsEncrypt(其他CA服务有速率限制)。然而,这个解决方案似乎很方便,因为它意味着我不必处理VM中的密钥,并且可以在任何主机上启动我的容器,而无需关心SSL证书。
3.使用docker run时将证书文件挂载到docker我读到过这个堆栈溢出response。如果我理解正确的话,该方法在使用docker run path/to/certs
的VM中运行容器时挂载证书文件。我有点担心这不会工作,因为证书是密码保护的。但我还没有尝试过,因为我还不了解这个解决方案,它是如何工作的。
**4.我可能读到过一种方法,可以在容器上打开一个端口来监听主机传递证书。**我不知道如何做到这一点,但这似乎是出于安全目的的理想选择。
问题
我应该采取什么方法,以及实现它的步骤是什么(如果可能的话,我是一个新的开发者,请提供示例代码)!
编辑:
我正在使用Traefik,但我需要帮助仔细检查我的Docker compose设置。目前它已经定义了traefik服务,我的webapp使用了证书。我还在运行时CMD复制证书,因为我不会从具有证书的VM构建此映像(我在本地构建它)。
services:
traefik:
image: traefik:v2.5
command:
- sh
- -c
- |
mkdir -p /certs
cp /etc/letsencrypt/live/dreamdai.io /certs/
traefik
--api.insecure=true
--providers.docker=true
--providers.docker.exposedbydefault=false
--entrypoints.web.address=:80
--entrypoints.websecure.address=:443
ports:
- "80:80"
- "8080:8080"
- "443:443"
webapp:
image: webapp
build:
context: .
dockerfile: docker/webapp.dockerfile
labels:
- "traefik.http.routers.webapp.rule=Host(`dreamdai.io`)"
- "traefik.http.routers.webapp.entrypoints=websecure"
- "traefik.http.routers.webapp.tls=true"
- "traefik.http.routers.webapp.tls.certresolver=myresolver"
型
我无法让traefik服务构建镜像。我正在运行docker compose build traefik
,日志显示“[+] Building 0.0s(0/0)”,但之后立即退出。
1条答案
按热度按时间b91juud31#
使用Traefik作为您的swarm的入口路由器。配置Traefik直接从LetsEncrypt获取证书,作为其ssl卸载设置的一部分。
现在你已经设置了一个容器,不必自己管理证书,并且有了tls对无数基于docker的服务的支持。