3

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

这是我的文件夹结构

Root/

  data/

  project/
    __pycache__/
    media/
    static/

  app/
    __pycache__/
    migrations/
    templates/

  .dockerignore
  .gitignore
  .env
  docker-compose.yml
  Dockerfile
  requirements.txt
  manage.py

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

我将在下一个.dockerignore文件中忽略这些

.git
.gitignore

.docker

*/__pycache__/
**/__pycache__/

.env/
.venv/
venv/

data/

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

这是泊坞窗文件。

码头工人-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
4

1 回答 1

3

您实际上是在使用 注入源代码volumes:,而不是在图像构建期间,这不符合.dockerignore.

像这样运行 Docker 应用程序分为两个阶段:

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

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

我建议的方法是跳过volumes:DockerfileCOPY中所需的源代码。您通常还应该指出CMD容器将在 Dockerfile 中运行的默认值,而不是使用docker-compose.ymlordocker 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:)。

于 2021-09-23T10:25:14.257 回答