Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

  1. From the directory containing compose.yaml, run docker compose up --build. Compose builds the web image and starts the services; the web service waits for the configured database and Redis healthchecks.

  2. Check service state with docker compose ps. To follow service output, run docker compose logs -f web db redis.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  3. 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.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 Container Linux Devops Programming Coding T-Shirt
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.