You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Nginx容器加载默认entrypoint启动后执行自定义脚本方法

实现方法

官方Nginx镜像默认的/docker-entrypoint.sh启动逻辑自带扩展点:启动Nginx主进程前,会自动按文件名排序执行/docker-entrypoint.d/目录下所有有可执行权限的.sh脚本,不需要修改、覆盖默认启动文件,也不需要在docker-compose里重写command配置,完全匹配需求。


具体操作步骤

1. 编写自定义初始化脚本

新建脚本文件40-certbot-init.sh(数字前缀保证它在官方自带的预处理脚本执行完之后再运行),内容如下:

#!/bin/sh
set -e

# 临时启动Nginx,用于响应Let's Encrypt的校验请求
nginx -g "daemon on;"

# 等待Nginx启动完成
until nc -z localhost 80; do
    echo "等待Nginx启动完成,准备申请证书..."
    sleep 1
done

# 执行证书申请,替换成自己的邮箱和域名
certbot certonly --webroot \
  -w /var/lib/letsencrypt \
  -d 你的域名 \
  --non-interactive \
  --agree-tos \
  --email 你的联系邮箱 \
  --no-eff-email

# 写入SSL配置片段
cat > /etc/nginx/snippets/ssl.conf << EOF
ssl_certificate /etc/letsencrypt/live/你的域名/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/你的域名/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
EOF

# 关闭临时启动的Nginx,后续由默认entrypoint启动前台主进程
nginx -s stop

注意:脚本最后不要手动启动Nginx,交给默认启动流程拉起前台运行的Nginx主进程即可,避免主进程退出导致容器反复重启。

2. 修改现有Dockerfile

在原有Dockerfile的基础上,补充复制脚本、给执行权限的步骤,删掉原来RUN块最后未完成的certbot相关行:

FROM node:14-alpine as frontend-builder
WORKDIR /app/frontend
COPY ./frontend .
ENV PATH ./node_modules/.bin/:$PATH
RUN set -ex; \
  yarn install --frozen-lockfile --production; \
  yarn cache clean; \
  yarn run build
###############################################
FROM nginx:1.19.2-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY ./compose/production/build/nginx.conf /etc/nginx/conf.d
COPY --from=frontend-builder /app/frontend/build /usr/share/nginx/html/build

# 安装依赖
RUN apk update && \
    apk add --no-cache nano certbot && \
    mkdir -p /var/lib/letsencrypt /var/lib/letsencrypt/.well-known /etc/nginx/snippets && \
    chgrp www-data /var/lib/letsencrypt && \
    chmod g+s /var/lib/letsencrypt

# 写入ACME校验配置片段
RUN cat > /etc/nginx/snippets/letsencrypt.conf << EOF
location ^~/.well-known/acme-challenge/ {
    allow all;
    root /var/lib/letsencrypt/;
    default_type "text/plain";
    try_files \$uri =404;
}
EOF

# 复制自定义初始化脚本到Nginx官方扩展目录,给执行权限
COPY ./40-certbot-init.sh /docker-entrypoint.d/
RUN chmod +x /docker-entrypoint.d/40-certbot-init.sh

之前操作的问题说明

  • 直接在Dockerfile里用RUN执行certbot:RUN指令是镜像构建阶段执行的,此时容器内Nginx服务根本没有启动,无法响应ACME校验请求,必然执行失败。
  • 在docker-compose里配置command:直接自定义command会覆盖默认entrypoint的执行逻辑,如果自定义命令执行完后没有以前台模式拉起Nginx主进程,容器主进程退出就会触发重启策略反复重启。

可选优化

如果需要自动续期证书,可以在初始化脚本里加一条定时任务,续期完成后重载Nginx配置即可:

# 加在40-certbot-init.sh末尾,关闭临时Nginx之前
echo "0 3 * * * certbot renew --quiet --deploy-hook 'nginx -s reload'" | crontab -
crond

内容的提问来源于stack exchange,提问作者user19271630

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:39:26