我有以下Dockerfile内容
FROM python:3.7-slim
# Install packages needed to run your application (not build deps):
RUN mkdir /code/
WORKDIR /code/
COPY Pipfile Pipfile.lock /code/
# Install build deps, then run `pip install`, then remove unneeded build deps all in a single step.
COPY ./src scripts /code/
EXPOSE 8000
ENTRYPOINT ["/code/entrypoint.sh"]
删除了与问题无关的其他行。
我在开发中的目录结构是
|- scripts
|- entrypoint.sh
|- src
|- # Application files
|- Dockerfile
|- docker-compose.yml
entrypoint.sh
文件位于scripts/
目录中,并且正在复制到 docker 守护程序中的/code/
。通过执行来验证相同
docker run -it my_image ls -la
其中将文件列为
drwxr-xr-x 1 root root 4096 Dec 28 19:57 .
drwxr-xr-x 1 root root 4096 Dec 28 19:59 ..
-rw-r--r-- 1 root root 545 Dec 28 19:24 Pipfile
-rw-r--r-- 1 root root 21517 Dec 28 19:24 Pipfile.lock
-rwxr-xr-x 1 root root 499 Dec 28 18:47 entrypoint.sh
-rwxr-xr-x 1 root root 540 Jan 3 2019 manage.py
但是当我使用docker-compose.yml(docker-compose up
( 文件运行带有内容的映像时
version: '3.7'
services:
web:
build:
context: .
dockerfile: Dockerfile
image: my_image:latest
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code/
它给出的错误为
ERROR: for myproj_py_web_1 Cannot start service web: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: "/code/entrypoint.sh": stat /code/entrypoint.sh: no such file or directory": unknown
entrypoint.sh的内容
#!/bin/sh
set -e
if [ "x$DJANGO_MANAGE_COLLECTSTATIC" = 'xon' ]; then
echo "Collecting static files"
python manage.py collectstatic --noinput
echo "Done: Collecting static files"
fi
if [ "x$DJANGO_MANAGE_MIGRATE" = 'xon' ]; then
echo "Migrating database"
python manage.py migrate --noinput
echo "Done: Migrating database"
fi
exec "$@"
volumes:
声明隐藏图像中/code
的内容,包括/code/entrypoint.sh
脚本。 当您启动容器时,Docker 会从入口点和命令部分组合构造单个命令,因此您的两个容器具有组合命令,例如
/code/entrypoint.sh ls -la
/code/entrypoint.sh python manage.py runserver 0.0.0.0:8000
(入口点脚本通常以类似exec "$@"
的行结尾,该行启动命令部分以简化此模式。
特别是你遇到了这个问题,因为文件系统布局不匹配;你在Dockerfile中重新排列了内容。 如果你要跑
docker run --rm -it --entrypoint /bin/bash -v $PWD:/code image
你会看到一个/code/scripts/entrypoint.sh
;如果你在没有-v
选项的情况下运行它,你会看到/code/entrypoint.sh
。
对此的直接解决方案是删除volumes:
指令。 然后,Docker Compose 将运行实际内置到映像中的代码,并且不会发生此冲突。