如何在运行时使用唯一参数在 Dockerfile 中调用 RUN?(在 Docker 中安装 Let's Encrypt for NGINX。



我正在尝试创建一个Dockerfile来设置Let's Encrypt。我的基本Docker Compose项目包含以下三个文件:

  • test/doker-compose.yml
  • test/nginx/Dockerfile
  • test/letsencrypt/Dockerfile

Let's Encrypt需要做两件事:(1(在验证域所有权后首次安装网站证书,以及(2(使用cron作业每隔60-90天定期续订证书。证书的初始安装是Dockerfile的RUN命令的理想用例,因为它在安装时只发生一次,而定期续订证书则是Dockerfle的ENTRYPOINT命令的理想用法,因为它需要持久运行。

然而,如果我在Dockerfile中包含完整的"RUN certbot certonly-d example.com…"命令,它将无法构建,因为Let's Encrypt的certbot应用程序需要运行web服务器来验证域名的有效性。为了解决这个问题,我想做的是在构建过程中调用"RUN certbot--help",然后在NGINX启动后的运行时调用"RUN-certbot certonly-d example.com…"。

我的Docker Compose文件组织如下:

services:
nginx:
...
letsencrypt:
...
environment:
CERTBOT_PARAMETERS: 'certonly -d example.com ...'
depends_on:
- nginx

我的Let's Encrypt dockerfile是:

FROM ubuntu:bionic
ENV CERTBOT_PARAMETERS="--help"
...
# Install Certs
RUN certbot $CERTBOT_PARAMETERS
...
# Renew Certs
RUN apt-get -y install cron && 
printf "30 */12 * * * root certbot renew > /proc/1/fd/1 2>/proc/1/fd/2n" > /etc/cron.d/certbot && 
chmod 644 /etc/cron.d/certbot && 
crontab /etc/cron.d/certbot
ENTRYPOINT ["cron", "-f"]

这成功地构建了,但当我调用"dockercompose-up-d"时,一切都会运行,但证书没有安装。如果我调用"docker exec-it CONTAINER_NAME/bin/bash",然后在docker容器内手动运行"certbot certonly-d example.com…",那么证书确实会安装。

我认为在运行时调用CERTBOT_PARAMETERS环境变量有问题。也许它不能接受空格?

如何在运行时调用与在构建时不同的RUN命令?我应该使用CMD而不是RUN吗?如果是,在Dockerfile的不同阶段调用CMD和ENTRYPOINT是否可以接受?

Dockerfile中的RUN命令只有在构建映像时才会执行。

docker compose文件中设置的CERTBOT_PARAMETERS环境变量只有在生成映像后才可用。

我不确定你是如何构建图像的,但如果你想传递在构建时可用的值,你需要使用构建参数,例如。如果使用docker compose,请参阅文档reARGS:https://docs.docker.com/compose/compose-file/#args

,它们是仅在构建过程中可访问的环境变量。

关于CMDENTRYPOINT,您应该了解它们的使用情况,因为它们并不互斥,请参阅:https://docs.docker.com/engine/reference/builder/#entrypoint

它们控制映像在编译映像后启动时运行的命令,而RUN仅在编译期间使用

最新更新