如何透過docker-compose將node服務部署到多套環境?以下這篇文章就來跟大家介紹Docker-compose多環境部署Node服務的方法,希望對大家有幫助!
一般情況下,我們專案在開發完成之後,需要部署到多套環境,例如測試、沙箱、整合等等,那麼如何透過docker-compose將node服務部署到多套環境呢?以下文章具體說下,有什麼不對的地方歡迎大家評論。
本文中的專案用到的技術是Gitlab Ansible Docker自動化部署node服務(nest框架寫的),步驟如下:
編寫docker-compose、docker-compose.prod.yml配置檔案
#修改package.json
遠端伺服器上建立兩個目錄,拉取node服務倉庫,切換到不同分支,分別表示測試、線上node服務
#.gitlab-ci.yml檔案寫
ansible.yml檔案編寫
遠端伺服器node服務(測試/線上)目錄下執行以下命令,執行之後,透過docker ps -a
查看容器是否正常啟動,如果是up狀態掛起,證明容器啟動成功了。 docker logs -f 容器id
查看容器日誌
# 测试目录 /opt/xxx/server-test/server docker-compose up -d # 线上目录 /opt/xxx/server-prod/server # -f表示指定具体文件,默认执行的是docker-compose.yml文件 docker-compose -f docker-compose.prod.yml up -d
編寫docker-compose、docker-compose .prod.yml設定檔
# docker-compose.yml version: '3.0' services: # 服务列表 # 测试数据库 mysql: image: mysql container_name: mysql_test restart: always environment: - MYSQL_ROOT_PASSWORD=test_sql - NODE_ENV=development ports: - 13306:3306 volumes: - 服务器上对应目录:/var/lib/mysql # 测试node服务 server: # node服务 container_name: server-test # 容器名称 image: node:14.15.0 ports: # 暴露的端口 - "7007:5088" environment: - NODE_ENV=development volumes: - .:/data working_dir: /data depends_on: # web服务依靠mysql要先等mysql启动 - mysql restart: on-failure:5 # 自动重启,失败的话重启5次后停止 command: yarn start # 覆盖容器启动后默认执行的命令
# docker-compose.prod.yml version: '3.0' services: # 服务列表 # 线上数据库 prod-mysql: image: mysql container_name: mysql_prod restart: always environment: - MYSQL_ROOT_PASSWORD=prod_sql - NODE_ENV=production ports: - 13307:3306 volumes: - 服务器上对应目录:/var/lib/mysql # 线上node服务 prod-server: container_name: server-prod image: node:14.15.0 ports: - "7077:5089" environment: - NODE_ENV=production volumes: - .:/data working_dir: /data depends_on: - prod-mysql restart: on-failure:5 command: yarn start:prod
package.json中做如下修改
# cross-env指定NODE_ENV为开发或线上环境 ... "scripts": { ... "build": "nest build", "start": "yarn && cross-env NODE_ENV=development nest start", "start:prod": "yarn && yarn build && cross-env NODE_ENV=production node dist/src/main", ... }, ...
#遠端伺服器上建立兩個目錄,分別存放測試、線上node服務
# 测试(dev分支),git clone node服务地址,切换到dev分支 /opt/xxx/server-test/server # 线上(master分支),git clone node服务地址,切换到master分支 /opt/xxx/server-prod/server
.gitlab-ci.yml檔案編寫
# CI变量说明说明 - BRANCH、DEV_BRANCH是CI变量,分别对应master、dev分支 - DOCKER_CONTAINER、DEV_DOCKER_CONTAINER分别对应线上、测试启动的docker容器 - ROOT_PATH、DEV_ROOT_PATH分别对应远程服务器上线上、测试node服务存放路径 - CI_PROJECT_NAME表示gitlab上仓库名称 stages: - dev_deploy - master_deploy master_deploy: stage: master_deploy image: ansible镜像地址 script: - echo \"${HOST}\" ansible_ssh_user=\"${USER}\" ansible_ssh_pass=\"${PASS}\" ansible_ssh_host=\"${HOST}\" > hosts - echo ansible-playbook ansible.yaml -e hosts=${HOST} -i ./hosts - ansible-playbook ansible.yaml -e "HOST=${HOST} DEST_PATH=${ROOT_PATH}/${CI_PROJECT_NAME} DOCKER_CONTAINER_NAME=${DOCKER_CONTAINER} CUR_BRANCH=${BRANCH}" -i ./hosts - rm -f hosts only: - master tags: - k8s dev_deploy: stage: dev_deploy image: ansible镜像地址 script: - echo \"${HOST}\" ansible_ssh_user=\"${USER}\" ansible_ssh_pass=\"${PASS}\" ansible_ssh_host=\"${HOST}\" > hosts - echo ansible-playbook ansible.yaml -e hosts=${HOST} -i ./hosts - ansible-playbook ansible.yaml -e "HOST=${HOST} DEST_PATH=${DEV_ROOT_PATH}/${CI_PROJECT_NAME} DOCKER_CONTAINER_NAME=${DEV_DOCKER_CONTAINER} CUR_BRANCH=${DEV_BRANCH}" -i ./hosts - rm -f hosts only: - dev tags: - k8s
ansible.yml檔案編寫
# cd到node服务server目录,切换分支,拉取最新代码,docker容器重启 - name: deploy hosts: "{{ HOST }}" become_user: root become: yes tasks: # 任务 - name: git checkout branch command: git checkout "{{CUR_BRANCH}}" args: chdir: "{{ DEST_PATH }}" - name: git pull command: git pull args: chdir: "{{ DEST_PATH }}" - name: docker restart container command: docker restart "{{ DOCKER_CONTAINER_NAME }}" args: chdir: "{{ DEST_PATH }}"
遠端伺服器node服務(測試/線上)目錄下執行如下指令
# 测试目录 /opt/xxx/server-test/server docker-compose up -d # 线上目录 /opt/xxx/server-prod/server docker-compose -f docker-compose.prod.yml up -d
啟動成功之後透過docker ps -a
檢視容器啟動情況,如下圖所示:
說明:
測試環境:當本地dev分支程式碼提交或其他分支合併到dev分支時,會透過itlab CI、Ansible自動化部署node服務到遠端伺服器,在對應伺服器遠端目錄下切換分支、拉取最新程式碼、重新啟動對應的測試docker容器
線上環境:本機master分支程式碼提交或其他分支合併到master分支時,會透過itlab CI、Ansible自動化部署node服務到遠端伺服器,在對應伺服器遠端目錄下切換分支、拉取最新程式碼、重新啟動對應的線上docker容器
問題一:測試/線上遠端node服務目錄下沒有node_modules目錄和dist目錄,也就是沒有下圖這兩個檔案同時遠端伺服器器上查看docker容器日誌報如下錯誤(這個問題排查了好久才解決)
檢查: 發現和正常啟動的node服務容器對比來看,沒有這兩個目錄(dist和node_modules),排查是不是docker-compose.yml中command執行指令有問題,即docker-compose.yml的command中yarn && yarn start是不是有問題,於是試著把yarn操作放在package.json中,結果好啦。
解決:
# 修改前 # docker-compose.yml version: '3.0' services: ... server: ... command: yarn && yarn start # package.json "scripts": { ... "build": "nest build", "start": "cross-env NODE_ENV=development nest start", "start:prod": "cross-env NODE_ENV=production yarn build && node dist/src/main", ... }, # 修改后 # docker-compose.yml version: '3.0' services: ... server: ... command: yarn start # package.json 方案一: "scripts": { ... "build": "nest build", "start": "yarn && cross-env NODE_ENV=development nest start", "start:prod": "yarn && yarn build && cross-env NODE_ENV=production node dist/src/main", ... }, 方案二: "scripts": { ... "build": "nest build", "start": "cross-env NODE_ENV=development nest start", "prestart": "yarn", "start:prod": "yarn build && cross-env NODE_ENV=production node dist/src/main", "prestart:prod": "yarn", ... },
注意:
cross-env的位置,放在可執行指令之前,在本專案中,放在最前面伺服器上報cross-env not found, 放在最後面環境變數不生效,NODE_ENV顯示undefined
#script中可執行指令注意執行順序,例如yarn && yarn build && cross-env NODE_ENV=production node dist/src/main
script中pre
#問題2: 前端線上網域對映不生效,nginx設定檔映射線上網域名稱之後,發現存取線上網域名稱時,發現頁面沒有生效
排查:將nginx測試設定檔和線上設定檔對比,發現檔案內容除了網域和api代理,其餘都是一樣,那到底是什麼原因呢?最後發現竟然是線上nginx設定檔後綴名不對,寫的是xxx.confg,此處心裡一萬個想打死自己
解決: 修改線上nginx設定檔為正確的後綴,即xxx.conf後綴
########问题三:Gitlab CI执行异常,具体报错信息大概是报/server目录找不到
排查:在CI里面打印输出CI变量以及拼接出来的目录变量,查看是哪一步有问题,经排查发现都是正常的,唯一不同的一点是CI变量后面设置了环境变量
解决:尝试把环境变量改为All default,结果好了,记住,不要随意配置CI后面的环境变量,如果修改的话,对应的Gitlab里面也是对应需要映射的,环境变量位置如下图所示:
master_deploy: ... script: ... - echo ${ROOT_PATH} - echo ${CI_PROJECT_NAME} - echo ${ROOT_PATH}/${CI_PROJECT_NAME} - echo ${DOCKER_CONTAINER} - echo ${BRANCH} ... ...
本文到这就结束了,后面还会有一篇文件,讲全栈项目从开发到自动化部署整个过程(用到的技术栈是Vue + Nest + Typeorm + Mysql+ Gitlab CI + Ansible + Docker)。
推荐学习:《docker视频教程》、《nodejs 教程》
以上是聊聊如何透過docker-compose將node服務部署到多套環境中的詳細內容。更多資訊請關注PHP中文網其他相關文章!