A well-behaved container logs to standard output and error. Docker 514 captures both through its logging driver (json-file by default, Logging Drivers), and docker logs replays them, even after the container stops. -t adds Docker's timestamps, --since 10m bounds the output by time, and -f follows new lines live. Here a background docker logs -f -n 0 watches while a failed login happens:
docker logs -t l3-postgres 2>&1 | grep 'ready to accept' | cut -c 1-90
timeout 4 docker logs -f -n 0 l3-postgres &
sleep 1
docker exec l3-postgres psql -U nobody -c 'SELECT 1' 2>/dev/null
wait2026-09-25T08:47:24.995842425Z 2026-09-25 08:47:24.995 UTC [53] LOG: database system is r 2026-09-25T08:47:25.502981543Z 2026-09-25 08:47:25.502 UTC [1] LOG: database system is re 2026-09-25 08:47:30.817 UTC [92] FATAL: role "nobody" does not exist
PostgreSQL 1,289 logs to standard error, which docker logs keeps separate, hence 2>&1 before grep. The server became ready twice: first a temporary server the entrypoint uses for initialization (PID 53), then the real one as PID 1. The temporary server listens only on the Unix socket, so a readiness check run inside the container can pass too early; Healthchecks allows for that. Interactively, stop following with Ctrl+C, which never stops the container. The default driver never rotates logs; set max-size and max-file in daemon.json (daemon.json).