Dockerfile复制文件成功但容器内无法找到,请求技术排查
问题解决:Docker镜像中复制的文件在容器中无法找到
问题描述
Dockerfile执行过程无报错,文件复制步骤显示成功,但镜像构建完成后,容器执行command: ls -la /app命令时,无法找到已复制的文件(例如entrypoint.sh)。
配置文件
docker-compose.yml
version: '3.8' services: web: build: context: . dockerfile: Dockerfile command: ls -la /app volumes: - ./ecommerce:/app ports: - "8000:8000" depends_on: - redis - rabbitmq environment: - DEBUG=${DEBUG} - DJANGO_SECRET_KEY=${DJANGO_SECRET_KEY} - DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} - DEVELOPMENT_MODE=${DEVELOPMENT_MODE} - STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY} - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY} - STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET} - REDIS_HOST=redis - CELERY_BROKER_URL=amqp://guest:guest@rabbitmq:5672// redis: image: redis:alpine rabbitmq: image: rabbitmq:3-management ports: - "5672:5672" - "15672:15672" environment: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest
Dockerfile
# Use the official Python image from the Docker Hub FROM python:3.9-slim # Set environment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # Set the working directory WORKDIR /app # Install system dependencies RUN apt-get update && apt-get install -y \ build-essential \ libpq-dev \ libpango1.0-0 \ libcairo2 \ libgdk-pixbuf2.0-0 \ libffi-dev \ shared-mime-info \ && rm -rf /var/lib/apt/lists/* # Install Python dependencies COPY requirements.txt /app RUN pip install --upgrade pip RUN pip install -r requirements.txt # Copy the entrypoint script into the container COPY ./entry/entrypoint.sh /app <--- this runs OK but it not listed in the container RUN chmod +x /app/entrypoint.sh # Copy the Django project code into the container COPY ./ecommerce /app # Collect static files RUN python manage.py collectstatic --noinput
问题原因
核心问题出在docker-compose.yml中的卷挂载配置:
volumes: - ./ecommerce:/app
容器启动时,本地./ecommerce目录会直接挂载到容器内的/app目录,这会完全覆盖镜像构建阶段复制到/app下的所有文件(包括entrypoint.sh、requirements.txt等),因此执行ls -la /app只能看到本地./ecommerce的内容,看不到镜像中原本复制的文件。
解决方案
方案1:移除本地卷挂载(生产环境推荐)
如果不需要本地代码热更新,直接删除volumes配置,容器将使用镜像内置的/app内容:
services: web: build: context: . dockerfile: Dockerfile command: ls -la /app # 移除卷挂载配置 ports: - "8000:8000" # 其余配置保持不变
方案2:调整卷挂载路径(开发环境热更新)
若需要本地代码热更新,不要直接挂载到/app,而是挂载到/app下的子目录,同时修改Dockerfile的复制路径:
- 修改Dockerfile:
# 将项目代码复制到/app/ecommerce子目录 COPY ./ecommerce /app/ecommerce # 收集静态文件时指定manage.py路径 RUN python /app/ecommerce/manage.py collectstatic --noinput
- 修改docker-compose.yml的卷挂载:
volumes: - ./ecommerce:/app/ecommerce
这样本地代码仅覆盖子目录,不会影响/app下的entrypoint.sh等文件。
方案3:将entrypoint.sh放在挂载目录外
如果必须挂载/app,可将entrypoint.sh复制到容器的其他目录(如/usr/local/bin),避免被卷覆盖:
- 修改Dockerfile:
# 复制entrypoint到/usr/local/bin COPY ./entry/entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/entrypoint.sh # 设置容器启动的entrypoint ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
内容的提问来源于stack exchange,提问作者Rodragon
相关产品推荐
相关产品推荐

