Appearance
症状与根因
- exec /docker-entrypoint.sh: no such file or directory、set: illegal option -
- 根因:Windows CRLF 行尾 + 直接 exec 导致脚本解析异常。
- 容器重启后仍未迁移
- 根因 1:后端容器未拿到 DB 密码(DB_PASS 未注入),探活循环一直失败。
- 根因 2:
docker-compose.dev.yaml的 healthcheck 在宿主侧使用了${DB_PASS},未读取.env.dev,同时产生干扰警告。
固定模板(可直接复用)
- Dockerfile.dev(镜像内 ENTRYPOINT,统一 CRLF)
dockerfile
WORKDIR /workspace
COPY ./entrypoint.sh /docker-entrypoint.sh
RUN sed -i 's/\r$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh
ENTRYPOINT ["sh", "/docker-entrypoint.sh"]
CMD ["npm", "run", "start:dev"]- docker-compose.dev.yaml(env 注入与健康检查)
yaml
services:
db:
env_file:
- .env.dev
healthcheck:
test:
[
"CMD",
"mysqladmin",
"ping",
"-h",
"localhost",
"-u",
"root",
"-p${MYSQL_ROOT_PASSWORD}",
]
backend:
env_file:
- .env.dev
# ENTRYPOINT/CMD 由镜像控制(Dockerfile)- .env.dev(提供两套变量且一致)
ini
# 应用连接(Nest)
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASS=secret
DB_NAME=app
# DB 容器初始化/healthcheck
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=app要点
- 入口脚本放进镜像(不要用 Compose 覆盖),避免跨平台行尾/解释器差异。
- 复制脚本后统一行尾:
sed -i 's/\r$//' /docker-entrypoint.sh。 - Compose 健康检查尽量使用 DB 容器可用变量(如
MYSQL_ROOT_PASSWORD),避免宿主解析失败。 - 所有应用侧必需的
DB_*变量通过env_file注入后端容器。