首頁  >  文章  >  運維  >  聊聊如何透過docker-compose將node服務部署到多套環境中

聊聊如何透過docker-compose將node服務部署到多套環境中

青灯夜游
青灯夜游轉載
2022-01-28 18:00:433877瀏覽

如何透過docker-compose將node服務部署到多套環境?以下這篇文章就來跟大家介紹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檢視容器啟動情況,如下圖所示:

聊聊如何透過docker-compose將node服務部署到多套環境中

說明

  • 測試環境:當本地dev分支程式碼提交或其他分支合併到dev分支時,會透過itlab CI、Ansible自動化部署node服務到遠端伺服器,在對應伺服器遠端目錄下切換分支、拉取最新程式碼、重新啟動對應的測試docker容器

  • 線上環境:本機master分支程式碼提交或其他分支合併到master分支時,會透過itlab CI、Ansible自動化部署node服務到遠端伺服器,在對應伺服器遠端目錄下切換分支、拉取最新程式碼、重新啟動對應的線上docker容器

遇到的問題

問題一:測試/線上遠端node服務目錄下沒有node_modules目錄和dist目錄,也就是沒有下圖這兩個檔案同時遠端伺服器器上查看docker容器日誌報如下錯誤(這個問題排查了好久才解決

聊聊如何透過docker-compose將node服務部署到多套環境中

聊聊如何透過docker-compose將node服務部署到多套環境中

檢查: 發現和正常啟動的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里面也是对应需要映射的,环境变量位置如下图所示:

聊聊如何透過docker-compose將node服務部署到多套環境中

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中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除