为什么不是我的.Docker忽略文件忽略文件?



当我构建容器并检查应该忽略的文件时,大多数文件都没有被忽略。

文件夹结构.

Root/
data/
project/
__pycache__/
media/
static/
app/
__pycache__/
migrations/
templates/
.dockerignore
.gitignore
.env
docker-compose.yml
Dockerfile
requirements.txt
manage.py

假设我想忽略__pycache__&data(在创建容器时将使用docker-compose up命令创建数据)文件夹和.gitignore&.env文件。

我将用下一个.dockerignore

来忽略这些文件

.git
.gitignore
.docker
*/__pycache__/
**/__pycache__/
.env/
.venv/
venv/
data/

最后的结果是只有git&.env文件被忽略。数据文件夹没有被忽略,但无法从容器访问它。__pycache__文件夹也没有被忽略。

这些是docker文件。

docker-compose.yml

version: "3.8"
services: 
app: 
build: .
volumes: 
- .:/django-app
ports: 
- 8000:8000
command: /bin/bash -c "sleep 7; python manage.py migrate; python manage.py runserver 0.0.0.0:8000"
container_name: app-container
depends_on: 
- db
db:
image: postgres
volumes:
- ./data:/var/lib/postgresql/data
environment: 
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
container_name: postgres_db_container

Dockerfile

FROM python:3.9-slim-buster
ENV PYTHONUNBUFFERED=1
WORKDIR /django-app
EXPOSE 8000
COPY requirements.txt requirements.txt
RUN apt-get update 
&& adduser --disabled-password --no-create-home userapp 
&& apt-get -y install libpq-dev 
&& apt-get -y install apt-file 
&& apt-get -y install python3-dev build-essential 
&& pip install -r requirements.txt
USER userapp

您实际上是在使用volumes:注入源代码,而不是在映像构建期间,这并不尊重.dockerignore

像这样运行一个Docker应用程序需要两个阶段:

  1. 构建一个可重用的映像,其中包含应用程序运行时、任何操作系统和特定语言的库依赖项以及应用程序代码;然后
  2. 基于该映像运行容器。

.dockerignore文件只在第一个构建阶段被考虑。在您的设置中,除了requirements.txt文件之外,您实际上没有在图像中COPY任何内容。相反,您可以使用volumes:将主机系统的部分注入容器。这发生在第二阶段,并且忽略.dockerignore

我建议的方法是跳过volumes:,而不是COPY在Dockerfile中所需的源代码。一般来说,你也应该在Dockerfile中指定容器将运行的默认CMD,而不是在docker-compose.ymldocker run命令中要求它。

FROM python:3.9-slim-buster
# Do the OS-level setup _first_ so that it's not repeated
# if Python dependencies change
RUN apt-get update && apt-get install -y ...
WORKDIR /django-app
# Then install Python dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt
# Then copy in the rest of the application
# NOTE: this _does_ honor .dockerignore
COPY . .
# And explain how to run it
ENV PYTHONUNBUFFERED=1
EXPOSE 8000
USER userapp
# consider splitting this into an ENTRYPOINT that waits for the
# the database, runs migrations, and then `exec "$@"` to run the CMD
CMD sleep 7; python manage.py migrate; python manage.py runserver 0.0.0.0:8000

这意味着,在docker-compose.yml设置中,您不需要volumes:;应用程序代码已经在您构建的映像中。

version: "3.8"
services:
app: 
build: .
ports: 
- 8000:8000
depends_on: 
- db
# environment: [PGHOST=db]
# no volumes: or container_name:
db:
image: postgres
volumes: # do keep for persistent database data
- ./data:/var/lib/postgresql/data
environment: 
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
# ports: ['5433:5432']

这种方法还意味着当应用程序发生更改时需要docker-compose build一个新映像。这在Docker中很正常。

对于日常开发,一个有用的方法是在Docker中运行所有非应用程序依赖项,但应用程序本身在容器之外。

# Start the database but not the application
docker-compose up -d db
# Create a virtual environment and set it up
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
# Set environment variables to point at the Docker database
export PGHOST=localhost PGPORT=5433
# Run the application locally
./manage.py runserver

这样做需要使数据库从外部Docker可见(通过ports:),并使数据库位置可配置(可能通过环境变量,在Compose中设置environment:)。

这实际上不是你的情况,但通常是一个额外的原因"。Dockerignore不忽略"它将过滤器应用于相对于上下文目录的整个路径,而不仅仅是基本名称,所以模式:

__pycache__
*.pyc

只适用于docker上下文的根目录,不适用于任何子目录。

为了使其递归,将其更改为:

**/__pycache__
**/*.pyc

相关内容

最新更新