在 Docker 中启动容器时自动执行初始化脚本,最推荐方式是使用自定义 ENTRYPOINT 脚本:先执行初始化(如改配置、等依赖),再以 exec "$@" 接管原 CMD 命令,确保其作为 PID 1 运行并支持信号;需用绝对路径、失败 exit 1、禁止后台启动。

在 Docker 中启动容器时自动执行初始化脚本,核心是让脚本在容器主进程(PID 1)启动前或启动初期运行。常见且可靠的方式是通过自定义 ENTRYPOINT 脚本实现,而非依赖 CMD 或 init 系统。
使用自定义 ENTRYPOINT 脚本
这是最推荐、最可控的方法:将初始化逻辑写入一个 shell 脚本,并设为容器的 ENTRYPOINT。该脚本先执行初始化(如修改配置、生成密钥、等待依赖服务就绪等),再用 exec "$@" 接管后续命令(即原来 CMD 或运行时指定的命令)。
- 创建
entrypoint.sh,开头加#!/bin/sh,确保可执行(chmod +x) - 脚本中按需做初始化:例如
sed -i 's/localhost/$DB_HOST/' /app/config.yml - 最后必须以
exec "$@"结尾,保证原命令作为 PID 1 运行,支持信号传递和优雅退出 - Dockerfile 中写:
COPY entrypoint.sh /entrypoint.sh和ENTRYPOINT ["/entrypoint.sh"]
利用 CMD 包裹初始化逻辑(简易场景)
适合简单、无依赖的单步操作,比如设置环境变量或改权限。直接在 Dockerfile 的 CMD 中组合命令:
CMD sh -c "chmod 600 /root/.ssh/id_rsa && exec /usr/local/bin/start-server"- 注意必须用
exec替换当前 shell 进程,否则容器主进程是 shell,收不到 SIGTERM - 不适用于多步、带条件或需错误处理的初始化,可维护性较差
配合 docker-compose 的 init 容器或 healthcheck 做依赖等待
若初始化需等待其他服务(如数据库就绪),单纯靠 ENTRYPOINT 无法重试。可在 entrypoint.sh 中加入等待逻辑:
- 用
until nc -z db 5432; do sleep 2; done等待 DB 启动 - 或调用
wait-for-it.sh(社区常用轻量脚本) - 在 docker-compose.yml 中可通过
depends_on: { service: { condition: service_healthy } }配合容器内 healthcheck 提升可靠性
避免踩坑的关键细节
几个容易忽略但影响稳定性的点:
- 脚本中所有路径用绝对路径,Docker 内部工作目录不可靠
- 初始化失败时应
exit 1,避免容器“假启动”——Docker 会将其视为启动失败并根据 restart policy 处理 - 不要在 ENTRYPOINT 中后台启动服务(如
nginx &),这会导致容器立即退出;所有服务应前台运行 - 如果基础镜像含 systemd 或 supervisord,通常没必要引入,反而增加复杂度和体积










