【问题标题】:Why does docker-compose build a new image on `docker-compose up`?为什么 docker-compose 在 `docker-compose up` 上构建一个新镜像?
【发布时间】:2021-02-05 18:19:22
【问题描述】:

当我运行docker-compose up 时,为什么会创建一个新图像?如何告诉 docker-compose 使用我刚刚创建的图像运行?我在这里做错了什么?

当我从干净的系统运行命令docker build . -t prod_srdc_web 时,使用docker system prune -a,一切正常。当我在构建映像后运行 docker image ls 时,我看到以下内容:

REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
prod_srdc_web       latest              923538608c06        5 seconds ago        1.1GB
<none>              <none>              04b24dbf7c93        About a minute ago   4.23MB
python              3.7                 42d620af35be        9 days ago           918MB
alpine              3.7                 6d1ef012b567        4 months ago         4.21MB

在我运行docker-compose up 之后,一切都会重新构建并启动容器。现在docker image ps 显示了一个具有新名称srdc_django_web 的相同图像:

REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
srdc_django_web     latest              7e75a841e0fd        About a minute ago   1.1GB
prod_srdc_web       latest              923538608c06        2 minutes ago        1.1GB
<none>              <none>              04b24dbf7c93        4 minutes ago        4.23MB
python              3.7                 42d620af35be        9 days ago           918MB
alpine              3.7                 6d1ef012b567        4 months ago         4.21MB

docker-compose up 为什么要构建新镜像?理想情况下,我想使用我刚刚构建和标记的图像,prod_srdc_web

Dockerfile:

FROM alpine:3.7

RUN apk upgrade --no-cache build-base gcc python=3.7 python3-dev postgresql-dev bash git

ENV LIBRARY_PATH=lib:/usr/lib

FROM python:3.7
ENV PYTHONUNBUFFERED 1
RUN mkdir -p /code && mkdir -p /var/www/website.com/static/
WORKDIR /code

# Install dependencies
COPY requirements.txt /code/
RUN pip3 install --no-cache-dir --upgrade pip
RUN pip3 install -r requirements.txt
RUN pip3 install gunicorn

# Copy project
COPY . /code

# Copy entrypoint.prod.sh
COPY ./entrypoint.prod.sh /

EXPOSE 4500

# Run entrypoint.prod.sh
RUN [ "chmod", "+x", "./entrypoint.prod.sh" ]
ENTRYPOINT [ "./entrypoint.prod.sh" ]

docker-compose.yml

version: '3'

services:
  django_web:
    build: .
    volumes:
      - .:/srdc
    ports:
      - "4500:4500"
    container_name: srdc_c_django_web

entrypoint.prod.sh

#!/usr/bin/env bash
python manage.py makemigrations
python manage.py migrate --noinput
python manage.py collectstatic --noinput
gunicorn srdc.wsgi:application -w 3 -b 0.0.0.0:4500

看起来存储库名称 srdc_django_web 是通过将目录名称 (srdc) 与 docker-compose.yml 文件 (django_web) 中的服务名称连接起来创建的。如果我最终添加 Nginx,我想使用 docker-compose up 来运行整个容器 prod_srdc_web,而不是让它重新构建每个服务。

仅供参考,我的版本是:

Docker version 18.09.2, build 6247962
docker-compose version 1.23.2, build 1110ad01

【问题讨论】:

    标签: python docker docker-compose


    【解决方案1】:

    您的撰写文件未指定图像名称。因此,即使您提前手动构建镜像,docker-compose 也没有您要运行的构建和您已经创建的镜像的任何映射。要给出图像名称,请指定:

    version: '3'
    
    services:
      django_web:
        build: .
        image: prod_srdc_web:latest
        volumes:
          - .:/srdc
        ports:
          - "4500:4500"
        container_name: srdc_c_django_web
    

    Docker 将使用图像缓存来避免重新创建它已经拥有的相同图像层。但是,由于您有以下内容:

    COPY . /code
    

    构建上下文中的任何文件(当前目录,假设您不忽略带有.dockerignore 的文件)的更改将导致创建新图像。这可以包括文件所有权和权限,并且像 docker-compose.yml 这样的文件(如果它们在此目录中)也包括在内。

    【讨论】:

    • 我们创建了一个卷。为什么我们还要写COPY . /code
    • @AliReza 将代码添加到图像使其可用于生产或其他仅拉取图像而不是源代码的领域。挂载卷是一种有用的开发实践,可以避免每次更改都重建映像。
    • 感谢@BMitvh。我有点困惑,尽管我们有一个卷,但我们再次复制所有东西(在 Dockerfile 中)。假设你有一个 python 项目。您将所有需要的包存储在requirements,txt 文件中。每当您安装新软件包时,您都会修改文件,以便在运行的容器中拥有更新的文件。 (容器中没有安装包)现在,您需要重建您的图像。我的意思是,你首先需要复制项目,但之后有一个卷可以消除这些步骤,
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 2018-12-18
    • 2016-02-16
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多