我有一个 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", "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
我的 Dockerfile:
FROM node:20
WORKDIR /myapp
COPY . .
RUN npm install
EXPOSE 3000
CMD [ "npm", "start" ]
如果你觉得这个问题需要写代码我也会添加代码。
编辑后: 现在,它运行良好。但我输入后就卡在这里了
1
:
[+] Running 3/3
✔ Network bind-mounts_default Created 0.0s
✔ Container postgresqldb Created 0.0s
✔ Container bind-mounts-app-1 Created 0.0s
Attaching to bind-mounts-app-1, postgresqldb
postgresqldb | The files belonging to this database system will be owned by user "postgres".
postgresqldb | This user must also own the server process.
postgresqldb |
postgresqldb | The database cluster will be initialized with locale "en_US.utf8".
postgresqldb | The default database encoding has accordingly been set to "UTF8".
postgresqldb | The default text search configuration will be set to "english".
postgresqldb |
postgresqldb | Data page checksums are disabled.
postgresqldb |
postgresqldb | fixing permissions on existing directory /var/lib/postgresql/data ... ok
postgresqldb | creating subdirectories ... ok
postgresqldb | selecting dynamic shared memory implementation ... posix
postgresqldb | selecting default max_connections ... 100
postgresqldb | selecting default shared_buffers ... 128MB
postgresqldb | selecting default time zone ... Etc/UTC
postgresqldb | creating configuration files ... ok
postgresqldb | running bootstrap script ... ok
postgresqldb | performing post-bootstrap initialization ... ok
postgresqldb | initdb: warning: enabling "trust" authentication for local connections
postgresqldb | initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
postgresqldb | syncing data to disk ... ok
postgresqldb |
postgresqldb |
postgresqldb | Success. You can now start the database server using:
postgresqldb |
postgresqldb | pg_ctl -D /var/lib/postgresql/data -l logfile start
postgresqldb |
postgresqldb | waiting for server to start....2024-08-01 14:14:30.694 UTC [48] LOG: starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgresqldb | 2024-08-01 14:14:30.694 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgresqldb | 2024-08-01 14:14:30.696 UTC [51] LOG: database system was shut down at 2024-08-01 14:14:30 UTC
postgresqldb | 2024-08-01 14:14:30.699 UTC [48] LOG: database system is ready to accept connections
postgresqldb | done
postgresqldb | server started
postgresqldb | CREATE DATABASE
postgresqldb |
postgresqldb |
postgresqldb | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
postgresqldb |
postgresqldb | waiting for server to shut down...2024-08-01 14:14:30.851 UTC [48] LOG: received fast shutdown request
postgresqldb | .2024-08-01 14:14:30.853 UTC [48] LOG: aborting any active transactions
postgresqldb | 2024-08-01 14:14:30.855 UTC [48] LOG: background worker "logical replication launcher" (PID 54) exited with exit code 1
postgresqldb | 2024-08-01 14:14:30.855 UTC [49] LOG: shutting down
postgresqldb | 2024-08-01 14:14:30.855 UTC [49] LOG: checkpoint starting: shutdown immediate
postgresqldb | 2024-08-01 14:14:30.881 UTC [49] LOG: checkpoint complete: wrote 922 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.011 s, sync=0.014 s, total=0.026 s; sync files=301, longest=0.004 s, average=0.001 s; distance=4255 kB, estimate=4255 kB; lsn=0/1911FA0, redo lsn=0/1911FA0
postgresqldb | 2024-08-01 14:14:30.886 UTC [48] LOG: database system is shut down
postgresqldb | done
postgresqldb | server stopped
postgresqldb |
postgresqldb | PostgreSQL init process complete; ready for start up.
postgresqldb |
postgresqldb | 2024-08-01 14:14:30.968 UTC [1] LOG: starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgresqldb | 2024-08-01 14:14:30.969 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgresqldb | 2024-08-01 14:14:30.969 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgresqldb | 2024-08-01 14:14:30.970 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgresqldb | 2024-08-01 14:14:30.973 UTC [64] LOG: database system was shut down at 2024-08-01 14:14:30 UTC
postgresqldb | 2024-08-01 14:14:30.976 UTC [1] LOG: database system is ready to accept connections
bind-mounts-app-1 |
bind-mounts-app-1 | > [email protected] start
bind-mounts-app-1 | > node app.js
bind-mounts-app-1 |
bind-mounts-app-1 | Choose an option:
bind-mounts-app-1 | 1. Add a name to the DB
bind-mounts-app-1 | 2. Get all names from the DB
bind-mounts-app-1 | 3. Quit
bind-mounts-app-1 |
Enter your choice: Server is running on http://localhost:3000
1
postgresqldb | 2024-08-01 14:19:31.073 UTC [62] LOG: checkpoint starting: time
postgresqldb | 2024-08-01 14:19:35.393 UTC [62] LOG: checkpoint complete: wrote 45 buffers (0.3%); 0 WAL file(s) added, 0 removed, 0 recycled; write=4.306 s, sync=0.006 s, total=4.320 s; sync files=12, longest=0.005 s, average=0.001 s; distance=261 kB, estimate=261 kB; lsn=0/19533D8, redo lsn=0/19533A0
您已将对 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