Gitlab-runner + Docker-compose部署方案:如何在主机服务器重启后正确地重新启动容器

4
假设我在Gitlab上有一个代码库,以下是部署方案:
  1. 在主机服务器上安装docker和gitlab-runner,并使用docker executor。
  2. .gitlab-ci.yml中设置docker-compose来构建和启动我的服务及其依赖项。
  3. 设置管道以通过将提交推送到production分支来触发。
假设docker-compose.yml有两个服务:app(具有restart:always)和db(没有重启规则)。app依赖于db,因此docker-compose up会先启动db,然后再启动app
它在主机服务器重新启动之前工作得很好。但主机服务器重新启动后,只有app容器会重新启动。
我找到的解决方法及其缺点如下:
  1. restart: always添加到db服务中。但是app可能会在db之前启动,从而导致失败。
  2. 在主机上使用docker-compose并设置docker-compose up自动运行。但在这种情况下,我应该设置docker-compose,在主机服务器上部署ssh密钥,在某个位置克隆代码并更新它。这似乎违反了DRY原则,并使方案过于复杂化。
  3. 在重新启动后触发流水线。我发现的唯一方法是通过API和触发器令牌来触发它。但在这种情况下,我必须设置触发器令牌,这似乎不像以前那样糟糕,但违反了DRY原则,并使方案过于复杂化。

如何改进部署方案以使docker在重启后以正确的顺序重新启动容器。

P.S. 配置如下:

.gitlab-ci.yml

image:
  name: docker/compose:latest

services:
  - docker:dind
stages:
  - deploy

deploy:
  stage: deploy
  only:
    - production
  script:
    - docker image prune -f
    - docker-compose build --no-cache
    - docker-compose up -d

docker-compose.yml:

version: "3.8"
services:
  app:
    build: .
    container_name: app
    depends_on:
      - db
    ports:
      - "80:80"
    restart: always
  db:
    image: postgres
    container_name: db
    ports:
      - "5432:5432"

1
你需要一个编排器。有很多方法可以做到这一点...最接近你所拥有的是使用Docker Swarm。更或者,你将使用docker stack deploy而不是docker-compose up。使用Docker Swarm,系统将自动工作以维护最初声明的状态,无需干预或特殊主机设置。理想情况下,你应该在群集中拥有多个主机,但从技术上讲并非必需。你也可以切换到k8s部署运行程序,但基本上你将从头开始。 - sytech
2个回答

1
当你在 db 服务中添加 restart: always 后,你的应用程序可能会在数据库之前启动并失败。但是由于 "restart:always" 策略,你的应用程序必须在失败后重新启动,如果它没有正常工作,那么你可能有错误的退出代码。
因此,你可以添加健康检查(healthcheck),并在延迟后重新启动应用程序,你认为应用程序必须能够正常工作。
简单检查80端口可以帮助你实现健康检查。

0

这基本上是因为您的应用程序由于无法使用数据库而快速失败。

在某些情况下,这可能很有用,但对于您的用例,您可以以一种重新尝试建立连接的方式实现应用程序。最好实现回退策略,以防出现真正问题时过载数据库。

失去与数据库的连接是可能发生的,但如果数据库不可用,杀死应用程序是否有意义?您能否实施任何后备计划,例如“抱歉,我们有问题,但我们正在努力解决”?从用户的角度来看,让他们知道您有问题并且正在努力解决它比仅仅不打开您的应用程序体验更好。


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