Deployer 持续交付

SECoder平台提供托管Web应用的服务,这意味着恰当设置的项目可以被持续集成并部署到SECoder平台上。 假如你的项目最终表现形式为一个网站 / Web App / C/S应用,则你可能会需要使用部署到SECoder上的功能。 假如你的项目的最终表现形式仅是一个构建产物,则你只需要用到CI流程。

Deployer拓扑

快速上手

部署应用

假如SECoder提供的样例中包含你期望使用的技术,那么快速上手将会变得非常简便。 通常而言,只需要将样例仓库克隆到本地,然后上传到一个勾选了“启用部署”的项目仓库中,样例仓库会自动部署到SECoder平台上运行。

管理界面

假如你在创建仓库时勾选了“启用部署”,那么一个应用容器会相应被创建;你也可以创建不与仓库挂钩的应用容器作为数据库服务等。 点选容器可以进入容器管理界面。

  • 概况:查看容器的信息,更换容器的镜像等。
  • 挂载:修改挂载在容器上的配置项。修改挂载会导致容器的重启。
  • 端口:修改容器对外暴露的端口。所有的容器都被设置为暴露80端口。 倘若容器被设置成是一个外部服务,平台会把对默认域名(<Dyno>_<Environment>.app.secoder.net)的请求转发到容器的80端口。 除此之外,暴露的端口可以通过内网地址(<Dyno>.<Environment>.secoder.local)访问到。
  • 域名:可以将其它域名绑定到容器上,详见特殊说明。
  • 管理:可以查看容器的日志,以及在正在运行的容器当中执行命令(/bin/bash)。

基本概念

SECoder提供一个小型的应用托管服务,给每个项目提供三类资源:应用容器、配置项和存储卷。

应用容器

应用容器是服务运行的基本单位。这里所说的容器(与Heroku的Dyno相近)与Docker的一个或一组同类容器对应。

一个应用容器里包含了除了Linux内核外你的应用运行所需要的所有文件:从文件系统到依赖库,再到应用程序本身。 一般情况下,可以大致认为容器与一个轻量虚拟机相当。

容器本身具有易失性:容器的文件系统是一个临时文件系统,容器的重启会导致临时文件系统存储的所有数据的丢失,故不应该在容器内存储持久性数据。 相应地,容器应当通过连接配置项来进行设置,并且将需要持久保存的数据存储于存储卷中。

同时,容器本身应该尽可能地轻量,一个容器应当大致上与一个进程对应,故将数据库等大型服务和应用一同塞进一个容器的做法是不被推荐的。一种被推荐的做法如下:

  • 应用的代码(以及配置文件的样例)托管于GitLab,并且通过CI/CD流程持续部署到应用容器上。
  • 应用的数据存放于存储卷中,由一个单独的数据库服务(如Redis,Postgres,MongoDB等)来管理。
  • 上述数据库服务的配置信息(如数据库本身的配置文件)存放于配置项中。
  • 数据库服务在挂载了数据库的配置项的容器里运行。
  • 应用需要的配置信息(如与数据库的连接信息)存放于配置项中。
  • 应用运行在挂载了应用的配置项的容器中,并接受持续部署。

Warning

应用容器的伸缩与替换是Roll-Out的。对于无状态的应用,这样的策略可以实现应用的无缝重启和无缝升级。 但是Master-Slave类型的“有状态副本”则不适用这种方法。

Deployer暂不支持有状态副本,这意味着你不能使用Deployer的伸缩功能实现主从服务等功能。

配置项

配置项存放容器可能用到的只读的配置信息,例如数据库连接信息、HTTPS证书等。

配置项可以被作为一个目录被挂载到容器中。暂不支持将配置项挂载到环境变量上。

配置项只能通过命令行创建。以下给出了将某个目录的所有文件作为一个配置项上传的方法。

docker run -v $(pwd):/mnt --rm -e API_SERVER=https://deployer.secoder.net/api/ -e DEPLOY_ENV=<environment> -e DEPLOY_TOKEN=<token> ccr.ccs.tencentyun.com/thusepi/deployer deployer config create /mnt/<config directory>
docker run -v $(pwd):/mnt --rm -e API_SERVER=https://deployer.secoder.net/api/ -e DEPLOY_ENV=<environment> -e DEPLOY_TOKEN=<token> ccr.ccs.tencentyun.com/thusepi/deployer deployer config rename <old_name> <new_name>
docker run -v $(pwd):/mnt --rm -e API_SERVER=https://deployer.secoder.net/api/ -e DEPLOY_ENV=<environment> -e DEPLOY_TOKEN=<token> ccr.ccs.tencentyun.com/thusepi/deployer deployer config replace <new_name> /mnt/<new config directory>

存储卷

存储卷用于存放容器的数据文件。存储卷内的数据不会随着容器重启而丢失。

存储卷可以作为一个目录被挂载到容器中。

Warning

尽管一个存储卷可以被挂载到多个容器上,但这并不意味着这是一个好主意。

存储卷的底层实现是基于NFS的,这意味着你可能需要特别注意文件加锁等问题。

配置教程

Dockerfile

Dockerfile描述Docker镜像是怎么被构建的。你可能需要编写自己的Dockerfile使得其符合你的应用的构建要求。

为了削减容器产物中的不必要文件,我们推荐采用多阶段构建的写法。 多阶段构建的做法是构建时使用一个带有构建工具的容器,然后将构建产物复制到一个没有构建工具的容器中。 参考样例中的Webpack网站采用了这种方法构建镜像,最终产物只有一个带有网站本体和nginx的镜像,而没有Webpack等工具。

.gitlab-ci.yml

Warning

对GitLab CI配置文件的修改可能会造成不可预料的后果。

对于已经支持的语言,SECoder提供的样例仓库中的GitLab CI配置文件是被设置成无需修改可以直接使用的,且能满足大多数需求。

所以除非你清楚自己在做什么,否则不要轻易修改.gitlab-ci.yml。

.gitlab-ci.yml描述了项目是如何通过GitLab CI进行构建的。 通常而言,一个容器型的项目的CI流程包括构建——测试(持续集成)——部署(持续部署)三个步骤, 而一个生成产物的项目的CI流程包括构建——测试两个步骤。

对于一部分常用的语言,SECoder已经给出了可以正确运行的参考样例。 通常情况下,假如你使用的技术是已经受支持的,那么你应该不需要考虑.gitlab-ci.yml的编写, 而是只需要修改Dockerfile和/或build.sh使其能够满足你的项目的构建需求。

已经支持的语言和技术有:

  • Javascript(包括前端Javascript、Node.js、Typescript)
  • Python
  • Java
  • Nginx-based应用(如静态网站或者Webpack构建的SPA)

对于其它语言开发的应用,我们提供了一个比较通用的.gitlab-ci.yml方便配置。 一般而言,除了测试工作外,即使是通用的配置也应该能较好地完成各项工作。

倘若已经给出的样例中没有你需要的语言或技术,请及时反馈。

运行环境

配额限制

  • 应用容器
    • 内存限制:1G
  • 持久卷
    • 容量限制:1G

构建环境

所有的构建任务都在Docker容器内完成。

  • OS版本: Linux/amd64
  • Docker版本: 17.05.0-ce

特殊说明

C/S架构

SECoder平台不支持Raw Socket的转发,但是支持WebSocket。 假如你的应用需要与服务器进行实时或者全双工通信,可以考虑使用WebSocket替代Raw Socket。

域名绑定

出于HTTPS证书的考虑,SECoder提供的域名<Dyno>_<Environment>.app.secoder.net不是一个FQDN。倘若遇到需要FQDN的情况等场合,你可能需要将自己的域名绑定到某个容器上。

SECoder仅支持HTTPS协议的转发,这意味着你必须首先拿到一个自己域名的HTTPS证书。可以考虑Let's Encrypt

  1. 将自己的域名的CNAME记录指向<Dyno>_<Environment>.app.secoder.net
  2. 在项目管理——部署管理中设置绑定域名。
  3. 在项目管理——部署管理中设置暴露443端口,并使用自己的证书侦听443端口上的HTTPS请求。

SECoder会自动将HTTPS请求转发到你的容器。测试

静态页面

静态页面的托管可以采用一个简单的Nginx容器实现。