• 技术文章 >运维 >Docker

    聊聊如何通过docker-compose将node服务部署到多套环境中

    青灯夜游青灯夜游2022-01-28 18:01:23转载290
    如何通过docker-compose将node服务部署到多套环境?下面本篇文章就来给大家介绍一下Docker-compose多环境部署Node服务的方法,希望对大家有所帮助!

    一般情况下,我们项目在开发完成之后,需要部署到多套环境,比如测试、沙箱、集成等等,那么如何通过docker-compose将node服务部署到多套环境呢?下面文章具体说下,有什么不对的地方欢迎大家评论。

    本文中的项目用到的技术是Gitlab+Ansible+Docker自动化部署node服务(nest框架写的),步骤如下:

    # 测试目录 /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.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
    # 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",
        ...
      },
    ...
    # 测试(dev分支),git clone node服务地址,切换到dev分支
    /opt/xxx/server-test/server
    
    # 线上(master分支),git clone node服务地址,切换到master分支
    /opt/xxx/server-prod/server
    # 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
    # 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 }}"
    # 测试目录 /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查看容器启动情况,具体如下图所示:

    1.png

    说明

    遇到的问题

    问题一:测试/线上远程node服务目录下没有node_modules目录和dist目录,即没有下图这两个文件同时远程服务器器上查看docker容器日志报如下错误(这个问题排查了好久才解决

    2.png

    3.png

    排查: 发现和正常启动的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",
        ...
    },

    注意

    问题2: 前端线上域名映射不生效,nginx配置文件映射线上域名之后,发现访问线上域名时,发现页面没有生效

    排查:将nginx测试配置文件和线上配置文件对比,发现文件内容除了域名和api代理,其余都是一样,那到底是什么原因呢?最后发现竟然是线上nginx配置文件后缀名不对,写的是xxx.confg,此处心里一万个想打死自己

    解决: 修改线上nginx配置文件为正确的后缀,即xxx.conf后缀

    问题三:Gitlab CI执行异常,具体报错信息大概是报/server目录找不到

    排查:在CI里面打印输出CI变量以及拼接出来的目录变量,查看是哪一步有问题,经排查发现都是正常的,唯一不同的一点是CI变量后面设置了环境变量

    解决:尝试把环境变量改为All default,结果好了,记住,不要随意配置CI后面的环境变量,如果修改的话,对应的Gitlab里面也是对应需要映射的,环境变量位置如下图所示:

    4.png

    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中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:docker-compose node
    上一篇:深入浅析docker文件分层(实例详解) 下一篇:docker无法访问容器怎么办

    相关文章推荐

    • 让人心动的docker快速入门指南(图文详解)• 详细介绍docker数据卷管理&convoy卷插件(实例详解)• 怎么在node中使用koa框架调用高德地图接口• 聊聊node中怎么使用Nest.js 连接 MongoDB 数据库• 深入浅析docker文件分层(实例详解)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网