使用travis结合docker实现前端自动化部署
2020年接近尾声,才刚开始摸索自动化部署,希望一切都来得及
刀跟火种和工业革命的碰撞
农耕时代我们怎么部署项目?
- 本地打包编译
yarn build
- 上传到服务器
scp xxx
自动化部署之后呢?
git push
看起来好像变化不大,但甲方爸爸总是多变的,一会儿要改个图表,一会儿要修改一个文字
农耕时代,需要不停的在本地打包,上传,打包,上传...
而现在:push,push,push...
不仅去掉了本地打包这一重复劳动,更减少了我们手动上传出错的可能。
push后发生了什么
那么我们push
后发生了什么呢?通过什么解放了双手呢?
-
Travis-CI
监测到Github
代码更新后,自动pull
代码 - 根据配置文件,安装所需环境,并编译
- 打包生成
Docker
镜像 - 自动登录到服务器,拉取并运行
Docker
镜像
两个概念
Travis-CI
Travis-CI
提供了持续集成服务。
持续集成: 帮助开发人员更加频繁地(有时甚至每天)将代码更改合并到共享分支或“主干”中。
也就是说,只要代码有变更,就会自动运行构建并测试,如果新旧代码之间存在冲突,CI可以更加轻松地快速修复这些错误。
注意
Travis-CI有两个网址:travis-ci.com和travis-ci.org,前者是商业版,后者是开源版。后者可以迁移到商业版中。如果使用商业版,在执行客户端命令的时候,需要加上--pro
。两个库是不通的,需要看清楚自己使用的是什么版本。
Docker
Docker是一个开源的应用容器引擎,可以让开发者打包他们的应用到一个轻量级、可移植的容器中,并发布到任意Linux服务器。
Docker
也有两个重要的概念:容器和镜像
- 容器(Container)
容器是在linux
上本机运行,并与其他容器共享主机的内核,它运行的一个独立的进程,不占用其他任何可执行文件的内存,非常轻量。
容器特别像一个虚拟机,容器中运行着一个完整的操作系统。可以再容器中装你想装的镜像,可以做一切你当前操作系统能做的事情。
- 镜像(Image)
镜像是一个文件,它是用来创建容器的。
通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量、和配置文件。
Docker
本质就是宿主机的一个进程,Docker
通过namespace
实现资源隔离,通过cgroup
实现资源限制,通过写时复制技术(copy-on-write
)实现了高效的文件操作。
开始使用
准备条件
提前在服务器中安装好:Docker、Docker-Compose、Nginx、Travis
- 如何安装
Nginx
,请参考官方 - 如何安装
Travis
,请参考在Debian9上安装Travis的正确芝士 - 如何安装
Docker
,请参考官方 - 如何安装
Docker-Compose
,请参考官方
操作步骤
访问Travis.com官网,并用
Github
账户注册登录Travis
,授权Travis
可以访问你的仓库;-
添加你需要监测的项目,并在
Setting
中添加以下环境变量,防止别人看到自己的密码:DOCKER_USERNAME
、DOCKER_PASSWORD
;
在项目的根目录中添加
.travis.yml
文件:
language: node_js
node_js:
- '12.16.1'
services:
- docker
# Travis-CI Caching
cache:
yarn: true
directories:
- node_modules # 缓存node_modules文档夹
addons:
ssh_known_hosts:
- $server_ip
branches:
only:
- master
install:
- yarn install
script:
- yarn build
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
- docker build -t lostimever/vue3-ts:latest .
- docker push lostimever/vue3-ts:latest
- 访问hub.docker.com并注册账户,创建仓库;
- 将配置文件中的
lostimever/vue3-ts
,替换成你的账户名/仓库名
;
- 在项目根目录中新建
Dockerfile
文件,这是为了告诉Travis
如何打包Docker
镜像,内容如下:
FROM nginx
COPY ./dist/ /usr/share/nginx/html/
RUN rm /etc/nginx/conf.d/*
COPY ./nginx.conf /etc/nginx/conf.d/vue3-ts.conf
EXPOSE 80
ENTRYPOINT ["nginx","-g","daemon off;"]
- 由于
Vue
是SPA
单页应用,需要配置Nginx
,以保证请求能找到index.html
文件。在项目根目录中新建nginx.conf
,内容如下:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
proxy_set_header Host $host;
if (!-f $request_filename) {
rewrite ^.*$ /index.html break;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
-
git push
后,可以在Travis
上看到编译结果。如果编译没有问题,访问hub.docker.com便可以看到lostimever/vue3-ts:latest
这个镜像了; -
ssh
到服务器上,在项目的目录中新建docker-compose.yml
,内容如下:
version: '3.8'
services:
info:
container_name: vue3-ts
image: lostimever/vue3-ts:latest
privileged: true
ports:
- '8082:80'
restart: on-failure
- 在目录中依次执行以下命令,查看镜像是否可以工作:
$ docker-compose pull info # 拉取镜像
$ docker-compose stop info
$ docker-compose rm info
$ docker-compose up -d info # -d 代表后台运行
- 运行完后,可以访问
IP:8082
,查看网页是否可以正常访问。
ssh免密登录
但是上述步骤还是需要我们登录到服务器,再执行相应的命令,才能让项目跑起来。
有没有什么办法,把这一切工作也交给Travis
来操作呢?
新建用户指定权限
- 创建用户
登录服务器创建新的用户:travis
,并指定权限。
# 新建用户
$ useradd travis
#修改密码(应该不是必要,但是万一以后需要用密码登陆呢),按照提示设置密码。
$ passwd travis
# 为用户添加添加权限
$ vim /etc/sudoers
- 添加权限
# 为用户添加添加权限
$ vim /etc/sudoers
在最后一行添加:
travis ALL=(ALL:ALL) ALL
- 检查权限
# 切换到新创建的用户:
$ su - travis
# 使用 sudo 命令运行 whoami 命令:
$ sudo whoami
#用户是否具有 sudo 访问权限,那么 whoami 命令的输出将为 root:
root
4.修改配置
$ sudo vi /etc/ssh/sshd_config
# 添加如下配置:
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
# 重启ssh服务
$ systemctl restart sshd
生成密钥对
- 生成密钥对
root@localhost:~$ su travis && cd ~
travis@localhost:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/travis/.ssh/id_rsa):
Created directory '/home/travis/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/travis/.ssh/id_rsa.
Your public key has been saved in /home/travis/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Sp5***********************NLb0us travis@localhost.domain
The key's randomart image is:
+---[RSA 2048]----+
| oo+o. |
| o oo.. |
| . o .o |
| = . . |
| . S. . + . |
| o + . * = o|
| * . B.*o|
| o =+Bo+|
| +X%Eo|
+----[SHA256]-----+
travis@localhost:~$ cd .ssh/
travis@localhost:~/.ssh$ ls
id_rsa id_rsa.pub
- 将生成的公钥添加为受信列表
travis@localhost:~/.ssh$ cat id_rsa.pub >> authorized_keys
- 测试连接
travis@localhost:~/.ssh$ ssh travis@localhost
The authenticity of host 'localhost (localhost)' can't be established.
ECDSA key fingerprint is SHA256:Ax4uI*********************Mchx4ZMw.
Are you sure you want to continue connecting (yes/no)? yes
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]' (ECDSA) to the list of known hosts.
Linux localhost.localdomain 4.19.0-13-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Dec 14 00:38:11 2020 from 127.0.0.1
travis@localhost:~$
使用Travis客户端工具加密秘钥
- 登录GitHub,进入
Settings/Developer settings
,创建token
- 复制创建好的
token
- 登录服务器登录
travis
客户端
# 因为我的项目在travis.com中,所以需要加--pro后缀
$ travis login --github-token 260************************34f --pro
- 在项目目录下新建空文件
.travis.yml
(如果没有该文件,会报错) - 加密秘钥
# -r lostimever/vue3-ts 防止找不到仓库地址
$ travis encrypt-file -r lostimever/vue3-ts ~/.ssh/id_rsa --add --pro
encrypting /home/travis/.ssh/id_rsa for lostimever/vue3-ts
storing result as id_rsa.enc
storing secure env variables for decryption
Overwrite the config file /project/dockerfiles/vue3-ts/.travis.yml with the content below?
This reformats the existing file.
---
before_install:
- openssl aes-256-cbc -K $encrypted_f978a38ee913_key -iv $encrypted_f978a38ee913_iv
-in id_rsa.enc -out ~\/.ssh/id_rsa -d
(y/N)
y
Make sure to add id_rsa.enc to the git repository.
Make sure not to add /home/travis/.ssh/id_rsa to the git repository.
Commit all changes to your .travis.yml.
可以看到该命令创建了新的文件id_rsa.enc
,并在.travis.yml
文件中写入了新的命令:
before_install:
- openssl aes-256-cbc -K $encrypted_f978a38ee913_key -iv $encrypted_f978a38ee913_iv
-in id_rsa.enc -out ~/.ssh/id_rsa -d
将这段命令添加到本地的.travis.yml
中
注意 去掉转译符\
同时在travis
的setting
中新增了两个环境变量:encrypted_04674a2f3de9_iv
、encrypted_04674a2f3de9_key
导出
id_rsa.enc
到本地项目的根目录中添加
docker
权限给当前用户,使docker
命令免sudo
# 如果还没有 docker group 就添加一个:
$ sudo groupadd docker
# 将用户加入该 group 内。然后退出并重新登录就生效啦。
$ sudo gpasswd -a ${USER} docker
# 重启 docker 服务
$ sudo systemctl restart docker
# 切换当前会话到新 group 或者重启 X 会话
$ newgrp docker
- 本地
.travis.yml
详细配置如下
language: node_js
node_js:
- '12.16.1'
services:
- docker
# Travis-CI Caching
cache:
yarn: true
directories:
- node_modules # 缓存node_modules文档夹
addons:
ssh_known_hosts:
- $server_ip
branches:
only:
- master
before_install:
- openssl aes-256-cbc -K $encrypted_04674a2f3de9_key -iv $encrypted_04674a2f3de9_iv -in id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa
install:
- yarn install
script:
- yarn build
- echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
- docker build -t lostimever/vue3-ts:latest .
- docker push lostimever/vue3-ts:latest
after_success:
- ssh -o "StrictHostKeyChecking no" -p $server_port travis@$server_ip "cd /project/dockerfiles/vue3-ts;docker-compose pull info;docker-compose stop info;docker-compose rm info;docker-compose up -d info;exit"