Skip to main content

Command Palette

Search for a command to run...

🐳Docker Networking, Volumes & Compose for DevOps (Part 3) - Day 13 šŸŒšŸš€

Running Stateful, Multi-Container Apps in Production

Updated
•4 min read
🐳Docker Networking, Volumes & Compose for DevOps (Part 3) - Day 13 šŸŒšŸš€
D

DevOps/Cloud Engineer focused on building, automating, and scaling cloud native systems. I write about Linux, CI/CD pipelines, Docker, Terraform, Kubernetes, and AWS, sharing practical insights from real-world DevOps workflows.

Why This Matters in Production

So far, we have learned how to build Docker images and run containers. But real applications don’t live in isolation.

In production:
• Services must talk to each other
• Data must survive container restarts
• Multiple services must start, stop, and scale together

This is where Docker Networking, Volumes, and Docker Compose become essential DevOps skills.

A. Docker Networking - How Containers Talk

Problem: You run two containers (app + database), but they cannot communicate using localhost.

Why This Happens Each container has its own network namespace. localhost inside a container ≠ host machine.

Action: Understand Docker Network Types

Command: docker network ls

Common networks:
bridge (default, most common)
host
none
custom bridge (recommended)

A-1. Create a Custom Bridge Network (Best Practice for multi-container applications)

Command: docker network create app-network

Run containers on the same network:
docker run -d --name db --network app-network mysql:8

docker run -d --name backend --network app-network busybox sleep 3600

Test DB Connectivity:

Now:
• Backend can connect to db using hostname db
• No IPs required

Key Takeaway: Always use custom bridge networks for service-to-service communication.

B. Docker Volumes, Persisting Data Safely

Problem: You restart or recreate a container and all data is lost.

Why This Happens
• Containers are ephemeral by design.
• Filesystem inside a container is destroyed when it stops.

Action: Use Docker Volumes

Create a Volume:
docker volume create mysql-data

Attach it to a container:
docker run -d --name mysql -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=rootpass -e MYSQL_DATABASE=appdb mysql:8
#Verify the DB (appdb)

Now:
• Data survives restarts
• Data survives container recreation

Inspect Volumes:
docker volume inspect mysql-data

Test Persistence:

#Stop and Remove the container

#Run a New Container Using the Same Volume

Our database and data are still intact, because the volume stores it outside the container.

Key Takeaway: Use Docker volumes for databases and persistent data in production.

C. Docker Compose, Managing Multi-Service Apps

Problem: Running multiple containers manually is:
• Error-prone
• Hard to reproduce
• Not scalable

Action: Use Docker Compose
Docker Compose lets you define your entire application stack in a single YAML file.

Example: Production-Style App Stack
Services:
• Backend API
• MySQL database

docker-compose.yml

version: "3.9"
services:
db:
image: mysql:8
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: appdb

volumes:

  • mysql-data:/var/lib/mysql
    networks:
  • app-network

backend:
build: .
container_name: backend-api
ports:

  • "8080:8080"
    depends_on:
  • db
    networks:
  • app-network
    volumes:
    mysql-data:
    networks:
    app-network:

#Run the entire stack:
docker compose up -d

In the image below, we are getting an error stating that the port is already allocated. We can see that the port is assigned to the ā€œapache containerā€, which is why it failed.

Solution: Stop the apache-container, and the 8080 port will automatically become free, allowing us to use it.

If you look at the image below, the ā€œbackend-apiā€ container is still not running due to a port conflict. Although we have resolved the port conflict, it still prevented the ā€œbackend-apiā€ from starting, which is why it is not showing in docker ps

Use the command: docker ps -a (To see all containers, whether exited, running, or in any other state)

Fix the issue:
Change the host port from 8080 to 8081, Edit docker-compose.yml:

#Stop everything:
docker compose down

#View Logs:
docker compose logs -f

Again, we can bring up the entire stack using: docker compose up -d --build.

Why depends_on Matters:
• Ensures DB starts before backend
• Prevents startup race conditions

Key Takeaway: Docker Compose is the standard way to run multi-service applications locally and in staging.

D. Production Observability

#Check Running Containers:
docker compose ps

#Inspect Network:
docker network inspect app-network

#Monitor Resource Usage
docker stats

Actual DevOps Workflow:

• Build images locally
• Use Compose for local + staging
• Push images to registry
• Deploy to Kubernetes / ECS later

Topic’s Covered Today:

• Docker Networking - How Containers Talk
• Docker Volumes, Persisting Data Safely
• Docker Compose, Managing Multi-Service Apps
• Production Observability