更新docker容器中的代码

bil*_*lba 12 django docker docker-compose

我已经设置了一个docker django容器并使用build 在这里构建了它的图像.本教程展示了如何制作基本的django应用程序并将应用程序安装到"/ code",据我所知,它包含在数据卷中.

但是,我想了解我将如何更新和开发此代码,并能够发布/部署它.因为当我进行提交时,它不会考虑代码中的任何更改,因为它是数据卷的一部分.

有什么办法可以让django代码成为图像的一部分,或用更新的代码更新图像?

Phi*_*nan 6

根据我的经验,Docker 有两个目的:

  1. 能够在容器化环境中开发代码。这非常有用,因为我现在可以在大约 5 分钟内让我的团队中的新开发人员准备好工作。以前,对于其他问题,这可能需要一个小时到几个小时,尤其是在旧项目中。
  2. 能够在容器化环境中打包应用程序。这也是一个很好的节省时间的方法,因为环境的唯一要求是安装 Docker。

在开发代码时,您应该挂载源/卷,以便您的更改始终反映在容器内。当你想打包一个应用程序进行部署时,你应该COPY将源代码放入容器并适当地打包。

这是一个 docker-compose 文件,我用来 (1) 构建要开发的映像,(2) 开发我的代码,以及 (3) 发布它(我正在使用 spring boot):

version: '3.7'
services:
  dev:
    image: '${MVN_BUILDER}'
    container_name: '${CONTAINER_NAME}'
    ports:
      - '8080:8080'
    volumes:
      - './src:/build/src'
      - './db:/build/db'
      - './target:/build/target'
      - './logs:/build/logs'
    command: 'mvn spring-boot:run -Drun.jvmArguments="-Xmx512m" -Dmaven.test.skip=true'
  deploy:
    build:
      context: .
      dockerfile: Dockerfile-Deploy
      args:
        MVN_BUILDER: '${MVN_BUILDER}'
    image: '${DEPLOYMENT_IMAGE}'
    container_name: '${CONTAINER_NAME}'
    ports:
      - '8080:8080'
  maven:
    build:
      context: .
      dockerfile: Dockerfile
    image: '${MVN_BUILDER}'
    container_name: '${CONTAINER_NAME}'
Run Code Online (Sandbox Code Playgroud)
  1. 我会跑去docker-compose build maven建立我的基本形象。这是必需的,以便当我在容器中运行我的代码时,所有依赖项都安装在映像中。为此,Dockerfile 基本上复制到pom.xml映像中并下载应用程序所需的依赖项。请注意,这需要在依赖项更改时随时执行。这是用于构建maven服务中引用的映像的 Dockerfile :
### BUILD a maven builder. This will contain all mvn dependencies and act as an abstraction for all mvn goals
FROM maven:3.5.4-jdk-8-alpine as builder

#Copy Custom Maven settings
#COPY settings.xml /root/.m2/

# create app folder for sources
RUN mkdir -p /build
RUN mkdir -p /build/logs

# The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile.
WORKDIR /build
COPY pom.xml /build
#Download all required dependencies into one layer
RUN mvn -B dependency:go-offline dependency:resolve-plugins
RUN mvn clean install
Run Code Online (Sandbox Code Playgroud)
  1. 接下来,我将运行docker-compose up dev以启动我的dev服务并开始开发我的应用程序。该服务将我的代码挂载到容器中,并使用 Maven 启动 Spring Boot 应用程序。每当我更改代码时,spring boot 都会重新启动服务器并反映我的更改。

  2. 最后,一旦我对我的应用程序感到满意,我就会构建一个映像,该映像将我的应用程序打包以使用docker-compose build deploy. 我使用两阶段构建过程首先将源复制到容器中并将其打包以进行部署,Jar然后将Jar其放入第二阶段,在那里我可以简单地运行java -jar build/app.jar(在容器中)以启动我的应用程序,第一阶段是移除。就是这样!现在你可以在任何安装了 Docker 的地方部署这个最新的镜像。

这是最后一个 Dockerfile (Dockerfile-Deploy) 的样子:

ARG MVN_BUILDER
### Stage 1 - BUILD image
FROM $MVN_BUILDER as builder
COPY src /build/src
RUN mvn clean package -PLOCAL

### Stage 2 - Deploy Jar
FROM openjdk:8
RUN mkdir -p /build
COPY --from=builder /build/target/*.jar /build/app.jar
EXPOSE 8080  
ENTRYPOINT ["java","-jar","build/app.jar"] 
Run Code Online (Sandbox Code Playgroud)

这里的.env文件与文件在同一目录中docker-compose。我用它来抽象图像/容器名称,并在需要新图像时简单地在一个地方增加版本号。

MVN_BUILDER=some/maven/builder:0.1
DEPLOYMENT_IMAGE=some/deployment/spring:0.1
CONTAINER_NAME=spring-container
CONTAINER_NAME_DEBUG=spring-container-debug
Run Code Online (Sandbox Code Playgroud)


Far*_*igo 5

我认为现在回答你的问题已经太晚了,但是,这对于其他伸出援手的人来说可能是有益的。

你提到的教程对于初次使用的人来说有点棘手,所以,我稍微改变了结构。我假设您有一个 docker 注册表帐户(如 Dockerhub),用于将映像发布到。如果您想访问远程主机上的映像,则这是必需的(您可以复制实际的映像文件,但不推荐)。

创建一个项目

假设您要使用 Django 创建一个网站并对其进行 dockerize,首先,您需要执行以下操作:

django-admin startproject samplesite
Run Code Online (Sandbox Code Playgroud)

它创建一个samplesite包含以下内容的目录(我添加了requirements.txt):

db.sqlite3  manage.py  requirements.txt  samplesite
Run Code Online (Sandbox Code Playgroud)

添加 Dockerfile 和 docker-compose.yml

对于Dockerfile,如您所见,与 相比,没有任何变化Dockerfile

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
Run Code Online (Sandbox Code Playgroud)

然而对于docker-compose.yml

version: '3'

services:
  db:
    image: postgres
  web:
    build: .
    image: yourUserNameOnDockerHub/mywebsite:0.1  # this line is added
    command: python manage.py runserver 0.0.0.0:8000
    #volumes:
    #  - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml也与教程中提到的几乎相同,只是注释了卷并添加了一行image: mywebsite:0.1。该行允许我们跟踪构建的映像并在需要时部署它。卷挂载与您编写的代码无关,放在那里是为了取出Django 更改的动态内容(sqlite、上传的文件等)。

构建并运行

如果您docker-compose up第一次运行,一切正常,但是,由于添加了新行,当您在第一次之后更改代码时,更改将不会反映在运行的容器中。这是因为在每个 上docker-compose up, compose 都会查找mywebsite:0.1(已经存在的)并且不会构建新图像并基于旧图像创建一个容器。由于我们需要该图像名称和标签来发布/部署我们的图像,因此我们需要使用:

docker-compose up --build
Run Code Online (Sandbox Code Playgroud)

它将重新构建反映更改的图像。每次进行一些更改时,运行它并创建一个新的图像,可以通过以下方式查看(请注意,虽然名称和标签保持不变,但图像 ID 的更改表明这是一个新图像):

$ docker images
REPOSITORY                                   TAG                 IMAGE ID            CREATED             SIZE
yourUserNameOnDockerHub/mywebsite            0.1                 033c9d2bfac0        7 seconds ago       974MB
Run Code Online (Sandbox Code Playgroud)

发布和部署

如果您已在 Dockerhub(或任何其他注册表)上设置了帐户,则可以发布映像以供以后使用或部署在远程服务器上:

docker push yourUserNameOnDockerHub/mywebsite:01 
Run Code Online (Sandbox Code Playgroud)

如果你想将其部署在远程主机上并想再次使用 docker-compose,只需将其更改docker-compose.yml为:

version: '3'

services:
  db:
    image: postgres
  web:
    image: yourUserNameOnDockerHub/mywebsite:0.1 
    command: python manage.py runserver 0.0.0.0:8000
    #volumes:
    #  - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
Run Code Online (Sandbox Code Playgroud)

请注意,该build: .行已被删除(因为我们将仅运行它)。在本地开发时,每当您运行docker-compose up --build一个新图像时,都会创建并标记一个新图像,并且基于该图像的容器将在撰写堆栈中运行。如果您认为对更改感到满意,则可以按照发布步骤将其发布到服务器上。


ale*_*jdg -1

在教程的第 9 步中,您设置了音量。该卷将链接您的当前目录和容器/code目录。换句话说,它们将是相同的。

因此,对本地文件的任何更新也会更改容器中的文件。请记住,您需要重新启动应用程序才能使更改生效。

在部署映像之前,您需要创建第二个 docker compose 文件。该文件将删除该卷,因此代码将保留在容器内并且不会从外部更改。您可以按照docker compose 文档中提供的步骤进行操作。