Maison >Opération et maintenance >Docker >Parlons de la façon de déployer des services de nœuds sur plusieurs environnements via docker-compose
Comment déployer des services nodesur plusieurs environnements via docker-compose ? L'article suivant vous présentera comment déployer les services Node dans plusieurs environnements avec Docker-compose. J'espère qu'il vous sera utile !
Généralement, une fois notre projet développé, il doit être déployé sur plusieurs environnements, tels que les tests, le bac à sable, l'intégration, etc. Alors, comment déployer des services de nœuds sur plusieurs environnements via docker-compose ? L'article suivant l'explique en détail. S'il y a quelque chose qui ne va pas, vous êtes invités à commenter.
La technologie utilisée dans le projet dans cet article est Gitlab+Ansible+DockerDéploiement automatisé des services de nœuds (écrit par Nest Framework). Les étapes sont les suivantes :
Écrivez docker-compose et docker-compose. Fichiers de configuration prod.yml
Modifier package.json
Créez deux répertoires sur le serveur distant, extrayez l'entrepôt de services de nœud et passez à différentes branches, représentant respectivement les services de test et de nœud en ligne
.gitlab Fichier -ci.yml Écrivez le fichier
ansible.yml et exécutez la commande suivante dans le répertoire du service de nœud de serveur distant (test/online) Après l'exécution, vérifiez si le conteneur démarre normalement via docker ps -a.
, s'il se bloque à l'état actif, cela prouve que le conteneur a été démarré avec succès. docker logs -f conteneur id
Afficher les journaux du conteneur
# 测试目录 /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 ps -a
查看容器是否正常启动,如果是up状态挂起,证明容器启动成功了。docker logs -f 容器id
查看容器日志
# 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、docker-compose.prod.yml配置文件
# 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", ... }, ...
package.json中做如下修改
# 测试(dev分支),git clone node服务地址,切换到dev分支 /opt/xxx/server-test/server # 线上(master分支),git clone node服务地址,切换到master分支 /opt/xxx/server-prod/server
远程服务器上创建两个目录,分别存放测试、线上node服务
# 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
.gitlab-ci.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 }}"
ansible.yml文件编写
# 测试目录 /opt/xxx/server-test/server docker-compose up -d # 线上目录 /opt/xxx/server-prod/server docker-compose -f docker-compose.prod.yml up -d
远程服务器node服务(测试/线上)目录下执行如下命令
# 修改前 # 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", ... },
启动成功之后通过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中,结果好啦。
解决:
master_deploy: ... script: ... - echo ${ROOT_PATH} - echo ${CI_PROJECT_NAME} - echo ${ROOT_PATH}/${CI_PROJECT_NAME} - echo ${DOCKER_CONTAINER} - echo ${BRANCH} ... ...
注意:
cross-env的位置,放在可执行命令之前,在本项目中,放在最前面服务器上报cross-env not found, 放在最后面环境变量不生效,NODE_ENV显示undefined
script中可执行命令注意执行顺序,比如yarn && yarn build && cross-env NODE_ENV=production node dist/src/main
rrreeerrreee
rrreee
Créez deux répertoires sur le serveur distant pour stocker respectivement les tests et les services de nœuds en ligne
rrreee
.écriture du fichier gitlab-ci.yml🎜🎜 🎜rrreee🎜🎜🎜écriture du fichier ansible.yml🎜🎜🎜rrreee🎜🎜🎜Exécutez la commande suivante dans le répertoire du service de nœud de serveur distant (test/en ligne)🎜🎜🎜rrreee🎜Après un démarrage réussi, transmettezdocker ps -a code>Vérifiez l'état de démarrage du conteneur, comme indiqué dans la figure ci-dessous : 🎜🎜<img src="https://img.php.cn/upload/image/795/886/918/1643363755384508.png" title="1643363755384508.png " alt="Parlons de la façon de déployer des services de nœuds sur plusieurs environnements via docker-compose">🎜🎜🎜Instructions🎜:🎜<ul>🎜🎜Environnement de test : lorsque le code de la branche de développement locale est soumis ou que d'autres branches sont fusionnées dans la branche de développement, le service de nœud sera automatiquement déployé via itlab CI et le serveur distant Ansible, changez de branche dans le répertoire distant du serveur correspondant, extrayez le dernier code et redémarrez le conteneur Docker de test correspondant🎜🎜🎜🎜Environnement en ligne : lorsque le code de la branche principale locale est soumise ou d'autres branches sont fusionnées dans la branche principale, elle sera traitée via itlab CI, Ansible déploie automatiquement les services de nœuds sur des serveurs distants, change de branche dans le répertoire distant du serveur correspondant, extrait le dernier code et redémarre le docker en ligne correspondant conteneur🎜🎜🎜<h2>Problèmes rencontrés</h2>🎜🎜Problème 1🎜 : Il n'y a pas de répertoire node_modules et de répertoire dist dans le répertoire du service de nœud distant test/online, c'est-à-dire qu'il n'y a pas deux fichiers comme indiqué ci-dessous. en même temps, lors de la visualisation du journal du conteneur Docker sur le serveur distant, l'erreur suivante est signalée (🎜Ce problème a mis du temps à être résolu🎜)🎜🎜🎜🎜<img src="https://img.php.cn/upload/image/%20770/228/862/164336376434247Parlons%20de%20la%20fa%C3%A7on%20de%20d%C3%A9ployer%20des%20services%20de%20n%C5%93uds%20sur%20plusieurs%20environnements%20via%20docker-compose" title="164336376434247Parlons de la façon de déployer des services de nœuds sur plusieurs environnements via docker-compose" alt="Parlons de la façon de déployer des services de nœuds sur plusieurs environnements via docker-compose">🎜🎜🎜Dépannage : 🎜 Trouvé et normal En comparant les conteneurs de services de nœuds démarrés, il n'y a pas ces deux répertoires (dist et node_modules). Vérifiez s'il y a un problème avec la commande d'exécution de la commande dans docker-compose.yml, c'est-à-dire s'il y a un problème avec le démarrage de fil dans la commande de docker-compose.yml. Il y a eu un problème, alors j'ai essayé ? pour mettre l'opération de fil dans package.json, et le résultat était bon. 🎜🎜🎜Solution : 🎜🎜rrreee🎜🎜Remarque🎜 : L'emplacement de 🎜🎜🎜🎜cross-env est placé avant la commande exécutable Dans ce projet, il est placé au premier plan. et placées à la fin. Les variables d'environnement ci-dessus ne prennent pas effet, NODE_ENV affiche undefined🎜🎜🎜🎜Faites attention à l'ordre d'exécution des commandes exécutables dans le script, telles que <code>yarn && Yarn build && cross-env NODE_ENV= nœud de production dist/src/main
🎜🎜🎜 🎜Script dans le pré🎜🎜🎜🎜🎜Problème 2🎜 : Le mappage du nom de domaine en ligne frontal ne prend pas effet une fois que le fichier de configuration nginx mappe le nom de domaine en ligne. , on constate que lors de l'accès au nom de domaine en ligne, la page ne prend pas effet🎜🎜🎜Dépannage🎜 : Test nginx En comparant le fichier de configuration avec le fichier de configuration en ligne, nous avons constaté qu'à l'exception du nom de domaine et du proxy api, le contenu du fichier sont les mêmes. Alors, quelle est la raison ? Finalement, j'ai trouvé que le nom du suffixe du fichier de configuration nginx en ligne était erroné. Il était écrit comme xxx.confg. J'avais envie de me battre à mort🎜🎜🎜Solution🎜 : modifiez le fichier de configuration nginx en ligne avec le suffixe correct, ce qui. est xxx.conf suffixe🎜问题三: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 教程》
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!