前言
最近在學習後端的知識,自己搞了個自己玩的全棧專案,在需要釋出上線的時候,一開始是在伺服器用的是git拉程式碼->編譯構造->重新啟動的手動擋模式,釋出次數頻繁了或者前後端需要同時釋出就覺得十分的繁瑣,所以就想著怎麼可以通過指令碼就把所有過程自動化執行,讓自己敲少幾次命令
思路簡介
阿里雲有個CodePipeline服務,類似jenkins那樣可以進行編譯構建,不過到最後一步想部署容器的話,貌似需要開通叢集之類的,但是錢要留著給女朋友花,所以就先放棄研究這一塊的實現了...,然後只能想點比較簡單暴力的方法去實現,結合自己的實際情況,一臺筆記本走天下的,所以通過shell指令碼來實現應該是比較合適的方案了
原材料:
ssh shell docker node
前端程式碼:
通過本地編譯出dist檔案用scp命令把檔案放上去伺服器對應的站點目錄
後端程式碼:
通過dockerFile編譯出image上傳到自己的倉庫再觸發伺服器的對應指令碼重新啟動對應的container
伺服器:
用的是Ubuntu 16.04,建立一個資料夾存著一系列對應專案的指令碼,讓本地通過ssh觸發執行指令碼
實現
使用docker是為了方便環境的構建,因為自己只有一個伺服器,使用docker就可以很從容的部署以及管理多個專案,docker的規劃如下圖
伺服器配置
配置ssh免密登陸
-
把本地的~/.ssh/id_rsa.pub複製到伺服器~/.ssh/authorized_keys裡面
-
重新登陸一次即可
安裝docker以及存放指令碼
- docker簡介以及安裝 如何使用下面會說
- 在伺服器喜歡的地方建一個存放執行指令碼的資料夾,例如我就放在根目錄下/server_sh,然後給個777許可權
本機配置
- 在本機建立一個資料夾server_sh,並給個777許可權,同時建立一個存放阿里雲伺服器上面的指令碼的資料夾aliyun,此資料夾對應伺服器上面的server_sh
- 在server_sh下面建立一個自動更新伺服器檔案update_aliyun.sh,通過scp命令把aliyun資料夾裡面的shell指令碼同步到伺服器,只要修改了指令碼,執行一次./update_aliyun.sh,即可完成同步
#!/bin/sh
#更新伺服器指令碼
scp -r ./aliyun/* root@(伺服器ip):/server_sh/
複製程式碼
- 在aliyun資料夾建立首次執行docker的指令碼、需要安裝的資料庫型別指令碼,這裡使用了nginx、mongodb、mysql
注意1:db型別的映象run的時候需要使用內部或者掛載主機目錄資料卷來存放db資料,不然容器被刪除,資料就會丟失
注意2:容器內容通訊需要建立一次內部網路,不然只能每個埠都暴露出去,我為了方便除錯,所有的埠好都暴露了出來,從正式環境來講,應該只暴露nginx的80埠即可,其他都使用容器內部通訊
- docker_create.sh
#!/bin/sh
# 首次安裝docker跑的指令碼
# 建立docker內部網路
docker network create --subnet 192.168.0.0/16 local-network
#啟動web服務
./webserver.sh
#啟動mongodb資料庫
./mongodb.sh
#啟動mysql資料庫
./mysql.sh
複製程式碼
- webserver.sh(根據需要,由官方nginx為基礎配置的映象,後面會說)
#!/bin/sh
# 啟動Nginx服務
#停止正在執行的映象
docker container stop webserver
#刪除舊映象
docker container rm webserver
#刪除image,確保啟動的時候能拿到最新的映象
docker image rm masonchow/webserver
#下載最新映象並啟動
docker run -d -p 80:80 --name webserver -v /dockerVolume/web:/web:ro masonchow/webserver
複製程式碼
- mongodb.sh
#!/bin/sh
#停止正在執行的映象
docker container stop mongo
#刪除舊映象
docker container rm mongo
#刪除image,確保啟動的時候能拿到最新的映象,若不需要拿最新版本映象則不用執行
docker image rm mongo
# 安裝並啟動mongodb
docker run -d -p 27017:27017 -v /dockerVolume/db/mongo/data:/data/db --name mongo --network local-network --ip 192.168.0.101 mongo
複製程式碼
- mysql.sh
#!/bin/sh
#停止正在執行的映象
docker container stop mysql
#刪除舊映象
docker container rm mysql
#刪除image,確保啟動的時候能拿到最新的映象,若不需要拿最新版本映象則不用執行
# docker image rm mysql
# 安裝並啟動mysql
docker run -d -p 3306:3306 -v /dockerVolume/db/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql --network local-network --ip 192.168.0.100 mysql
複製程式碼
- 執行update_aliyun.sh同步指令碼到伺服器並且在伺服器執行一次docker_create.sh之後,在伺服器打
docker container ls
就可以看到正在執行的容器資訊
專案配置
Nginx
因為只有一個伺服器,如果多個前端專案的話,每次增加一個前端專案,就需要更改一次nginx的配置,所以就根據官方的nginx加以自己的配置,利用指令碼把定製好的dockerfile構造一個image更新到自己的docker倉庫上,給伺服器下載使用即可
- DockerFile
FROM nginx:latest
#一些nginx配置
ADD conf/nginx.conf /etc/nginx/nginx.conf
#nginx站點配置
ADD conf/server_app.conf /etc/nginx/conf.d/default.conf
ADD conf/gzip.conf /etc/nginx/conf.d/gzip.conf
RUN cd / \ && mkdir /web
WORKDIR /web
CMD ["nginx", "-g", "daemon off;"]
複製程式碼
這裡監聽的web目錄是docker監聽的本地目錄,是由於在上文啟動nginx的時候跑了-v /dockerVolume/web:/web:ro
前端專案
前端專案只需要在本地構建完之後把dist資料夾同步到伺服器對應的資料夾即可,例如我在專案資料夾下會建立一個publsh.sh,同時給個777的許可權即可
#!/bin/sh
#刪除本地的依賴包
rm -rf ./node_modules
#重新安裝
npm i
#開始構建
npm run build
#刪除遠端本身的檔案
ssh root@120.78.190.53 "rm -rf /dockerVolume/web/專案資料夾"
#把本地編譯的檔案放上去遠端
scp -r ./wallet root@伺服器IP:/dockerVolume/web/
複製程式碼
後端專案
後端專案的思路是每次更新發布就跑一次專案的指令碼,通過dockerflie把後端編譯成一個新的image更新到自己的docker倉庫讓伺服器的docker跑最新的映象
- publish.sh
#開始構建
npm run build
#構建最新映象
docker build -t 使用者名稱/映象名 .
#釋出映象
docker push 使用者名稱/映象名
# 刪除構建之後的程式碼
rm -rf ./dist
# 伺服器現實新映象
ssh root@伺服器IP "cd /server_sh && ./伺服器上面對應的指令碼.sh"
複製程式碼
- DockerFile
FROM node:8.9.3
COPY /dist /server
WORKDIR /server
ENV NODE_ENV=production
COPY /package.json /server
RUN npm install
CMD ["node", "./app.js"]
複製程式碼
- 伺服器上面的指令碼
#!/bin/sh
# 啟動後端服務
#停止正在執行的映象
docker container stop 容器名
#刪除舊映象
docker container rm 容器名
#刪除image,確保下載的是最新映象
docker image rm 使用者名稱/映象名
#下載最新映象並啟動
docker run -d -p 3005:3005 --name 容器名 --network local-network --ip 192.168.0.105 使用者名稱/映象名
複製程式碼
最後
畢業一年多,第一次寫文章,不足之處,請求指出,十分感謝