【问题标题】:How to update source code without rebuilding image each time?如何更新源代码而不每次都重建图像?
【发布时间】:2021-11-29 14:01:14
【问题描述】:

有没有办法避免每次我对源代码进行更改时都重新构建我的 Docker 映像?

我认为我已经优化了我的 Dockerfile 以减少构建时间,但它总是 2 个命令和一些等待时间,有时只添加一行代码。它比简单的 CTRL + S 更长,然后检查结果。

对于代码中的每个小更新,我必须执行的命令:

docker-compose down
docker-compose build
docker-compose up

这是我的 Dockerfile:

FROM python:3-slim as development

ENV PYTHONUNBUFFERED=1

COPY ./requirements.txt /requirements.txt
COPY ./scripts /scripts

EXPOSE 80

RUN apt-get update && \
    apt-get install -y \
    bash \
    build-essential \
    gcc \
    libffi-dev \
    musl-dev \
    openssl \
    wget \
    postgresql \
    postgresql-client \
    libglib2.0-0 \
    libnss3 \
    libgconf-2-4 \
    libfontconfig1 \
    libpq-dev && \
    pip install -r /requirements.txt && \
    mkdir -p /vol/web/static && \
    chmod -R 755 /vol && \
    chmod -R +x /scripts

COPY ./files /files

WORKDIR /files

ENV PATH="/scripts:/py/bin:$PATH"

CMD ["run.sh"]

这是我的 docker-compose.yml 文件:

version: '3.9'

x-database-variables: &database-variables
  POSTGRES_DB: ${POSTGRES_DB}
  POSTGRES_USER: ${POSTGRES_USER}
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
  ALLOWED_HOSTS: ${ALLOWED_HOSTS}

x-app-variables: &app-variables
  <<: *database-variables
  POSTGRES_HOST: ${POSTGRES_HOST}
  SPOTIPY_CLIENT_ID: ${SPOTIPY_CLIENT_ID}
  SPOTIPY_CLIENT_SECRET: ${SPOTIPY_CLIENT_SECRET}
  SECRET_KEY: ${SECRET_KEY}
  CLUSTER_HOST: ${CLUSTER_HOST}
  DEBUG: 0

services:
  website:
    build:
      context: .
    restart: always
    volumes:
      - static-data:/vol/web
    environment: *app-variables
    depends_on:
      - postgres

  postgres:
    image: postgres
    restart: always
    environment: *database-variables
    volumes:
      - db-data:/var/lib/postgresql/data

  proxy:
    build:
      context: ./proxy
    restart: always
    depends_on:
      - website
    ports:
      - 80:80
      - 443:443
    volumes:
      - static-data:/vol/static
      - ./files/templates:/var/www/html
      - ./proxy/default.conf:/etc/nginx/conf.d/default.conf
      - ./etc/letsencrypt:/etc/letsencrypt

volumes:
  static-data:
  db-data:

【问题讨论】:

  • 你不需要运行docker-compose down。您可以重组 Dockerfile 以提高效率:RUN apt-get install 在您之前 COPY 任何东西;然后COPY requirements.txtRUN pip install然后 COPY 在您的应用程序的其余部分。这样,如果只有 scripts 目录发生更改,您就不会重复缓慢调用网络的“安装”步骤。
  • 谢谢你的回答,我马上去实施!

标签: docker docker-compose dockerfile


【解决方案1】:

通过docker-compose.yml直接在容器中挂载你的脚本文件:

volumes:
  - ./scripts:/scripts
  - ./files:/files

请记住,如果您在 Dockerfile 中使用 WORKDIR,则必须使用前缀。

【讨论】:

    【解决方案2】:

    快速回答

    有没有办法避免每次我对源代码进行更改时都重新构建我的 Docker 映像?

    如果您的应用需要构建步骤,则不能跳过它。

    在你的情况下,你可以在 python 应用程序之前启动需求,所以在每次源代码修改时,你只需要构建和运行你的 python 应用程序,而不是整个堆栈:postgress、代理等

    Docker 用途

    Docker 的主要目标或功能是让开发人员能够将应用程序打包到易于在任何地方部署的容器中,从而简化您的基础架构。

    所以,从这个意义上说,docker 并不是严格意义上的开发者阶段。在开发阶段,程序员应该使用专门的IDE(eclipse、intellij、visual studio等)来创建和更新源代码。

    这些 IDE 具有热重载(源代码更改时自动更新应用程序)、变量和方法自动完成等功能。这些功能可以减少开发人员的时间。

    Docker 用于由开发人员更改源代码

    不是主要目标,但如果您没有专门的 ide 或者您在非常有限的开发人员工作区中,docker 可以拯救您

    如果您是 Java 开发人员(例如),您需要在您的机器上安装 java 和一些 IDE(如 eclipse),配置 maven 等。使用 docker,您可以创建包含所有必需技术和在您的源代码docker容器之间建立一种连接。 docker 中的这种连接称为 Volumes

    对于需要构建过程的技术:java 和 c#,会有时间损失,因为开发人员应该对任何源代码更改执行构建。正如我所解释的,使用专门的 ide 不需要这样做。

    对于不需要构建过程的技术,例如:php,只需安装库/依赖项,docker 的工作方式几乎与专用 IDE 相同。

    使用热重载进行本地开发的 Docker

    在您的情况下,您的应用基于 python。 Python 不需要构建过程。只是库的安装,所以如果你想使用 docker 而不是经典方式使用 python 进行开发:安装 python、执行 python app.py 等,你应该按照以下步骤操作:

    • 不要将源代码复制到容器中
    • 只需将 requirements.txt 传递给容器
    • 在容器内执行 pip install
    • 在容器内运行您的应用
    • 创建一个 docker 卷:您的源代码 -> 容器上的内部文件夹

    这里是一些带有热重载的python框架的例子:

    FROM python:3
    RUN mkdir -p /usr/src/app
    WORKDIR /usr/src/app
    COPY requirements.txt /usr/src/app
    RUN pip install -r requirements.txt
    CMD [ "mkdocs", "serve",  "--dev-addr=0.0.0.0:8000" ]
    

    以及如何构建为开发版本:

    docker build -t myapp-dev .
    

    以及如何使用卷运行它以同步您的开发人员对容器的更改:

    docker run --name myapp-dev -it --rm -p 8000:8000 -v $(pwd):/usr/src/app mydocs-dev
    

    总而言之,这将是在开发人员阶段使用 docker 运行您的应用程序的流程:

    • 在应用之前启动需求(数据库、api等)
    • 为开发阶段创建一个特殊的 Dockerfile
    • 为开发目的构建 docker 映像
    • 运行应用程序,将源代码与容器 (-v) 同步
    • 开发者修改源代码
    • 如果你可以在 python 上使用某种热重载库
      • 应用已准备好从浏览器打开

    Docker 用于本地开发,无需热重载

    如果您不能使用热重载库,则需要随时构建并运行来测试您的源代码修改。在这种情况下,您应该将源代码复制到容器中,而不是像以前的方法那样与卷同步:

    FROM python:3
    RUN mkdir -p /usr/src/app
    COPY . /usr/src/app
    WORKDIR /usr/src/app
    RUN pip install -r requirements.txt
    RUN mkdocs build
    WORKDIR /usr/src/app/site
    CMD ["python", "-m", "http.server", "8000" ]
    

    步骤应该是:

    • 在应用之前启动需求(数据库、api等)
    • 为开发阶段创建一个特殊的 Dockerfile
    • 开发者修改源代码
    • 构建
    docker build -t myapp-dev.
    
    • 运行
    docker run --name myapp-dev -it --rm -p 8000:8000 mydocs-dev
    

    【讨论】:

      猜你喜欢
      • 2021-10-16
      • 1970-01-01
      • 2018-09-26
      • 1970-01-01
      • 2017-08-25
      • 2012-03-06
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多