如何防止在代码更改时必须重建映像

Mic*_*one 4 flask docker

我开始在个人项目中使用 Docker,并意识到这将我的开发时间增加到了无法接受的程度。如果我必须为每次代码更改重建映像,我宁愿启动 LXC 实例。

我听说有一种方法可以安装它,但不确定具体如何进行。我还有一个 docker compose yaml 文件,但我认为您在 Dockerfile 中安装了卷或其他内容?目标是让代码更改不需要重建容器镜像。

FROM ubuntu:18.04
EXPOSE 5000

# update apt
RUN apt-get update -y
RUN apt-get install -y --no-install-recommends build-essential gcc wget

# pip installs
FROM python:3.10

# TA-Lib
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
  tar -xvzf ta-lib-0.4.0-src.tar.gz && \
  cd ta-lib/ && \
  ./configure && \
  make && \
  make install

RUN rm -R ta-lib ta-lib-0.4.0-src.tar.gz

ADD app.py /
RUN pip install --upgrade pip setuptools
RUN pip install pymysql
COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
RUN pip freeze >> /tmp/requirement.txt

COPY . /tmp
CMD ["python", "/tmp/app.py"]

RUN chmod +x ./tmp/start.sh
RUN ./tmp/start.sh
Run Code Online (Sandbox Code Playgroud)
version: '3.8'
services: 
  db:
    image: mysql:8.0.28
    command: '--default-authentication-plugin=mysql_native_password'
    restart: always
    environment:
      - MYSQL_DATABASE=#########
      - MYSQL_ROOT_PASSWORD=####

  # client:
  #   build: client
  #   ports: [3000]
  #   restart: always

  server:
    build: server
    ports: [5000]
    restart: always
Run Code Online (Sandbox Code Playgroud)

Nic*_*ell 7

以下是我建议的加快开发速度的建议:

将挂载代码绑定到容器中

绑定挂载是容器和主机之间共享的目录。这是它的语法:

version: '3.8'
services: 
  # ... other services ...

  server:
    build: server
    ports: [5000]
    restart: always
    volumes:
      # Map the server directory in into the container at /code
      - ./server:/code
Run Code Online (Sandbox Code Playgroud)

挂载的第一部分./server与 docker-compose.yml 文件所在的目录相关。如果服务器目录和 docker-compose.yml 文件位于不同的目录中,则需要更改这部分。

之后,您需要删除 Dockerfile 中将代码复制到容器中的部分。像这样的东西:

# pip installs
FROM python:3.10

# TA-Lib
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
  tar -xvzf ta-lib-0.4.0-src.tar.gz && \
  cd ta-lib/ && \
  ./configure && \
  make && \
  make install

RUN rm -R ta-lib ta-lib-0.4.0-src.tar.gz

RUN pip install --upgrade pip setuptools
RUN pip install pymysql
COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt

CMD ["python", "/code/app.py"]
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是,当您在编辑器中点击“保存”时,更改将立即传播到容器中,而不需要重建。

语法文档

关于生产构建的注意事项:我不建议在运行生产服务器时进行绑定安装。在这种情况下,我建议将代码复制到容器中,而不是使用绑定安装。这使得升级正在运行的服务器变得更加容易。我通常编写两个 Dockerfile 和两个 docker-compose.yml 文件:一组用于生产,一组用于开发。

将代码复制到容器之前安装依赖项

Dockerfile 的一部分导致了大部分速度缓慢。就是这一部分:

ADD app.py /
# ... snip two lines ...
COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
Run Code Online (Sandbox Code Playgroud)

这会破坏 Docker 的层缓存。Docker 能够缓存层,并在该层中没有任何更改的情况下使用缓存。但是,如果图层发生更改,则更改后的任何图层都将被重建。这意味着更改app.py将导致pip install --requirement /tmp/requirements.txt线路再次运行。

要利用缓存,您应该遵循以下规则:最不频繁更改的文件放在最前面,最频繁更改的文件放在最后。由于更改项目中的代码比更改正在使用的依赖项更频繁,这意味着您应该在安装依赖项后复制 app.py 。

Dockerfile 会像这样改变:

COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt

# After installing dependencies
ADD app.py /
Run Code Online (Sandbox Code Playgroud)

在我的项目中,我发现即使我没有使用绑定安装技巧,在不更改依赖项的情况下重建容器也需要大约一秒钟的时间。

有关更多信息,请参阅有关层缓存的文档

删除未使用的阶段

Dockerfile 中有两个阶段:

FROM ubuntu:18.04
# ... snip ...
FROM python:3.10
Run Code Online (Sandbox Code Playgroud)

FROM命令意味着您将丢弃映像中的所有内容并从新的基础映像开始。这意味着这两行之间的所有内容都没有真正执行任何操作。要解决此问题,请删除第二条FROM语句之前的所有内容。

为什么要使用多阶段构建?有时,安装编译器、编译某些内容,然后将其复制到新映像中会很有用。例子

合并安装和删除步骤

如果要删除文件,应在创建该文件的同一层中执行此操作。原因是删除前一层中的文件并不能完全删除该文件:该文件仍然占用图像中的空间。像div这样的工具可以向您显示存在此问题的文件。

以下是我建议更改此部分的方法:

RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
  tar -xvzf ta-lib-0.4.0-src.tar.gz && \
  cd ta-lib/ && \
  ./configure && \
  make && \
  make install

RUN rm -R ta-lib ta-lib-0.4.0-src.tar.gz
Run Code Online (Sandbox Code Playgroud)

合并rm到上一步中:

RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
 tar -xvzf ta-lib-0.4.0-src.tar.gz && \
 cd ta-lib/ && \
 ./configure && \
 make && \
 make install && \
 cd .. && \
 rm -R ta-lib ta-lib-0.4.0-src.tar.gz
Run Code Online (Sandbox Code Playgroud)