使用Docker的监视功能进行CI/CD。

huangapple go评论80阅读模式
英文:

Using docker watch feature for CI/CD

问题

我对“实验性”的Docker Compose监视功能很感兴趣:[1] [2]

可用的两种操作是“同步”和“重建”(实际上是重建+重启)。

我需要这个功能来实现持续部署:我只希望Docker能够检测到我已更改了.envdocker-compose.yml文件(通过更新要拉取的镜像版本) - 然后重新启动容器。不需要重新构建,因为我首先并未构建镜像,而是从Docker注册表中拉取它。

我该如何做到这一点?

英文:

I'm interested in the "experimental" docker compose watch feature: [1] [2].

The two actions available are "sync" and "rebuild" (which is actually rebuild + restart).

I need this for continuous deployment: all I want is docker to detect that I've changed the .env or docker-compose.yml file (by updating the image version to be pulled) - and to restart the container. No rebuilding is necessary, as I'm not building the image in the first place but rather pulling it from a docker registry.

How can I do that?

答案1

得分: 1

我已尝试了许多方法,似乎不可能在修改.envdocker-compose.yml时更新/重新启动容器。由于某种原因,更改这些文件会重新启动容器,但不会遵守更改。

但是,你可以实现你想要的效果,但不是修改.envdocker-compose.yml,而是需要定义一个中间的Dockerfile,然后直接对该文件进行更改。对我来说,这更容易,因为所有更改都局限于该Dockerfile。你可以在docker-compose.yml中定义以下内容:

services:
  myapp:
    build:
      context: ./myapp
    x-develop:
      watch:
        - action: rebuild
          path: ./myapp/Dockerfile

无论如何,以下是一个示例,使用来自DockerHub的envoyproxy/envoy镜像

示例

具有以下目录结构:

$ tree
.
├── docker-compose.yml
└── envoy
    ├── Dockerfile
    └── envoy.yaml # 没关系,这只是一个虚拟的配置文件

以及以下文件:

  • envoy/Dockerfile
FROM envoyproxy/envoy:v1.27.0

ENV ENVOY_UID=1234
  • docker-compose.yml
version: '3'

services:
  envoy:
    build:
      context: ./envoy
    ports:
      - "9901:9901"
    volumes:
      - ./envoy/envoy.yaml:/etc/envoy/envoy.yaml
    x-develop:
      watch:
        - action: rebuild
          path: ./envoy/Dockerfile

对于你在问题中提到的对envoy/Dockerfile的任何更改,比如:

  • 更新镜像(FROM指令):相当于在你的问题中更改docker-compose.yml中的镜像
  • 更新/添加/删除环境变量(ENV指令):相当于在你的问题中更改.env

都将触发镜像的重建,并使用新值重新启动。

你可以通过执行以下操作来测试它是否正常工作:

$ docker compose up -d 2>/dev/null

$ docker compose alpha watch

然后在另一个窗口中:

$ # 检查 envoy 版本(与 Dockerfile 中的版本匹配)
$ curl -s http://localhost:9901/server_info | jq -r .version | cut -d / -f 2
1.27.0

$ # 检查 ENVOY_UID 环境变量
$ docker inspect 76803907-using-docker-watch-feature-for-ci-cd-envoy | jq -r '.[0].Config.Env' | grep 'ENVOY_UID'
"ENVOY_UID=1234"

$ # 进行一些更改(镜像版本、环境变量)
$ sed -i -e 's/v1.27.0/v1.21.0/' -e 's/ENVOY_UID=1234/ENVOY_UID=5678/' envoy/Dockerfile

$ # 等待几秒钟,直到 docker compose 重新启动容器...
$ sleep 5

$ # 检查 envoy 版本已更新!
$ curl -s http://localhost:9901/server_info | jq -r .version | cut -d / -f 2
1.21.0

$ # 检查 ENVOY_UID 环境变量已更新!
$ docker inspect 76803907-using-docker-watch-feature-for-ci-cd-envoy | jq -r '.[0].Config.Env' | grep 'ENVOY_UID'
"ENVOY_UID=5678"
英文:

I've tried many things, and it does not seem possible to update/restart the containers when modifying either .env or docker-compose.yml. For some reason, changing these files restarts the container, but does not honor the changes.

However, you can achieve what you want, but instead of modifying .env or docker-compose.yml, it requires defining an intermediate Dockerfile and make changes to that file directly. To me, it's even easier because all changes are localized to that Dockerfile. And you can define the following in your docker-compose.yml:

services:
  myapp:
    build:
      context: ./myapp
    x-develop:
      watch:
        - action: rebuild
          path: ./myapp/Dockerfile

Anyway, here's an example below with envoyproxy/envoy image from DockerHub.

Example

With the following directory structure:

$ tree
.
├── docker-compose.yml
└── envoy
    ├── Dockerfile
    └── envoy.yaml # it does not matter, it's just a dummy config file

And the following files:

  • envoy/Dockerfile
FROM    envoyproxy/envoy:v1.27.0

ENV     ENVOY_UID=1234
  • docker-compose.yml:
version: '3'

services:
  envoy:
    build:
      context: ./envoy
    ports:
      - "9901:9901"
    volumes:
      - ./envoy/envoy.yaml:/etc/envoy/envoy.yaml
    x-develop:
      watch:
        - action: rebuild
          path: ./envoy/Dockerfile

Any changes to envoy/Dockerfile you've asked in your question, like:

  • updating the image (FROM directive): equivalent of changing the image in docker-compose.yml in your question
  • updating/adding/removing an environment variable (ENV directive): equivalent of changing the .env in your question

will trigger a rebuild of the image, and restart with the new values.

You can test it works by doing:

$ docker compose up -d 2>/dev/null

$ docker compose alpha watch

And in another window:

$ # check envoy version (matches the version in Dockerfile)
$ curl -s http://localhost:9901/server_info | jq -r .version | cut -d / -f 2
1.27.0

$ # check ENVOY_UID env var
$ docker inspect 76803907-using-docker-watch-feature-for-ci-cd-envoy | jq -r '.[0].Config.Env' | grep 'ENVOY_UID'
  "ENVOY_UID=1234"

$ # make some changes (image version, env var)
$ sed -i -e 's/v1.27.0/v1.21.0/' -e 's/ENVOY_UID=1234/ENVOY_UID=5678/' envoy/Dockerfile

$ # wait a few seconds while docker compose is restarting the container...
$ sleep 5

$ # check envoy version has been updated!
$ curl -s http://localhost:9901/server_info | jq -r .version | cut -d / -f 2
1.21.0

$ # check ENVOY_UID env var has been updated!
$ docker inspect 76803907-using-docker-watch-feature-for-ci-cd-envoy | jq -r '.[0].Config.Env' | grep 'ENVOY_UID'
  "ENVOY_UID=5678"

huangapple
  • 本文由 发表于 2023年7月31日 21:02:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803907.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定