Docker Compose 持续部署设置

9
我正在寻找一种方法将docker-compose镜像和/或构建部署到远程服务器,尤其是但不限于 DigitalOcean VPS。
目前,在CircleCI持续集成服务上docker-compose正在工作,并自动验证测试是否通过。但是,它应该在成功后自动部署。
我的docker-compose.yml看起来像这样:
version: '2'
services:
  web:
    image: name/repo:latest
    ports:
      - "3000:3000"
    volumes:
      - /app/node_modules
      - .:/app
    depends_on: 
      - mongo
      - redis
  mongo:
    image: mongo
    command: --smallfiles
    volumes:
      - ./data/mongodb:/data/db
  redis:
    image: redis
    volumes:
      - ./data/redis:/data

docker-compose.override.yml:

version: '2'
services:
  web:
    build: .

circle.yml 相关部分:

deployment:
  latest:
    branch: master
    commands:
      - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
      - docker push name/repo:$CIRCLE_SHA1
      - docker push name/repo:latest
2个回答

12

您的docker-composecircle配置已经看起来非常不错。

您的docker-compose.yml已经设置好从Docker Hub获取镜像,这个镜像在测试通过后上传。我们将在远程服务器上使用此镜像,而不是每次构建镜像(这需要很长时间),我们将使用这个已经准备好的镜像。

您很好地将build: .分离到了docker-compose.override.yml文件中,因为如果我们使用docker-compose.prod.yml文件,则可能会出现优先级问题

让我们开始部署:

有多种方法可以完成部署。最流行的可能是SSH和Webhooks。

我们将使用SSH。

编辑您的circle.yml配置以添加一个步骤,即加载我们的.scripts/deploy.sh bash文件:

deployment:
  latest:
    branch: master
    commands:
      - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
      - docker push name/repo:$CIRCLE_SHA1
      - docker push name/repo:latest
      - .scripts/deploy.sh

deploy.sh将包含一些指令,通过SSH连接到我们的远程服务器,并更新存储库和Docker映像,并重新加载Docker Compose服务。

在执行之前,您应该有一个包含您的项目文件夹(即git clone https://github.com/zurfyx/my-project )的远程服务器,并安装DockerDocker Compose

deploy.sh

#!/bin/bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

(
  cd "$DIR/.." # Go to project dir.

  ssh $SSH_USERNAME@$SSH_HOSTNAME -o StrictHostKeyChecking=no <<-EOF
    cd $SSH_PROJECT_FOLDER
    git pull
    docker-compose pull
    docker-compose stop
    docker-compose rm -f
    docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
EOF
)

注意:最后一个 EOF 没有缩进。这就是 bash 中 HEREDOC 的工作方式。

deploy.sh 步骤解释:

  1. ssh $SSH_USERNAME@$SSH_HOSTNAME:通过 SSH 连接到远程主机。-o StrictHostChecking=no 避免 SSH 询问我们是否信任该服务器。
  2. cd $SSH_PROJECT_FOLDER:浏览到项目文件夹(您通过git clone ...获取的文件夹)。
  3. git pull:更新项目文件夹。这对于保持 docker-compose / Dockerfile 的最新状态以及任何依赖于某些源代码文件的共享卷非常重要。
  4. docker-compose stop:刚刚下载了我们的远程依赖项。停止当前正在运行的 docker-compose 服务。
  5. docker-compose rm -f:删除 docker-compose 服务。这一步非常重要,否则 我们将重用旧的卷
  6. docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d。在后台模式下执行扩展了 docker-compose.ymldocker-compose.prod.yml

在 CI 中,您需要填写以下环境变量(部署脚本使用):

以下是您需要翻译的内容:
  • $SSH_USERNAME: 您的SSH用户名(例如root)
  • $SSH_HOSTNAME: 您的SSH主机名(例如stackoverflow.com)
  • $SSH_PROJECT_FOLDER: 存储项目的文件夹(相对于$SSH_USERNAME登陆位置的绝对或相对路径。例如my-project/)

那么SSH密码呢?在这种情况下,CircleCI提供了一种存储SSH密钥的方法,因此登录时不再需要密码。

否则,只需编辑deploy.sh SSH连接,如下所示:

sshpass -p your_password ssh user@hostname

关于SSH密码的更多信息在这里

总之,我们所要做的就是创建一个脚本来连接我们的远程服务器,让它知道源代码已经更新。当然,还需要执行适当的升级步骤。

顺便提一下,这类似于备选Webhooks方法的工作方式。


我想你应该在 git pull 之前先停止并删除 rm 吧?否则,如果 docker-compose.yml 在未来被修改,这个设置如何能够停止旧的部署呢?服务可能会在较新版本的 compose 文件中被重命名或删除,网络名称可能会更改等。 - zypA13510
3
使用 docker-compose rm -f 命令删除卷时,Mongo 中的所有数据都会丢失吗? - kasvith

3
WatchTower可以帮助您解决这个问题。
您的CI只需要构建镜像并将其推送到注册表中。然后,WatchTower每N秒轮询注册表,并使用最新和最好的镜像自动重新启动您的服务。只需将以下代码添加到compose yaml中即可:

https://github.com/v2tec/watchtower

watchtower:
image: v2tec/watchtower
volumes:
  - /var/run/docker.sock:/var/run/docker.sock
  - /root/.docker/config.json:/config.json
command: --interval 30

1
比起在你的 CI 流程中放置一个可能会被窃取的 SSH 密钥,这要好得多,不是吗? - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接