How to Ensure an Express.js application container and PostgreSQL container work interactively with Interactive Terminal?

I have an Express.js application that takes input from the terminal and outputs data to the terminal interactively. For data storage, I am using PostgreSQL. The application needs to run interactively and should only start after the PostgreSQL container is properly running. I am using Docker Compose to manage the containers.

However, I am facing issues with the order of running containers. It seems like the Express.js app container is trying to start before the PostgreSQL container is ready, causing connection errors. Or it doesn’t work interactively.

How can I configure my docker-compose.yml file to ensure that the Express.js application waits for the PostgreSQL container to be fully operational before starting and it works interactively on terminal?

here is my docker-compose.yml file:

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

My Dockerfile:

FROM node:20

WORKDIR /myapp

COPY . .

RUN npm install

EXPOSE 3000

CMD [ "npm", "start" ]

If you think the code needs to be written in this question I will also add the code.

AFTER EDIT:
Now, it runs well. but it gets stuck here after I input 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

You have set the dependency on the postgres container as service_completed_successfully, but postgres never “completes” (it is a persistent service). You should be using the service_healthy dependency instead:

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

See “Control startup and shutdown order in Compose”” for complete documentation.

You probably want to tune your healthcheck a bit; the interval value defaults to 30 seconds so you’ll have to wait at least that long for the container to become healthy. Also, prefer CMD over CMD-SHELL unless you have a specific need to run a shell script. Something like this is perhaps more reasonable:

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

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật