使用travis結(jié)合docker實現(xiàn)前端自動化部署
2020年接近尾聲,才剛開始摸索自動化部署,希望一切都來得及
刀跟火種和工業(yè)革命的碰撞
農(nóng)耕時代我們怎么部署項目?
- 本地打包編譯
yarn build - 上傳到服務(wù)器
scp xxx
自動化部署之后呢?
git push
看起來好像變化不大,但甲方爸爸總是多變的,一會兒要改個圖表,一會兒要修改一個文字
農(nóng)耕時代,需要不停的在本地打包,上傳,打包,上傳...
而現(xiàn)在:push,push,push...
不僅去掉了本地打包這一重復(fù)勞動,更減少了我們手動上傳出錯的可能。
push后發(fā)生了什么
那么我們push后發(fā)生了什么呢?通過什么解放了雙手呢?
-
Travis-CI監(jiān)測到Github代碼更新后,自動pull代碼 - 根據(jù)配置文件,安裝所需環(huán)境,并編譯
- 打包生成
Docker鏡像 - 自動登錄到服務(wù)器,拉取并運行
Docker鏡像
兩個概念
Travis-CI
Travis-CI提供了持續(xù)集成服務(wù)。
持續(xù)集成: 幫助開發(fā)人員更加頻繁地(有時甚至每天)將代碼更改合并到共享分支或“主干”中。
也就是說,只要代碼有變更,就會自動運行構(gòu)建并測試,如果新舊代碼之間存在沖突,CI可以更加輕松地快速修復(fù)這些錯誤。
注意
Travis-CI有兩個網(wǎng)址:travis-ci.com和travis-ci.org,前者是商業(yè)版,后者是開源版。后者可以遷移到商業(yè)版中。如果使用商業(yè)版,在執(zhí)行客戶端命令的時候,需要加上--pro。兩個庫是不通的,需要看清楚自己使用的是什么版本。
Docker
Docker是一個開源的應(yīng)用容器引擎,可以讓開發(fā)者打包他們的應(yīng)用到一個輕量級、可移植的容器中,并發(fā)布到任意Linux服務(wù)器。
Docker也有兩個重要的概念:容器和鏡像
- 容器(Container)
容器是在linux上本機運行,并與其他容器共享主機的內(nèi)核,它運行的一個獨立的進程,不占用其他任何可執(zhí)行文件的內(nèi)存,非常輕量。
容器特別像一個虛擬機,容器中運行著一個完整的操作系統(tǒng)??梢栽偃萜髦醒b你想裝的鏡像,可以做一切你當(dāng)前操作系統(tǒng)能做的事情。
- 鏡像(Image)
鏡像是一個文件,它是用來創(chuàng)建容器的。
通過鏡像啟動一個容器,一個鏡像是一個可執(zhí)行的包,其中包括運行應(yīng)用程序所需要的所有內(nèi)容包含代碼,運行時間,庫、環(huán)境變量、和配置文件。
Docker本質(zhì)就是宿主機的一個進程,Docker通過namespace實現(xiàn)資源隔離,通過cgroup實現(xiàn)資源限制,通過寫時復(fù)制技術(shù)(copy-on-write)實現(xiàn)了高效的文件操作。
開始使用
準備條件
提前在服務(wù)器中安裝好:Docker、Docker-Compose、Nginx、Travis
- 如何安裝
Nginx,請參考官方 - 如何安裝
Travis,請參考在Debian9上安裝Travis的正確芝士 - 如何安裝
Docker,請參考官方 - 如何安裝
Docker-Compose,請參考官方
操作步驟
訪問Travis.com官網(wǎng),并用
Github賬戶注冊登錄Travis,授權(quán)Travis可以訪問你的倉庫;-
添加你需要監(jiān)測的項目,并在
Setting中添加以下環(huán)境變量,防止別人看到自己的密碼:DOCKER_USERNAME、DOCKER_PASSWORD;
travis_setting.png 在項目的根目錄中添加
.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并注冊賬戶,創(chuàng)建倉庫;
docker_create_rep.png
- 將配置文件中的
lostimever/vue3-ts,替換成你的賬戶名/倉庫名;
docker_rep_name.png
- 在項目根目錄中新建
Dockerfile文件,這是為了告訴Travis如何打包Docker鏡像,內(nèi)容如下:
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單頁應(yīng)用,需要配置Nginx,以保證請求能找到index.html文件。在項目根目錄中新建nginx.conf,內(nèi)容如下:
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上看到編譯結(jié)果。如果編譯沒有問題,訪問hub.docker.com便可以看到lostimever/vue3-ts:latest這個鏡像了; -
ssh到服務(wù)器上,在項目的目錄中新建docker-compose.yml,內(nèi)容如下:
version: '3.8'
services:
info:
container_name: vue3-ts
image: lostimever/vue3-ts:latest
privileged: true
ports:
- '8082:80'
restart: on-failure
- 在目錄中依次執(zhí)行以下命令,查看鏡像是否可以工作:
$ docker-compose pull info # 拉取鏡像
$ docker-compose stop info
$ docker-compose rm info
$ docker-compose up -d info # -d 代表后臺運行
- 運行完后,可以訪問
IP:8082,查看網(wǎng)頁是否可以正常訪問。
ssh免密登錄
但是上述步驟還是需要我們登錄到服務(wù)器,再執(zhí)行相應(yīng)的命令,才能讓項目跑起來。
有沒有什么辦法,把這一切工作也交給Travis來操作呢?
新建用戶指定權(quán)限
- 創(chuàng)建用戶
登錄服務(wù)器創(chuàng)建新的用戶:travis,并指定權(quán)限。
# 新建用戶
$ useradd travis
#修改密碼(應(yīng)該不是必要,但是萬一以后需要用密碼登陸呢),按照提示設(shè)置密碼。
$ passwd travis
# 為用戶添加添加權(quán)限
$ vim /etc/sudoers
- 添加權(quán)限
# 為用戶添加添加權(quán)限
$ vim /etc/sudoers
在最后一行添加:
travis ALL=(ALL:ALL) ALL
- 檢查權(quán)限
# 切換到新創(chuàng)建的用戶:
$ su - travis
# 使用 sudo 命令運行 whoami 命令:
$ sudo whoami
#用戶是否具有 sudo 訪問權(quán)限,那么 whoami 命令的輸出將為 root:
root
4.修改配置
$ sudo vi /etc/ssh/sshd_config
# 添加如下配置:
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
# 重啟ssh服務(wù)
$ 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,創(chuàng)建token
github_setting.png
- 復(fù)制創(chuàng)建好的
token
github_token.png
- 登錄服務(wù)器登錄
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.
可以看到該命令創(chuàng)建了新的文件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中
注意 去掉轉(zhuǎn)譯符\
同時在travis的setting中新增了兩個環(huán)境變量:encrypted_04674a2f3de9_iv、encrypted_04674a2f3de9_key

導(dǎo)出
id_rsa.enc到本地項目的根目錄中添加
docker權(quán)限給當(dāng)前用戶,使docker命令免sudo
# 如果還沒有 docker group 就添加一個:
$ sudo groupadd docker
# 將用戶加入該 group 內(nèi)。然后退出并重新登錄就生效啦。
$ sudo gpasswd -a ${USER} docker
# 重啟 docker 服務(wù)
$ sudo systemctl restart docker
# 切換當(dāng)前會話到新 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"




