最近开了个新的项目,由于涉及到多人的协作,为了便于前端的开发,我把服务器部署到腾讯云的服务器上,并且利用 Travis CI 实现了从提交代码、运行测试、构建Docker镜像到部署服务的自动化流程。
依赖服务
首先,我们先要解决服务端所依赖的服务。本项目的服务端主要依赖于以下的服务:
- MongoDB
- Redis
这些服务通过docker很容易就可以实现部署,这里就不再详细说明了。
自动测试
下一步就是需要利用 Travis CI 实现自动测试了。
对于 Golang 来说,单元测试的实现是非常简单的,因此语言本身就提供了关于测试的库。只需要编写xxx_test.go
文件,然后使用go test
命令就可以进行测试。
现在主要遇到的问题就是本项目的单元测试主要测试的是对数据库的操作,因此需要先连接数据库,而在 Golang中我们很难指定测试文件的运行顺序,因此对于每个模块的测试,都需要先连接数据库,再执行测试代码,最后清理数据库。因此,我们不能按照 Golang 中传统的测试方式来写测试代码,而是需要自定义一套测试的顺序。
利用testing.T
中的Run
接口,实现自定义的测试序列
1 | func TestCache(t *testing.T) { |
然后编写travis.yml
,实现构建和测试,并且将测试结果上传到codecov
进行分析
1 | language: go |
构建Docker
在实现自动部署之前,我们需要在本地实现服务端的Docker打包并部署。
首先编写dockerfile
构建镜像。
基于 Golang 1.12, 我们可以使用 go mod
模块来安装依赖库,利用Docker
我们可以加速这个过程。
具体的实现原理是使用一个中间层缓存镜像存储Golang 的编译以及依赖环境,然后每次编译如果go.mod
没有发生变化,那就直接重用这个环境进行编译,而不需要再重新下载依赖进行编译。
通过切换WORKDIR
就可以实现,具体操作如下
1 | FROM golang:1.12 as build |
打包的时候需要将配置文件config.yaml
一同COPY
进去
然后使用docker-compose
进行部署
1 | version: '3' |
自动部署
本地完成部署之后,就可以实现自动部署了。
自动部署的原理是再Travis CI
测试通过之后,通过ssh
登陆到服务器,执行部署脚本。
在这个过程中,我们需要保护我们服务器的安全,并且不能影响到服务器中其他的服务,因此我新建了一个用户deploy
专门用于部署,然后生成该用户的登陆密钥。
1 | ssh-keygen -t rsa -C "deploy_key" -f ~/.ssh/id_ras_deploy |
然后我们需要利用Travis
提供的工具对这个密钥进行加密
1 | gem install travis |
然后脚本会自动在我们的travis.yaml
中添加对密钥的解密指令。其原理是使用存储在环境变量中的密钥对文件进行解密,我们只需要把加密后的文件deploy.enc
放在仓库中就可以了。
1 | before_install: |
然后我们再编写一个部署的脚本,自动从GitHub上获取最新的源码,然后进行部署。
1 | git checkout . |
要实现远程ssh登陆,我们还需要做一点工作,在仓库中加入ssh_config
配置文件,表明远程地址用户名以及密钥位置。
1 | Host love.zhenly.cn |
最后修改一下travis.yaml
,在after_success
中加入远程登陆部署的命令
1 | language: go |
最后当我们把船新的代码push到GitHub上的时候,Travis CI
就会开始工作
当测试通过的时候,就会自动连接服务器,执行上面的部署脚本,拉取最新的代码并且进行打包部署。
小结
在这次项目中,首次使用自动部署的方式进行开发,每次提交代码后就可以直接测试并部署到服务器上,而前端也不需要在本地打开服务端进行测试,直接连接远程的测试服务器进行开发,极大地提高了开发的效率,感觉非常方便,果然技术发展的动力还是因为太懒了。因为懒得开本地服务端,懒得部署服务器,才搞出来这一套东西🐷。
🚀 项目: Github