我有一个 Express.js 应用程序,它从终端获取输入并将数据交互地输出到终端。对于数据存储,我使用 PostgreSQL。该应用程序需要交互运行,并且只能在 PostgreSQL 容器正常运行后启动。我正在使用 Docker Compose 来管理容器。
但是,我面临着容器运行顺序的问题。 Express.js 应用程序容器似乎试图在 PostgreSQL 容器准备就绪之前启动,从而导致连接错误。或者它无法交互工作。
如何配置 docker-compose.yml 文件以确保 Express.js 应用程序在启动之前等待 PostgreSQL 容器完全运行并在终端上以交互方式工作?
这是我的 docker-compose.yml 文件:
services:
postgresdb:
image: "postgres:latest"
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=root
- POSTGRES_DB=userinfo
container_name: postgresqldb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U root -d userinfo"]
timeout: 20s
retries: 10
app:
build: .
depends_on:
postgresdb:
condition: service_completed_successfully
stdin_open: true
tty: true
我的 Dockerfile:
FROM node:20
WORKDIR /myapp
COPY . .
RUN npm install
EXPOSE 3000
CMD [ "npm", "start" ]
如果你觉得这个问题需要写代码我也会添加代码。
您已将对 postgres 容器的依赖设置为
service_completed_successfully
,但 postgres 永远不会“完成”(它是一个持久服务)。您应该改用 service_healthy
依赖项:
services:
postgresdb:
image: "postgres:latest"
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=root
- POSTGRES_DB=userinfo
container_name: postgresqldb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U root -d userinfo"]
timeout: 20s
retries: 10
app:
build: .
depends_on:
postgresdb:
condition: service_healthy
stdin_open: true
tty: true
请参阅“在 Compose 中控制启动和关闭顺序””以获取完整文档。
您可能想稍微调整一下您的健康检查;
interval
值默认为 30 秒,因此您必须至少等待那么长时间容器才能正常运行。另外,除非您有运行 shell 脚本的特定需要,否则优先选择 CMD
而不是 CMD-SHELL
。这样的事情也许更合理:
services:
postgresdb:
image: "postgres:latest"
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=root
- POSTGRES_DB=userinfo
container_name: postgresqldb
healthcheck:
test: ["CMD", "pg_isready", "-U", "root", "-d", "userinfo"]
interval: 10s
timeout: 10s
retries: 3
app:
build: .
depends_on:
postgresdb:
condition: service_healthy
stdin_open: true
tty: true