摘要:前言前段時間,自己搞了個阿里云的服務器。編寫服務器部署腳本從上面步驟來看,我們還需要一個服務器端的部署腳本。服務器一個,本地一個簡稱只需一個腳本。最終我達成了滿足我需求的一個方便的部署腳本。
1.前言
前段時間,自己搞了個阿里云的服務器。想自己在上面折騰,但是不想因為自己瞎折騰而污染了現有的環境。畢竟,現在的阿里云已經沒有免費的快照服務了。要想還原的話,最簡單的辦法就是重新裝系統。而一旦重裝,之前的搭建的所有環境就都白搭了。
再加上之前本身就想引入docker,所以就打算利用docker容器來部署這次的前端應用。
2.構建前端應用在打包之前,首先需要一個可正常運行的前端應用。這個可以使用umi或者create-react-app來構建。
3.nginx的默認配置文件然后需要在項目中加上默認nginx配置文件。
server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } }4.編寫本地構建腳本 4.1. 移除上次的目錄和Dockerfile
#!/bin/bash if [ -d "./dist" ]; then rm -rf ./dist fi if [ -f "./Dockerfile" ]; then rm -f ./Dockerfile fi
因為每次更改后dist中的內容肯定與之前不同,其實這一步顯得不是那么必要。運行npm的打包命令也會自動清楚該目錄。
而清除Dockerfile則是為了防止更新了Dockerfile,而這次卻不能得到最新的配置。
4.2. 打包前端應用執行前端的打包命令,生成靜態文件目錄。
yarn build4.3. 生成Dockerfile
echo "FROM nginx:latest" >> ./Dockerfile echo "COPY ./dist /usr/share/nginx/html/" >> ./Dockerfile echo "COPY ./default.conf /etc/nginx/conf.d/" >> ./Dockerfile echo "EXPOSE 80" >> ./Dockerfile
FROM制定了該定制容器的基礎鏡像為nginx:latest;COPY命里將打包好的靜態文件目錄復制到容器內的/usr/share/nginx/html/目錄下,然后將nginx的配置寫入容器中對應的位置; EXPOSE則是設置對外暴露容器的80端口。
4.4. 生成并推送定制imagedocker build -t detectivehlh/mine . docker login -u detectivehlh -p ******** docker push detectivehlh/mine
這里是在開發本地,使用docker命令來打包,所以該腳本對docker有強依賴。build命令表示打包docker應用的,-t選項則制定了docker鏡像的名字和tag,tag會默認為latest。
然后登錄dockerHub,將定制好的鏡像推送到dockerHub中。detectivehlh就是dockerHub的用戶名,mine是image的名字。
4.5. 刪除tag為none的無用image第一次構建不會生成tag為none的image,但是后面每次再次執行該命令就會出現這樣的情況。所以每次構建了一個新的image后,需要清除調不需要的image。
docker images | grep none | awk "{print $3}" | xargs docker rmi
使用grep命令匹配到tag為none的image,awk是一個強大的文本分析工具,{print $3}表示打印出匹配到的每一行的第三個字段,也就是docker的image id。如果是$0的話表示當前整行的數據。
xargs是一個給其他命令(也就是后面的docker rmi)傳遞參數的一個過濾器,將標準輸入轉換成命令行參數。
總結來說,上述命令就是找到tag為none的image的ID,然后使用docker rmi命令移除該image。
4.6. 執行部署cmd="cd ~ && sh deploy.sh mine" ssh -t USER_NAME@IP_ADDRESS "bash -c "${cmd}""
通過ssh命令,登錄遠程服務器,并且執行參數中的腳本。
deploy.sh是放在服務端的構建腳本。放在默認的登錄用戶下。我們發現,后面還跟了個mine,這是在服務器上運行的docker鏡像的名字。這里暫時沒有對container的名字加上hash,因為自己的小項目,暫時沒有必要。
在項目中的完整構建腳本如下。
#!/bin/bash if [ -d "./dist" ]; then rm -rf ./dist fi if [ -f "./Dockerfile" ]; then rm -f ./Dockerfile fi yarn build echo "FROM nginx:latest" >> ./Dockerfile echo "COPY ./dist /usr/share/nginx/html/" >> ./Dockerfile echo "COPY ./default.conf /etc/nginx/conf.d/" >> ./Dockerfile echo "EXPOSE 80" >> ./Dockerfile docker build -t detectivehlh/mine . docker login -u detectivehlh -p ******** docker push detectivehlh/mine docker images | grep none | awk "{print $3}" | xargs docker rmi cmd="cd ~ && sh deploy.sh mine" ssh -t USER_NAME@IP_ADDRESS "bash -c "${cmd}""5. 編寫服務器部署腳本
從上面步驟來看,我們還需要一個服務器端的部署腳本。大家可能會說,標題不是說一個腳本搞定嗎?em。。。服務器一個,本地一個...簡稱只需一個腳本。
5.1 接收參數在本地的構建腳本中,我們傳入了docker運行的container的名字。在服務器構建腳本中需要來接收它。然后更新剛剛推送的docker image。
#!/bin/bash name=$1 docker pull detectivehlh/$name5.2. 啟動container
在啟動container時我們會面對兩種情況,名字為傳入參數的container已經在運行了。而在此時如果再次運行docker run命令就會報錯而導致我們無法使用最新的container,也無法達到更新應用的目的。
if docker ps | grep $name | awk {"print $(NF)"} | grep -Fx $name; then echo "Container mine is already start" docker stop $name docker rm $name docker run -d --name $name -p 3000:80 detectivehlh/$name else echo "Container mine is not start!, starting" docker run -d --name $name -p 3000:80 detectivehlh/$name echo "Finish starting" fi docker images | grep none | awk "{print $3}" | xargs docker rmi
所以在這里做一個判斷,第一個if判斷如果存在名字為傳入參數的container正在運行,就停止當前容器再重新啟動。如果不存在則直接啟動容器。
run命令就不過多解釋了。-d表示后臺運行容器并返回容器ID,--name表示設置容器的名字,-p表示設置端口,將阿里云服務器的3000端口映射到容器的80端口,最后一句表示要啟動哪個image(好像還是解釋了一遍)。
最后一句就是移除多次更新后出現的tag為none的無用鏡像。完整的腳本如下。
#!/bin/bash name=$1 docker pull detectivehlh/$name if docker ps | grep $name | awk {"print $(NF)"} | grep -Fx $name; then echo "Container mine is already start" docker stop $name docker rm $name docker run -d --name $name -p 3000:80 detectivehlh/$name else echo "Container mine is not start!, starting" docker run -d --name $name -p 3000:80 detectivehlh/$name echo "Finish starting" fi docker images | grep none | awk "{print $3}" | xargs docker rmi6. 如果你只是想打個包
看到標題進來的兄dei,如果只是想打包一個docker鏡像,那么你只需要Dockerfile文件和docker build命令就OK了。
7. 總結最初寫這個腳本,主要目的是為了方便。所以腳本中為了達到這個目的做了一些調整。最終我達成了滿足我需求的一個方便的部署腳本。
它的方便體現在,當我完成了項目代碼的更新,只需要跑一下這個腳本,然后等待一會兒,項目就會自動打包成docker image,并且自動的在我的服務器上運行該container。
但是這種方式會給實際的生產環境帶來一些不可控的問題。比如,腳本必須不能上傳,因為涉及一些服務器的敏感信息。但是如果你不小心上傳了,那你的服務器就相當于裸奔了;再比如,你對你的代碼必須要十分自信,沒有經過測試的代碼就直接部署,會帶來一些風險。
如果是自己用的,那完全不用擔心,想怎么搞怎么搞。但是如果是開放給所有人用的并且有一定的訪問量,比如博客,那么對于其他用戶來說,這種方式就不怎么友好。
所以我的觀點是,分情況來。目前來說我的項目只有少數幾個人在用,也還在處于迭代階段。并且代碼倉庫是私有的,所以我完全不用擔心隱私的問題。服務未經測試就直接上線對于我來說,其實問題也不大。首先我會在本地測試,確認無誤后才會執行部署操作。所以在不同的階段,找到最適合自己的方案就OK。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/103803.html
摘要:前言前段時間,自己搞了個阿里云的服務器。編寫服務器部署腳本從上面步驟來看,我們還需要一個服務器端的部署腳本。服務器一個,本地一個簡稱只需一個腳本。最終我達成了滿足我需求的一個方便的部署腳本。 1.前言 前段時間,自己搞了個阿里云的服務器。想自己在上面折騰,但是不想因為自己瞎折騰而污染了現有的環境。畢竟,現在的阿里云已經沒有免費的快照服務了。要想還原的話,最簡單的辦法就是重新裝系統。而一...
摘要:解決的痛點免搭建后端開發環境。開發環境改變只需要改變鏡像就能同步更新。啟動這個新建的鏡像。 這篇文章是為了解決前后端開發沒有徹底分離的坑,因為我司用的是java,入職第一天就是搭建本地開發環境,看見了多年不見的eclipse的圖標出現我的電腦上,我是難過的。后來知道并不是我一個人有此感受。依稀記得有個同學整整一天項目都沒跑起來的崩潰感。為了解決這個問題我們嘗試了很多方案,但是大大小小都...
摘要:解決的痛點免搭建后端開發環境。開發環境改變只需要改變鏡像就能同步更新。啟動這個新建的鏡像。 這篇文章是為了解決前后端開發沒有徹底分離的坑,因為我司用的是java,入職第一天就是搭建本地開發環境,看見了多年不見的eclipse的圖標出現我的電腦上,我是難過的。后來知道并不是我一個人有此感受。依稀記得有個同學整整一天項目都沒跑起來的崩潰感。為了解決這個問題我們嘗試了很多方案,但是大大小小都...
摘要:解決的痛點免搭建后端開發環境。開發環境改變只需要改變鏡像就能同步更新。啟動這個新建的鏡像。 這篇文章是為了解決前后端開發沒有徹底分離的坑,因為我司用的是java,入職第一天就是搭建本地開發環境,看見了多年不見的eclipse的圖標出現我的電腦上,我是難過的。后來知道并不是我一個人有此感受。依稀記得有個同學整整一天項目都沒跑起來的崩潰感。為了解決這個問題我們嘗試了很多方案,但是大大小小都...
摘要:打開終端執行,再開一個終端輸入輸出,則表示該服務沒有問題。將服務打包成鏡像,然后將鏡像實例化并運行,方便部署。此處以我的賬號為例,需要推送到你自己的賬號。是一種自動化運維工具,本文主要需要了解,,三個概念。至此成功使用部署應用。 本文將以一個簡單的示例演示如何使用 Docker 與 Kubernetes 部署應用上線。 Http Service 首先使用 Go 語言搭建一個簡單的 Ht...
閱讀 4162·2021-11-22 13:52
閱讀 2508·2021-11-22 13:52
閱讀 3682·2021-11-19 09:59
閱讀 1182·2021-11-17 09:33
閱讀 2443·2019-08-30 10:53
閱讀 1205·2019-08-29 17:28
閱讀 1305·2019-08-29 17:03
閱讀 3096·2019-08-26 11:31