🔥 0
0
Lesson 6 of 10 20 min +125 XP

Connecting Store Services

Real e-commerce apps have multiple services: product API, user service, cart, database, cache. These need to communicate. Docker networking makes this seamless.

The Problem

Run two containers:

docker run -d --name api-container nginx
docker run -d --name db-container postgres:15

Can api-container connect to db-container? Not easily on the default network.

Docker Networks

Docker networks let containers communicate securely:

┌─────────────────────────────────────────────────┐
│              shopflow-network                    │
│                                                  │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐    │
│  │ product  │   │   cart   │   │ postgres │    │
│  │   api    │◄──│ service  │──►│    db    │    │
│  └──────────┘   └──────────┘   └──────────┘    │
│                                                  │
│  Containers communicate by name:                 │
│  "postgres://shopflow-db:5432"                  │
│  "http://product-api:3000"                      │
└─────────────────────────────────────────────────┘

Create a Network

# Create a bridge network for our e-commerce app
docker network create shopflow-network
Output:
a1b2c3d4e5f6g7h8i9j0...

List networks:

docker network ls
Output:
NETWORK ID     NAME               DRIVER    SCOPE
abc123...      bridge             bridge    local
def456...      host               host      local
ghi789...      shopflow-network   bridge    local

Connect Containers to a Network

Method 1: At Creation Time

# Start database on our network
docker run -d \
  --name shopflow-db \
  --network shopflow-network \
  -e POSTGRES_USER=shopflow \
  -e POSTGRES_PASSWORD=secretpass \
  -e POSTGRES_DB=shopflow \
  postgres:15

# Start Redis cache on same network
docker run -d \
  --name shopflow-cache \
  --network shopflow-network \
  redis:7-alpine

Method 2: Connect Existing Container

# Start a container (default network)
docker run -d --name product-api nginx

# Connect it to our network
docker network connect shopflow-network product-api

Service Communication Example

Let's create a complete e-commerce network setup:

1. Create the network:
docker network create shopflow-network
2. Start PostgreSQL:
docker run -d \
  --name shopflow-db \
  --network shopflow-network \
  -e POSTGRES_USER=shopflow \
  -e POSTGRES_PASSWORD=secretpass \
  -e POSTGRES_DB=shopflow \
  postgres:15
3. Start Redis:
docker run -d \
  --name shopflow-cache \
  --network shopflow-network \
  redis:7-alpine
4. Create a Product API that connects to both:

Create test-api/server.js:

const express = require('express');
const { Pool } = require('pg');
const Redis = require('ioredis');

const app = express();

// Connect to PostgreSQL using container name as host
const db = new Pool({
  host: 'shopflow-db',        // Container name!
  port: 5432,
  user: 'shopflow',
  password: 'secretpass',
  database: 'shopflow'
});

// Connect to Redis using container name
const cache = new Redis({
  host: 'shopflow-cache',     // Container name!
  port: 6379
});

app.get('/health', async (req, res) => {
  try {
    // Test database connection
    await db.query('SELECT 1');

    // Test cache connection
    await cache.ping();

    res.json({
      status: 'healthy',
      database: 'connected',
      cache: 'connected'
    });
  } catch (err) {
    res.status(500).json({
      status: 'unhealthy',
      error: err.message
    });
  }
});

app.get('/api/products', async (req, res) => {
  // Try cache first
  const cached = await cache.get('products');
  if (cached) {
    return res.json({ source: 'cache', products: JSON.parse(cached) });
  }

  // Query database
  const result = await db.query('SELECT * FROM products');

  // Cache for 60 seconds
  await cache.setex('products', 60, JSON.stringify(result.rows));

  res.json({ source: 'database', products: result.rows });
});

app.listen(3000, () => {
  console.log('Product API running on port 3000');
});
5. Build and run the API:
docker build -t shopflow/product-api:1.0 .

docker run -d \
  --name product-api \
  --network shopflow-network \
  -p 3000:3000 \
  shopflow/product-api:1.0

DNS Resolution in Action

Inside any container on the network, hostnames resolve automatically:

# Enter the product-api container
docker exec -it product-api sh

# Ping the database by name
ping shopflow-db

# Ping the cache by name
ping shopflow-cache
Output:
PING shopflow-db (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.089 ms

Docker's internal DNS resolved shopflow-db to 172.18.0.2.

Inspect the Network

docker network inspect shopflow-network
Output:
{
  "Name": "shopflow-network",
  "Driver": "bridge",
  "Containers": {
    "abc123...": {
      "Name": "shopflow-db",
      "IPv4Address": "172.18.0.2/16"
    },
    "def456...": {
      "Name": "shopflow-cache",
      "IPv4Address": "172.18.0.3/16"
    },
    "ghi789...": {
      "Name": "product-api",
      "IPv4Address": "172.18.0.4/16"
    }
  }
}

Network Isolation

Containers on different networks can't communicate:

# Create a separate network
docker network create admin-network

# Start admin service on admin network
docker run -d \
  --name admin-panel \
  --network admin-network \
  nginx

# admin-panel CANNOT reach shopflow-db
# shopflow services CANNOT reach admin-panel

This is useful for security - isolate admin tools from customer-facing services.

Multiple Networks

A container can be on multiple networks:

# Connect admin panel to both networks
docker network connect shopflow-network admin-panel

# Now admin-panel can reach both networks

Complete E-commerce Network

Here's a typical setup:

# Create networks
docker network create frontend-net
docker network create backend-net
docker network create data-net

# Database only on data network (most secure)
docker run -d --name shopflow-db --network data-net postgres:15

# API connects to backend and data
docker run -d --name product-api --network backend-net product-api:1.0
docker network connect data-net product-api

# Frontend connects to backend only
docker run -d --name web-store --network frontend-net -p 80:80 nginx
docker network connect backend-net web-store
┌─────────────────────────────────────────────────────────┐
│  frontend-net                                            │
│  ┌───────────┐                                          │
│  │ web-store │──────────┐                               │
│  │   :80     │          │                               │
│  └───────────┘          │                               │
└─────────────────────────┼───────────────────────────────┘
                          │
┌─────────────────────────┼───────────────────────────────┐
│  backend-net            ▼                                │
│               ┌─────────────────┐                       │
│               │   product-api   │──────────┐            │
│               │      :3000      │          │            │
│               └─────────────────┘          │            │
└────────────────────────────────────────────┼────────────┘
                                             │
┌────────────────────────────────────────────┼────────────┐
│  data-net                                  ▼            │
│                              ┌─────────────────┐        │
│                              │   shopflow-db   │        │
│                              │     :5432       │        │
│                              └─────────────────┘        │
└─────────────────────────────────────────────────────────┘

Connection String Patterns

In your app code, use container names:

PostgreSQL:
const connectionString = 'postgresql://shopflow:secretpass@shopflow-db:5432/shopflow';
Redis:
const redisUrl = 'redis://shopflow-cache:6379';
Another API:
const productApiUrl = 'http://product-api:3000/api/products';

Cleanup

# Remove containers
docker rm -f product-api shopflow-db shopflow-cache

# Remove network
docker network rm shopflow-network

# Remove all unused networks
docker network prune

Key Takeaways

  • docker network create makes isolated networks
  • Containers on the same network use names as hostnames
  • --network connects at creation, network connect adds later
  • Networks provide isolation and security
  • Use multiple networks to segment your architecture

Next, let's learn about volumes to persist our product data!

🧠 Quick Quiz

Test your understanding of this lesson.

1

How do containers on the same Docker network communicate?

2

What's the advantage of user-defined networks over the default bridge?

3

In 'docker network create shopflow-net', what is 'shopflow-net'?

Building the Product API Image