【问题标题】:Why isn't my .Dockerignore file ignoring files?为什么我的 .Dockerignore 文件不忽略文件?
【发布时间】:2021-11-16 17:02:48
【问题描述】:

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

这是我的文件夹结构

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

【问题讨论】:

    标签: python django docker dockerignore


    【解决方案1】:

    您实际上是在使用 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: 设置)。

    【讨论】:

    • 因此,如果我理解正确... 将 docker-compose 与我拥有的两个服务和我当前的 conf(用于日常开发)一起使用,如果我想共享我的容器,.dockerignore 将永远无法工作, 正确的?在这种情况下,我有两个选择,每当我想共享它时重建图像而不是按卷传递代码(如您所解释的)或使用仅在 Docker 外部运行应用程序的方法
    • 如果您想分享您的 图像.dockerignore 文件将控制复制到其中的内容。您不会单独分发代码,只需将图像推送到 Docker 注册表。
    猜你喜欢
    • 2022-11-28
    • 1970-01-01
    • 2018-01-06
    • 2018-06-29
    • 2015-02-03
    • 2019-07-14
    • 2011-04-19
    • 2016-02-18
    • 1970-01-01
    相关资源
    最近更新 更多