更新docker容器中的代码

时间:2016-09-21 11:32:10

标签: docker

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

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

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

4 个答案:

答案 0 :(得分:4)

以我的经验,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}'
  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
  1. 接下来,我将运行docker-compose up dev以启动我的dev服务并开始开发我的应用程序。该服务将我的代码安装到容器中,并使用Maven启动Spring Boot应用程序。每当我更改代码时,Spring Boot都会重新启动服务器,并反映出我的更改。

  2. 最后,一旦我对我的应用程序感到满意,我将构建一个映像,该映像将我的应用程序打包为使用docker-compose build deploy进行部署。我使用两个阶段的构建过程,首先将源复制到容器中并打包为Jar进行部署,然后将Jar放入第二阶段,我可以简单地运行{{1} }(在容器中)启动我的应用程序,并且第一阶段已删除。而已!现在,您可以在安装了Docker的任何地方部署此最新映像。

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

java -jar build/app.jar

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"] 文件放在与.env文件相同的目录中。我使用它来抽象图像/容器名称,并在需要新图像时将版本号简单地放在一个位置。

docker-compose

答案 1 :(得分:0)

如果您想更新图片,可以说由于您的应用程序代码更改,您在构建图片时使用COPY,因此在Dockerfile中您可以执行类似

的操作
COPY /you/code/on/the/host /var/www

另请参阅我对“卷”和图像构建https://stackoverflow.com/a/39314602/3625317的回答,以阐明构建中缺少代码的原因

答案 2 :(得分:0)

我认为现在回答您的问题为时已晚,但是,这对其他伸出援手的人可能是有益的。

您提到的教程对于初学者来说有些棘手,因此,我对结构进行了一些更改。我假设您有一个Docker注册表帐户(例如Dockerhub),用于将映像发布到该帐户。如果要访问远程主机上的图像,这是必需的(可以复制实际的图像文件,但不建议这样做)。

创建项目

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

django-admin startproject samplesite

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

db.sqlite3  manage.py  requirements.txt  samplesite

添加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/

但是对于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

docker-compose.yml也几乎与本教程中提到的相同,只是注释了体积,并添加了一行image: mywebsite:0.1。这行代码使我们可以跟踪构建的映像并在需要时进行部署。卷安装无关,与您编写的代码无关,它被放置在其中取出 Django更改的动态内容(sqlite,上传的文件等)。

构建并运行

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

docker-compose up --build

它将重新构建反映了更改的图像 。每次进行一些更改时,都运行它,并创建一个新的可见图像(请注意,尽管名称和标记保持不变,但图像ID的更改表明这是一个新图像):

$ docker images
REPOSITORY                                   TAG                 IMAGE ID            CREATED             SIZE
yourUserNameOnDockerHub/mywebsite            0.1                 033c9d2bfac0        7 seconds ago       974MB

发布和部署

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

docker push yourUserNameOnDockerHub/mywebsite:01 

如果要将其部署在远程主机上并想再次使用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

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

答案 3 :(得分:-1)

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

因此,对本地文件的任何更新都将更改容器中的文件。请记住,您需要重新启动应用,以便进行更改。

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