BookNest has no image of its own until BookNest Dockerfile, but the official node:24-slim image can already run its source. A bind mount (Bind Mounts) makes the project directory, including the node_modules that npm 2,036 install created, appear at /app inside the container. The API reads its database host from PGHOST (Environment Variables and db/index.js), so pointing it at the postgres alias is the whole configuration:
docker run -d --name l3-api --network l3-booknest -v "$PWD/booknest:/app" -w /app \
-e PGHOST=postgres node:24-slim node server.js
sleep 3
docker logs l3-api
docker run --rm --network l3-booknest alpine:3 \
wget -qO- http://l3-api:3000/api/books/3 | cut -c 1-80ef8fa1e53b1fcf7d723b29d022f54fe2cbff7c639b632d723f86eded81263fe8
BookNest API listening on http://localhost:3000
{"id":3,"title":"Salt and Saffron","author":"Priya Nair","genre":"Cooking","pricOn start-up the API created the books table and loaded the six seed books into this fresh database, then answered a request from a third container that addressed it by name. None of the three containers publishes a port; this traffic never leaves the l3-booknest bridge, which is exactly how a database should be deployed.
Inside a container, localhost is the container itself, so the baseline default PGHOST=localhost would fail here with ECONNREFUSED. And if PostgreSQL 1,289 is still initializing when the API starts, db.init() fails and the process exits; Healthchecks fixes that ordering with a healthcheck.