无法获得 docker 集群模式与 nodejs 一起工作
Unable to get docker swarm mode working with nodejs
我正在尝试启动一个基本的 nodeJs 和 postgres 系统 运行 但由于某种原因,节点容器不断接收 SIGTERM 信号并关闭,只是为了重新启动备份策略然后再次关机。周而复始。
我在这里错过了什么?我 运行 在非 swarm 模式下使用相同的代码,它工作正常,容器很健康并且保持正常运行。我在 swarm 模式期间注意到的另一件事是,尽管要求 docker 保留 1 个副本,docker stack services service_name
总是 returns 0/1 个副本
在这里发布我的 dockerfile
和 docker-compose.yml
文件
# BASE stage
FROM node:14-alpine as base
ENV NODE_ENV production
WORKDIR /usr/src/app
COPY package.json ./
COPY yarn.lock ./
RUN yarn install --frozen-lockfile --prod
FROM node:14-alpine
ENV NODE_ENV development
ENV VERSION V1
WORKDIR /usr/src/app
RUN apk --no-cache add curl
COPY src src/
# Other copy commands
COPY --from=base /usr/src/app/node_modules /usr/src/app/node_modules
# check every 5s to ensure this service returns HTTP 200
HEALTHCHECK --interval=5s --timeout=3s --start-period=10s --retries=3 \
CMD curl -fs http://localhost/health
ENTRYPOINT [ "node", "src/index.js" ]
version: "3.7"
services:
api:
image: demo/hobby:v1
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 5
window: 120s
rollback_config:
parallelism: 1
delay: 20s
order: start-first
update_config:
parallelism: 1
delay: 1s
failure_action: rollback
order: start-first
env_file:
- ./.env
ports:
- target: 9200
published: 80
mode: host
networks:
- verse
postgres:
image: "postgres:12.3-alpine"
container_name: "test-db-dev"
networks:
- verse
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USER}
expose:
- "5432"
ports:
- "5432:5432"
restart: "unless-stopped"
networks:
verse:
driver: overlay
external: false
我假设您的容器每 30 秒被杀死一次。如果这是真的,那么这就是原因:
HEALTHCHECK
正在尝试 curl http://localhost/health(默认端口 80)。
尽管您在端口 80
上将应用程序公开给主机,但 HEALTHCHECK
是从容器的角度执行的,其中没有服务正在侦听该端口。
假设您的节点应用程序正在侦听端口 9200 并且 GET
在 /health
returns 状态 200
上执行,Dockerfile
应该是像这样建造:
[...]
HEALTHCHECK --interval=5s --timeout=3s --start-period=10s --retries=3 \
CMD curl -fs http://localhost:9200/health
[...]
我正在尝试启动一个基本的 nodeJs 和 postgres 系统 运行 但由于某种原因,节点容器不断接收 SIGTERM 信号并关闭,只是为了重新启动备份策略然后再次关机。周而复始。
我在这里错过了什么?我 运行 在非 swarm 模式下使用相同的代码,它工作正常,容器很健康并且保持正常运行。我在 swarm 模式期间注意到的另一件事是,尽管要求 docker 保留 1 个副本,docker stack services service_name
总是 returns 0/1 个副本
在这里发布我的 dockerfile
和 docker-compose.yml
文件
# BASE stage
FROM node:14-alpine as base
ENV NODE_ENV production
WORKDIR /usr/src/app
COPY package.json ./
COPY yarn.lock ./
RUN yarn install --frozen-lockfile --prod
FROM node:14-alpine
ENV NODE_ENV development
ENV VERSION V1
WORKDIR /usr/src/app
RUN apk --no-cache add curl
COPY src src/
# Other copy commands
COPY --from=base /usr/src/app/node_modules /usr/src/app/node_modules
# check every 5s to ensure this service returns HTTP 200
HEALTHCHECK --interval=5s --timeout=3s --start-period=10s --retries=3 \
CMD curl -fs http://localhost/health
ENTRYPOINT [ "node", "src/index.js" ]
version: "3.7"
services:
api:
image: demo/hobby:v1
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 5
window: 120s
rollback_config:
parallelism: 1
delay: 20s
order: start-first
update_config:
parallelism: 1
delay: 1s
failure_action: rollback
order: start-first
env_file:
- ./.env
ports:
- target: 9200
published: 80
mode: host
networks:
- verse
postgres:
image: "postgres:12.3-alpine"
container_name: "test-db-dev"
networks:
- verse
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=${DB_USER}
expose:
- "5432"
ports:
- "5432:5432"
restart: "unless-stopped"
networks:
verse:
driver: overlay
external: false
我假设您的容器每 30 秒被杀死一次。如果这是真的,那么这就是原因:
HEALTHCHECK
正在尝试 curl http://localhost/health(默认端口 80)。
尽管您在端口 80
上将应用程序公开给主机,但 HEALTHCHECK
是从容器的角度执行的,其中没有服务正在侦听该端口。
假设您的节点应用程序正在侦听端口 9200 并且 GET
在 /health
returns 状态 200
上执行,Dockerfile
应该是像这样建造:
[...]
HEALTHCHECK --interval=5s --timeout=3s --start-period=10s --retries=3 \
CMD curl -fs http://localhost:9200/health
[...]