我不确定我的问题是否相关,因为我可能会尝试混合不应混合使用的工具(Capistrano和Docker)。

最近,我已经将与Capistrano一起部署的应用程序进行了docker化。 Docker compose用于开发和登台环境。

这是我的项目的样子(未显示应用程序文件):

Capfile
docker-compose.yml
docker-compose.staging.yml
config/
    deploy.rb
    deploy
        staging.rb

Docker Compose文件创建了所有必要的容器(Nginx,PHP,MongoDB,Elasticsearch等),以便在开发或暂存环境中运行应用程序(因此,在docker-compose.staging.yml中定义了一些特定的参数)。

使用以下命令将应用程序部署到登台环境:
cap staging deploy

服务器上的文件夹体系结构是Capistrano之一:
current
releases
    20160912150720
    20160912151003
    20160912153905
shared

已在登台服务器的current目录中运行以下命令,以实例化运行该应用程序所需的所有容器:
docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d

到现在为止还挺好。在下一次部署中,事情变得更加复杂:current符号链接(symbolic link)将指向releases目录的新目录:
  • 如果deploy.rb定义了需要在容器内执行的命令(如PHP的docker-compose exec php composer install),则Docker会告知该容器尚不存在(因为现有容器是在先前的发行文件夹中创建的)。
  • 如果在Capistrano部署过程中执行了docker-compose up -d命令,由于端口冲突(以前的容器仍然存在),我会遇到一些错误。

  • 您是否有解决此问题的想法?我应该离开Capistrano并做一些不同的事情吗?

    这个想法是保持Capistrano提供的(几乎)零停机时间部署以及Docker容器的灵活性(例如,为同一台服务器上的各种应用程序提供多个PHP版本)。

    最佳答案

    据我了解,您在主机上使用capistrano来重新部署整个应用程序堆栈,即容器。因此,您正在使用capistrano来协调构建,容器创建以及部署。

    基本上,您这样做时,在运行cap部署时

  • 构建应用程序(基于您在主机上获取的当前库)-甚至可能包含gulp/grunt/build任务
  • ,然后使用“volume mounts”将其“打包”到镜像中
    在启动/替换容器
  • 期间的


  • 您这样做是为了实现“近乎”零停机时间的部署。

    如果您真的很在乎停机时间并非常在乎您的部署过程,那么应该使用正确的管道实现
  • 包装/ci
  • 部署/分发

  • 我认为capistrano不能/不应成为您在此策略中可以使用的工具之一。 Capistrano旨在使用ssh和git作为传输直接在服务器上部署应用程序。顶住恕我直言,使用cap在目标服务器上构建整个镜像,然后将其作为容器启动。

    包装/建筑

    使用诸如jenkins/bamboo/gocd之类的CI/CD服务器为您的应用程序构建一个发行镜像。假设仅根据“发布”对应用程序进行了自定义,假设您将数据库和应用程序作为容器/服务,则应用程序将包含您的源代码,并且在发布期间会定期更改。

    因此,它是CD/CI流程,用于在CI服务器上异地构建新的应用程序镜像(发行版)。通过使用COPY然后使用任何RUN语句将应用程序的源代码打包并打包到图像中,以编译 Assets (npm/gulp/grunt等等)。所有这些都不在生产服务器上发生,而是在CI/CD代理上发生。鼓励对 slim 图像使用多阶段构建。

    然后,您将该发布镜像推送,让该镜像yourregistry.com/yourapp称为private registry作为部署的新“版本”。

    部署

    停机时间(轻松)

    要在停机时部署到生产服务器或登台服务器中,只需执行docker-composer pull && docker-composer up-这将提取较新的镜像,然后在堆栈中启动它-应用已升级。在发布阶段使用标记的图像将需要更改docker-compose.yml

    该服务器当然应该能够从您的专用存储库中提取。

    无需停机(更多精力)

    要实现零停机时间部署,您应该使用blue-green deployment concept。因此,您将代理添加到设置中,并且不再从应用程序公开公用端口,而是使用此代理公用端口。您当前的实时系统可能正在随机端口21231上运行,代理从443转发到21231。

    我们正在使用随机端口来避免在部署“第二个”系统期间发生冲突,这涵盖了您提到的问题之一。

    重新部署时,您将仅基于新的应用程序镜像(除了旧的)启动一个"new"容器,它会获得一个新的随机端口12312-如果您愿意,请直接运行集成测试12312(不要使用代理)。如果您满意并满意,请重新配置代理以将其转发到12312-然后删除旧容器(21231)。

    如果您希望自动化代理重新配置(详细信息不在此问题范围之内),则可以使用服务发现和注册器,该注册器使随机端口更加实用,并易于重新配置代理,请将其设为nginx/haproxy运行时。例如,将使用工具。
  • 领事
  • 代理上的
  • consul watch + consul-templatetiller以更新代理配置
  • Registator用于集中注册,或者consul agent client modeservice-configuration.json(取决于您的选择)
  • --

    关于docker - 如何将Capistrano与Docker集成在一起进行部署?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39457603/

    10-16 13:56
    查看更多