使用 Docker-compose 一鍵打包部署項目!真心不錯啊
前言
我們常常見到很多比較棒的開源項目,但在本地安裝運行的話就會很複雜,要配置不同的環境,安裝不同的依賴,好一點的會用 docker 直接拉取,或者打包好。
這些無疑都會增加初學者上手的成本,所以這篇文章總結了下目前比較常用的解決方法之一:
使用 docker-compose 同時管理多個服務,只需要一行命令docker compose up -d
,就可以啓動一個包含後端項目、前端項目、數據庫的完整服務。
而 docker-compose 作爲 docker 容器的編排工具,可以幫助我們實現管理多個 docker 容器。
其實整體的過程並不難,但要配置完成,也要很多步驟,這篇文章主要是從實戰的角度,將整個過程串起來。涉及的知識點包括:nginx、docker、docker-compose、node、mysql 也需要了解下。
適合讀下去的朋友:
-
對 Docker 有基本的瞭解
-
同時需要部署多個項目
-
需要開源項目或者自建項目的整體部署
-
需要打包部署一整個網站
需要提前準備的
Docker 安裝並啓動(演示版本如下)
-
docker-compose(安裝 Docker 同時會自動安裝,如果沒有可以自行安裝,也很簡單)
-
一個前端項目(這裏演示使用 React SPA)
-
一個後端項目(這裏使用 Express)
如圖所示,通過 docker-componse.yml 文件一次啓動不同的容器,然後他們都可以對外提供服務。
前端項目構建
前端項目處理
首先我們通過 CRA 下載一個項目模版,爲了可以模擬實際的項目需要,對下載的模版做一些處理,讓這個項目可以
-
1、區分當前項目是預發環境還是生產環境
-
2、引入 Axios 可以請求接口
接着我們打包yarn build:prod
,打包後的文件夾 build 就是我們要部署的靜態資源。
拉取 Nginx 鏡像部署
我們通過 Docker 部署前面打包的靜態資源,當前項目的路徑是
/Users/user/Desktop/mine/fronted-demo2/build
直接運行下面命令行,啓動前端服務
docker run -d -p 80:80 -v /Users/user/Desktop/mine/fronted-demo2/build:/usr/share/nginx/html --name frontend-test nginx
通過本機 80 端口訪問,發現當前服務是生產環境,並且由於後端服務沒有部署,此時數據庫拿到的數據爲空。
測試,我們切換路由,發現頁面 404 了,是因爲單頁面應用路由在前端,需要 nginx 轉發下,接着我們用項目中的 Nginx 配置覆蓋容器中的配置
提取 Nginx 配置到項目中
首先,我們進入上一步的 Docker 容器,可以看到 Nginx 的路徑。
docker exec -it frontend-test /bin/bash
在項目根目錄下新建 nginx/default.conf
server {
listen 80;
server_name localhost;
underscores_in_headers on;
root /home/frontend;
location / {
try_files $uri $uri/ @router;
index index.html;
}
location @router {
rewrite ^.*$ /index.html last;
}
}
然後通過掛載的方式,啓動容器,發現訪問正常。
編寫 Dockerfile 文件
FROM nginx
WORKDIR /home/frontend
COPY build .
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
在項目根目錄下,新建 Dockerfile 文件,其中包括基礎鏡像、工作目錄、將項目 copy 到鏡像,將 Nginx 配置文件複製到鏡像中。
構建前端服務鏡像並啓動
docker build -t frontend .
docker images
docker run -d -p 80:80 --name frontend-v1 frontend
可以發現前端服務的鏡像已經打包完成並啓動,打開本地 80 端口訪問,測試完畢可以刪除,然後留鏡像 frontend 備用。也可以將鏡像推送鏡像倉庫,後面直接通過遠程來拉取也可以。
主意:如果之前的 Docker 容器啓動,需要先關掉,否則會報端口被佔用,如果不刪除,就需要修改重新啓動容器的名字。
數據庫啓動
拉取並啓動數據庫、連接數據庫
docker run -p 3306:3306 --restart=always --privileged=true --name mysql -v /Users/user/Desktop/mysql/data:/var/lib/mysql -v /Users/user/Desktop/mysql/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD="123456" -d mariadb
一行命令啓動 Mariadb,這裏選擇 Mariadb 是由於我 m1 的電腦,不支持 mysql 鏡像,所以改成了 Mariadb,使用是一樣。上面的命令除了啓動數據庫服務,還設置了數據的一些配置,密碼,將數據庫的數據放在了本地。
[mysqld]
skip-name-resolve
user=root
character-set-server=utf8
default_authentication_plugin=mysql_native_password
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
lower_case_table_names=1 #忽略表名大小寫
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
新建庫和表
這裏可以進入容器中操作數據庫,還可以使用客戶端連接數據庫
後端項目啓動
下載 Express 項目模版並連接數據庫
這裏配置數據庫,寫好項目接口,確保本地啓動服務正常。
拉起鏡像,部署鏡像
部署服務,我們選擇使用 pm2,爲了區分生產環境和預發環境,我們在根目錄下新建 pm2.config.js,然後通過傳入不同的參數,啓動對應的環境
module.exports = {
apps : [
{
name: "myapp",
script: "./bin/www",
watch: true,
env: {
"NODE_ENV": "development"
},
env_production: {
"NODE_ENV": "production",
}
}
]
}
-
啓動預發環境
pm2 start pm2.config.js --env development
-
啓動生產環境
pm2 start pm2.config.js --env production
-
再項目中通過
process.env.NODE_ENV
讀取
編寫 Dockerfile 並構建新的鏡像
FROM keymetrics/pm2
RUN mkdir -p /home/backend
WORKDIR /home/backend
COPY ./ /home/backend
RUN yarn install
ENV NPM_CONFIG_LOGLEVEL warn
EXPOSE 9000
CMD ["pm2-runtime", "start", "pm2.config.js", "--env", "production"]
然後構建鏡像docker build -t backend .
docker-compose.yml 配置
截止目前,我們有了三個 Docker 鏡像,分別是前端服務的鏡像,後端服務的鏡像和數據庫的鏡像。然後我們編寫 docker-compose.yml 來同時啓動這三個服務,並且保證三者的啓動順序。
編寫 docker-compose 配置文件
新建一個目錄,然後再目錄下新建 docker-compose.yml 和目錄 mysql,mysql 中包含了 mysql 的數據和日誌信息,這樣就不用重啓服務導致數據庫信息丟失
version: '3'
networks:
app-web:
driver: bridge
services:
mysql:
image: mariadb
ports:
- 3306:3306
command: --default-authentication-plugin=mysql_native_password
restart: always
networks:
- app-web
environment:
- TZ=Asia/Shanghai
- MYSQL_USER=root
- MYSQL_ROOT_PASSWORD=123456
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/my.cnf
- /etc/localtime:/etc/localtime
backend:
image: backend
ports:
- 9000:9000
depends_on:
- mysql
networks:
- app-web
frontend:
image: frontend
ports:
- 80:80
depends_on:
- backend
看到這個配置不要怕,拆分開,其實很簡單,整個配置文件就是一個完整的項目,包括了 mysql、backend、frontend,每個部分和配置 Dockerfile 差不多,增加了 depends_on,很好理解,前置的服務需要提前部署,networks,讓不同的容器在相同的網絡中運行。當然這只是提供了最基礎的配置,更復雜的配置需要根據使用場景來完善。
啓動服務
docker compose up -d
-d #是以守護進程的方式運行,通過docker ps可以查看當前所有運行中的服務。
docker compose down
#停止當前集羣下的所有服務,並刪除容器。
到這裏,我們的 docker-compose 整體打包部署一個網站已經完成了,過程中可能存在各種各樣的坑,但只要配置報錯日誌進行查詢,就能一一解決。
如果需要重新部署一套,或者發佈新版本,只需要更新 docker-compose.yml 就可以了
注意點
1、mysql 配置
數據庫和項目的一些信息需要靈活配置,根據自己的需要。
自動遷移數據庫
我們發現,一些新的數據庫表,沒有進行初始化,導致需要手動處理,在項目中我們可以用腳本去,或者使用一些數據庫封裝的 orm 進行自動遷移。
一些報錯信息
解決辦法,修改 mysql 配置 host 爲 mysql
-
1、docker 拉取鏡慢的話,可以考慮國內鏡像
-
2、前端、後端項目可以使用任意的語言,只要構架不同的鏡像就可以了。
docker 查看日誌
docker logs -f --tail 100 containerId
_作者:前端中後臺 _
鏈接:juejin.cn/post/6981207521994211359
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/MsU2MuJBISqoPv6WDOJ27A