使用travis結(jié)合docker實(shí)現(xiàn)前端自動(dòng)化部署
2020年接近尾聲,才剛開始摸索自動(dòng)化部署脆霎,希望一切都來得及
刀跟火種和工業(yè)革命的碰撞
農(nóng)耕時(shí)代我們?cè)趺床渴痦?xiàng)目总处?
- 本地打包編譯
yarn build
- 上傳到服務(wù)器
scp xxx
自動(dòng)化部署之后呢?
git push
看起來好像變化不大睛蛛,但甲方爸爸總是多變的鹦马,一會(huì)兒要改個(gè)圖表,一會(huì)兒要修改一個(gè)文字
農(nóng)耕時(shí)代忆肾,需要不停的在本地打包荸频,上傳,打包客冈,上傳...
而現(xiàn)在:push旭从,push,push...
不僅去掉了本地打包這一重復(fù)勞動(dòng)场仲,更減少了我們手動(dòng)上傳出錯(cuò)的可能和悦。
push后發(fā)生了什么
那么我們push
后發(fā)生了什么呢?通過什么解放了雙手呢渠缕?
-
Travis-CI
監(jiān)測(cè)到Github
代碼更新后鸽素,自動(dòng)pull
代碼 - 根據(jù)配置文件,安裝所需環(huán)境亦鳞,并編譯
- 打包生成
Docker
鏡像 - 自動(dòng)登錄到服務(wù)器付鹿,拉取并運(yùn)行
Docker
鏡像
兩個(gè)概念
Travis-CI
Travis-CI
提供了持續(xù)集成服務(wù)。
持續(xù)集成: 幫助開發(fā)人員更加頻繁地(有時(shí)甚至每天)將代碼更改合并到共享分支或“主干”中蚜迅。
也就是說舵匾,只要代碼有變更,就會(huì)自動(dòng)運(yùn)行構(gòu)建并測(cè)試谁不,如果新舊代碼之間存在沖突坐梯,CI可以更加輕松地快速修復(fù)這些錯(cuò)誤。
注意
Travis-CI有兩個(gè)網(wǎng)址:travis-ci.com和travis-ci.org刹帕,前者是商業(yè)版吵血,后者是開源版。后者可以遷移到商業(yè)版中偷溺。如果使用商業(yè)版蹋辅,在執(zhí)行客戶端命令的時(shí)候,需要加上--pro
挫掏。兩個(gè)庫(kù)是不通的侦另,需要看清楚自己使用的是什么版本。
Docker
Docker是一個(gè)開源的應(yīng)用容器引擎,可以讓開發(fā)者打包他們的應(yīng)用到一個(gè)輕量級(jí)褒傅、可移植的容器中弃锐,并發(fā)布到任意Linux服務(wù)器。
Docker
也有兩個(gè)重要的概念:容器和鏡像
- 容器(Container)
容器是在linux
上本機(jī)運(yùn)行殿托,并與其他容器共享主機(jī)的內(nèi)核霹菊,它運(yùn)行的一個(gè)獨(dú)立的進(jìn)程,不占用其他任何可執(zhí)行文件的內(nèi)存支竹,非常輕量旋廷。
容器特別像一個(gè)虛擬機(jī),容器中運(yùn)行著一個(gè)完整的操作系統(tǒng)礼搁×螅可以再容器中裝你想裝的鏡像,可以做一切你當(dāng)前操作系統(tǒng)能做的事情叹坦。
- 鏡像(Image)
鏡像是一個(gè)文件熊镣,它是用來創(chuàng)建容器的。
通過鏡像啟動(dòng)一個(gè)容器募书,一個(gè)鏡像是一個(gè)可執(zhí)行的包绪囱,其中包括運(yùn)行應(yīng)用程序所需要的所有內(nèi)容包含代碼,運(yùn)行時(shí)間莹捡,庫(kù)鬼吵、環(huán)境變量、和配置文件篮赢。
Docker
本質(zhì)就是宿主機(jī)的一個(gè)進(jìn)程齿椅,Docker
通過namespace
實(shí)現(xiàn)資源隔離,通過cgroup
實(shí)現(xiàn)資源限制启泣,通過寫時(shí)復(fù)制技術(shù)(copy-on-write
)實(shí)現(xiàn)了高效的文件操作涣脚。
開始使用
準(zhǔn)備條件
提前在服務(wù)器中安裝好:Docker、Docker-Compose寥茫、Nginx遣蚀、Travis
- 如何安裝
Nginx
,請(qǐng)參考官方 - 如何安裝
Travis
纱耻,請(qǐng)參考在Debian9上安裝Travis的正確芝士 - 如何安裝
Docker
芭梯,請(qǐng)參考官方 - 如何安裝
Docker-Compose
,請(qǐng)參考官方
操作步驟
訪問Travis.com官網(wǎng)弄喘,并用
Github
賬戶注冊(cè)登錄Travis
玖喘,授權(quán)Travis
可以訪問你的倉(cāng)庫(kù);-
添加你需要監(jiān)測(cè)的項(xiàng)目蘑志,并在
Setting
中添加以下環(huán)境變量累奈,防止別人看到自己的密碼:DOCKER_USERNAME
贬派、DOCKER_PASSWORD
;
在項(xiàng)目的根目錄中添加
.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并注冊(cè)賬戶费尽,創(chuàng)建倉(cāng)庫(kù);
- 將配置文件中的
lostimever/vue3-ts
羊始,替換成你的賬戶名/倉(cāng)庫(kù)名
旱幼;
- 在項(xiàng)目根目錄中新建
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è)應(yīng)用柏卤,需要配置Nginx
,以保證請(qǐng)求能找到index.html
文件匀油。在項(xiàng)目根目錄中新建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
這個(gè)鏡像了桥滨; -
ssh
到服務(wù)器上,在項(xiàng)目的目錄中新建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 代表后臺(tái)運(yùn)行
- 運(yùn)行完后,可以訪問
IP:8082
纷跛,查看網(wǎng)頁(yè)是否可以正常訪問喻括。
ssh免密登錄
但是上述步驟還是需要我們登錄到服務(wù)器,再執(zhí)行相應(yīng)的命令贫奠,才能讓項(xià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 命令運(yùn)行 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
生成密鑰對(duì)
- 生成密鑰對(duì)
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
- 測(cè)試連接
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勒叠,進(jìn)入
Settings/Developer settings
兜挨,創(chuàng)建token
- 復(fù)制創(chuàng)建好的
token
- 登錄服務(wù)器登錄
travis
客戶端
# 因?yàn)槲业捻?xiàng)目在travis.com中,所以需要加--pro后綴
$ travis login --github-token 260************************34f --pro
- 在項(xiàng)目目錄下新建空文件
.travis.yml
(如果沒有該文件眯分,會(huì)報(bào)錯(cuò)) - 加密秘鑰
# -r lostimever/vue3-ts 防止找不到倉(cāng)庫(kù)地址
$ 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)譯符\
同時(shí)在travis
的setting
中新增了兩個(gè)環(huán)境變量:encrypted_04674a2f3de9_iv
、encrypted_04674a2f3de9_key
導(dǎo)出
id_rsa.enc
到本地項(xiàng)目的根目錄中添加
docker
權(quán)限給當(dāng)前用戶弊决,使docker
命令免sudo
# 如果還沒有 docker group 就添加一個(gè):
$ sudo groupadd docker
# 將用戶加入該 group 內(nèi)噪舀。然后退出并重新登錄就生效啦魁淳。
$ sudo gpasswd -a ${USER} docker
# 重啟 docker 服務(wù)
$ sudo systemctl restart docker
# 切換當(dāng)前會(huì)話到新 group 或者重啟 X 會(huì)話
$ newgrp docker
- 本地
.travis.yml
詳細(xì)配置如下
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"