iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Define the web app, PostgreSQL, and Redis as services in one compose.yaml. Connect the app to the other services by their Compose names—db and redis—and use healthchecks with condition: service_healthy when the app must wait for them to become ready. Store PostgreSQL data in a named volume so it survives container removal.
Write the Compose file
Save this template as compose.yaml in your project directory. Replace the web build context, app-specific environment variables, image tags, and credentials with values compatible with your application. The image tags are examples, not universal version recommendations.
services:
web:
build: .
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://app:${POSTGRES_PASSWORD}@db:5432/app
REDIS_URL: redis://redis:6379
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
db:
image: postgres:18
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
redis:
image: redis:alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
volumes:
postgres_data:
How the services connect
Compose provides a network for services in the project. From inside the web container, use the service names db and redis as hostnames, with the ports those services listen on inside their containers. Do not use localhost for these connections: inside the web container, that refers to the web container itself. The published mapping 8000:8000 makes the web service’s port available on the host; it is separate from the internal database and Redis connections. See Docker’s Compose Quickstart.
The connection-string formats and environment-variable names are illustrative. Adapt them to the framework and application; some apps expect separate host, port, database, or credential settings instead of these URLs.
#1 Best Overall
What the healthchecks do
The PostgreSQL probe runs pg_isready using the configured database user and database name. The Redis probe runs redis-cli ping. Docker’s startup-order guide uses pg_isready, and its Quickstart demonstrates the Redis probe.
The doubled dollar signs in $${POSTGRES_USER} and $${POSTGRES_DB} prevent Compose from expanding those variables on the host. The shell running inside the PostgreSQL container expands them when it executes the healthcheck.
Why startup order is not the same as readiness
Short-form depends_on starts dependencies before the dependent service, but does not wait for them to become ready. The long-form conditions in the template make Compose wait for each dependency’s configured healthcheck to succeed before starting web. Docker’s Compose service reference explains that dependencies marked service_healthy must be healthy before the dependent service starts.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
A healthy result means only that the configured probe succeeded within its timing settings. It does not confirm that database migrations have run, credentials work for every app operation, or the web service can complete its required queries. Applications should still handle connection failures and retries where appropriate.
Set credentials without committing secrets
The example uses ${POSTGRES_PASSWORD} so the value can be supplied through Compose interpolation rather than written directly into the Compose file. For local development, keep real credentials in a local environment file excluded from version control, or use a secrets mechanism suitable for the target environment. Docker’s Node.js guide demonstrates Compose secrets. The right approach depends on how and where you deploy.
Start the stack and inspect it
-
From the directory containing
compose.yaml, rundocker compose up --build. Compose builds the web image and starts the services; the web service waits for the configured database and Redis healthchecks. -
Check service state with
docker compose ps. To follow service output, rundocker compose logs -f web db redis.Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy. -
When you want to stop the stack and remove its containers and default network, run
docker compose down.
If a service does not become healthy, inspect its logs and health status, then check that the image, command, credentials, and probe match your chosen versions and configuration. A successful probe is not a substitute for checking application logs or verifying database schema and app behavior.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Choose what should happen to data
PostgreSQL: keep the named volume
The postgres_data named volume stores PostgreSQL files outside the database container’s lifecycle. Removing and recreating the container with docker compose down leaves that volume in place. Avoid adding -v to the command if you want to retain named-volume data; removing volumes deletes their persisted contents. Docker’s Quickstart demonstrates named-volume persistence.
PostgreSQL initialization settings apply to an empty data directory
The official PostgreSQL image documentation states that initialization environment variables apply when the data directory is empty. Changing POSTGRES_USER, POSTGRES_PASSWORD, or POSTGRES_DB after a volume already contains a database does not reinitialize that database or update its existing credentials.
Recommended Free Tools
The image also processes initialization files during initial database creation. If an initialization script fails after the data directory has been initialized, restarting the container does not automatically resume the remaining scripts. Diagnose and correct the failure, then choose a deliberate recovery process for the existing data rather than assuming the scripts will rerun.
Best Value
- Docker, Docker Swarm, Docker Compose, Programmer, Developer, Coding, Programming, Software Engineer, Code, DevOps, Deploy, Deployment, Kubernetes, Salt, Puppet, Chef, Terraform, Container, AWS, Azure, Cloud, Geek, Funny, Computer, Software, Tech, IT
- Integration, Scrum, Compile, Compilation, Science, Bug, Debug, Python, Linux, Java, Javascript, Scala, Dotnet, Kotlin
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
Redis: decide whether its data is disposable
This template treats Redis as a service without a data volume. That can suit a rebuildable cache, but not necessarily a queue or a store whose contents must survive container replacement. A volume by itself does not define an appropriate Redis persistence policy: decide what data must survive, how Redis should be configured to persist it, and what backup or recovery expectations apply. The Compose Quickstart shows a named volume mounted at /data, but the appropriate setup depends on Redis’s role in your application.
Check versions and deployment scope
Choose PostgreSQL and Redis image tags that your application supports and that fit the deployment target. Confirm framework compatibility, database migration constraints, and any required server-version support before adopting tutorial tags.
This Compose file is a starting point for running services together, not a complete production design. Security, backups, high availability, monitoring, and disaster recovery need decisions based on the actual deployment environment.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

