Wie stellt man KnotenDienste über Docker-Compose in mehreren Umgebungen bereit? Der folgende Artikel stellt Ihnen vor, wie Sie Node-Dienste in mehreren Umgebungen mit Docker-Compose bereitstellen. Ich hoffe, er wird Ihnen helfen!
Im Allgemeinen muss unser Projekt nach der Entwicklung in mehreren Umgebungen bereitgestellt werden, z. B. zum Testen, in der Sandbox, in der Integration usw. Wie stellt man also Knotendienste über Docker-Compose in mehreren Umgebungen bereit? Der folgende Artikel erklärt es im Detail. Wenn etwas nicht stimmt, können Sie gerne einen Kommentar abgeben.
Die im Projekt in diesem Artikel verwendete Technologie ist Gitlab+Ansible+DockerAutomatisierte Bereitstellung von Knotendiensten (geschrieben vom Nest Framework). Die Schritte sind wie folgt:
Schreiben Sie Docker-Compose und Docker-Compose. prod.yml-Konfigurationsdateien
Paket.json ändern
Erstellen Sie zwei Verzeichnisse auf dem Remote-Server, rufen Sie das Node Service Warehouse ab und wechseln Sie zu verschiedenen Zweigen, die jeweils Test- und Online-Knotendienste darstellen
.gitlab -ci.yml-Datei Schreiben Sie die Datei
ansible.yml und führen Sie den folgenden Befehl im Verzeichnis des Remote-Server-Knotendienstes (Test/Online) aus. Überprüfen Sie nach der Ausführung, ob der Container normal startet, über docker ps -a
Wenn es im aktiven Zustand hängt, beweist es, dass der Container erfolgreich gestartet wurde. docker logs -f container id
Containerprotokolle anzeigen
# 测试目录 /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
Erstellen Sie zwei Verzeichnisse auf dem Remote-Server, um Tests bzw. Online-Knotendienste zu speichern rrreee
Ansible.yml-Datei schreiben
🎜rrreee🎜🎜🎜Führen Sie den folgenden Befehl im Verzeichnis des Remote-Serverknotendienstes (Test/Online) aus🎜🎜🎜rrreee🎜Übergeben Sie nach erfolgreichem Startdocker ps -a </ code>Überprüfen Sie den Startstatus des Containers, wie in der folgenden Abbildung dargestellt: 🎜🎜<img src="https://img.php.cn/upload/image/795/886/918/1643363755384508.png" title= "1643363755384508.png " alt="Lassen Sie uns darüber sprechen, wie Sie Knotendienste über Docker-Compose in mehreren Umgebungen bereitstellen"/>🎜🎜🎜Hinweis🎜:🎜<ul>🎜🎜Testumgebung: Wenn der lokale Entwicklungszweigcode übermittelt wird oder andere Zweige mit dem Entwicklungszweig zusammengeführt werden, wird der Knotendienst verwendet Wird automatisch über itlab CI und den Ansible-Remote-Server bereitgestellt, wechseln Sie die Zweige im Remote-Verzeichnis des entsprechenden Servers, rufen Sie den neuesten Code ab und starten Sie den entsprechenden Test-Docker-Container neu. Online-Umgebung: Wenn der lokale Master-Branch-Code vorhanden ist Wenn übermittelte oder andere Zweige in den Hauptzweig zusammengeführt werden, wird er über itlab CI verarbeitet. Ansible stellt Knotendienste automatisch auf Remote-Servern bereit, wechselt Zweige im Remote-Verzeichnis des entsprechenden Servers, ruft den neuesten Code ab und startet den entsprechenden Online-Docker neu Container🎜🎜🎜<h2>Aufgetretene Probleme</h2>🎜🎜Problem 1🎜: Es gibt kein node_modules-Verzeichnis und kein dist-Verzeichnis im Test-/Online-Remote-Node-Service-Verzeichnis, das heißt, es gibt keine zwei Dateien, wie unten gezeigt Gleichzeitig wird beim Anzeigen des Docker-Container-Protokolls auf dem Remote-Server der folgende Fehler gemeldet (🎜Die Lösung dieses Problems hat lange gedauert🎜)🎜🎜< img src="https://img.php.cn/upload /image/836/140/889/1643363760218636.png" title="1643363760218636.png" alt="Lassen Sie uns darüber sprechen, wie Sie Knotendienste über Docker-Compose in mehreren Umgebungen bereitstellen"/>🎜🎜<img src= "https://img.php.cn/upload/image/ 770/228/862/164336376434247Lassen Sie uns darüber sprechen, wie Sie Knotendienste über Docker-Compose in mehreren Umgebungen bereitstellen" title="164336376434247Lassen Sie uns darüber sprechen, wie Sie Knotendienste über Docker-Compose in mehreren Umgebungen bereitstellen" alt="Lassen Sie uns darüber sprechen, wie Sie Knotendienste über Docker-Compose in mehreren Umgebungen bereitstellen"/>🎜🎜🎜Fehlerbehebung: 🎜 Gefunden und normal Beim Vergleich der gestarteten Knotendienstcontainer gibt es keine dieser beiden Verzeichnisse (dist Überprüfen Sie, ob beim Befehlsausführungsbefehl in docker-compose.yml ein Problem vorliegt, d Ich habe versucht, die Garnoperation in package.json einzufügen, und das Ergebnis war in Ordnung. 🎜🎜🎜Lösung: 🎜🎜rrreee🎜🎜Hinweis🎜: Der Speicherort von 🎜🎜🎜🎜cross-env wird vor dem ausführbaren Befehl platziert. Der Server meldet, dass „cross-env“ nicht gefunden wurde. und am Ende platziert. Die oben genannten Umgebungsvariablen werden nicht wirksam, NODE_ENV zeigt undefiniert an🎜🎜🎜🎜Achten Sie auf die Reihenfolge der Ausführung ausführbarer Befehle im Skript, z Produktionsknoten dist/src/main
🎜🎜🎜 🎜Skript in pre🎜🎜🎜🎜🎜Problem 2🎜: Die Front-End-Online-Domänennamenzuordnung wird nicht wirksam, nachdem die Nginx-Konfigurationsdatei den Online-Domänennamen zugeordnet hat Es wurde festgestellt, dass die Seite beim Zugriff auf den Online-Domainnamen nicht wirksam wird🎜🎜🎜Fehlerbehebung🎜: Nginx testen Beim Vergleich der Konfigurationsdatei mit der Online-Konfigurationsdatei haben wir festgestellt, dass der Inhalt mit Ausnahme des Domainnamens und des API-Proxys nicht vorhanden ist der Datei sind gleich. Was ist der Grund? Schließlich stellte ich fest, dass der Suffixname der Online-Nginx-Konfigurationsdatei falsch war. Er wurde als xxx.confg geschrieben. Ich wollte mich hier umbringen🎜🎜🎜Lösung🎜: Ändern Sie die Online-Nginx-Konfigurationsdatei in das richtige Suffix xxx. conf-Suffix🎜问题三: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 教程》
Das obige ist der detaillierte Inhalt vonLassen Sie uns darüber sprechen, wie Sie Knotendienste über Docker-Compose in mehreren Umgebungen bereitstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!