为何容器内找不到docker-entrypoint.sh?本地正常EC2部署失败
问题场景
使用以下docker-compose.yml部署Flask应用:
version: '3.7' services: users: build: context: ./services/users dockerfile: Dockerfile volumes: - './services/users:/usr/src/app' ports: - 5001:5000 environment: - FLASK_ENV=development - APP_SETTINGS=project.config.DevelopmentConfig - DATABASE_URL=postgresql://postgres:postgres@users-db:5432/users_dev - DATABASE_TEST_URL=postgresql://postgres:postgres@users-db:5432/users_test depends_on: - users-db users-db: build: context: ./services/users/project/db dockerfile: Dockerfile ports: - 5435:5432 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres
用户服务的Dockerfile内容:
FROM python:3.11.6-alpine RUN apk update && apk add --virtual --no-cache gcc python3-dev musl-dev && \ apk add postgresql-dev && apk add netcat-openbsd WORKDIR /usr/src/app COPY ./requirements.txt /usr/src/app/requirements.txt RUN pip install -r requirements.txt COPY ./docker-entrypoint.sh /usr/src/app/docker-entrypoint.sh RUN chmod +x /usr/src/app/docker-entrypoint.sh COPY . /usr/src/app CMD ["/usr/src/app/docker-entrypoint.sh"]
部署到AWS EC2时出现错误:
Cannot start service users: failed to create task for container:
failed to create shim task: OCI runtime create failed: runc create
failed: unable to start container process: exec:
"/usr/src/app/docker-entrypoint.sh": stat
/usr/src/app/docker-entrypoint.sh: no such file or directory: unknown
本地构建运行正常,EC2与本地操作系统相同,文件位置已确认正确。
解决建议
验证EC2上的文件完整性
在EC2实例中进入项目目录,执行ls ./services/users/确认docker-entrypoint.sh存在。若缺失,检查代码同步环节:- 若用Git同步,确认该文件未被
.gitignore排除,且不存在大小写匹配问题。 - 若用其他方式传输(如SCP),确认传输过程中文件未丢失。
- 若用Git同步,确认该文件未被
排查卷挂载覆盖问题
当前compose配置中,./services/users:/usr/src/app的卷挂载会将容器内的目标目录完全替换为宿主机目录。若EC2宿主机的./services/users中无docker-entrypoint.sh,即使镜像内置该文件也会被覆盖。
临时注释volumes配置,执行docker-compose up --build测试:若能正常启动,说明是宿主机目录缺少文件导致的覆盖问题,补全文件后重新挂载即可。优化Dockerfile的COPY逻辑
当前Dockerfile先单独拷贝entrypoint文件,之后又拷贝整个目录,存在重复且易引发路径错误。调整为更简洁可靠的写法:FROM python:3.11.6-alpine RUN apk update && apk add --virtual --no-cache gcc python3-dev musl-dev && \ apk add postgresql-dev && apk add netcat-openbsd WORKDIR /usr/src/app COPY . . RUN pip install -r requirements.txt && chmod +x docker-entrypoint.sh CMD ["./docker-entrypoint.sh"]确保脚本路径引用正确,避免绝对路径拼写错误。
检查脚本的换行符与权限
若本地开发环境存在Windows/WSL混合场景,脚本可能携带DOS换行符,导致Alpine无法识别。在EC2上执行dos2unix ./services/users/docker-entrypoint.sh转换换行符。
同时确认宿主机上的脚本有执行权限:执行chmod +x ./services/users/docker-entrypoint.sh后再启动容器。确认构建上下文路径
确保在EC2上执行docker-compose up的工作目录与本地一致,避免build的context相对路径错误。比如若本地在项目根目录执行,EC2也需进入相同根目录再运行命令。
内容的提问来源于stack exchange,提问作者itsallgood

