无法获得 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 个副本

在这里发布我的 dockerfiledocker-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

[...]