Skip to content

thara/docker-compose-network-playground

Repository files navigation

Docker Compose Network Playground

A hands-on demonstration of Docker Compose networking concepts featuring multiple services with public and private endpoints, showcasing inter-service communication patterns and network isolation principles.

🎯 Purpose

This playground helps you understand:

  • Docker Compose multi-service architecture
  • Network isolation and communication patterns
  • Service discovery and inter-service communication
  • Public vs private endpoint concepts
  • Container orchestration best practices

πŸ—οΈ Architecture

graph TB
    subgraph "Host System"
        subgraph "Service 1"
            S1PUB[Public Container<br/>service1<br/>Port: 8001:8080]
            S1PRIV[Private Container<br/>service1-private<br/>No external port]
            S1PUB --> S1PE[Public Endpoints<br/>/health<br/>/public/echo<br/>/call-others]
            S1PRIV --> S1PV[Private Endpoint<br/>/private/info]
        end
        
        subgraph "Service 2"
            S2PUB[Public Container<br/>service2<br/>Port: 8002:8080]
            S2PRIV[Private Container<br/>service2-private<br/>No external port]
            S2PUB --> S2PE[Public Endpoints<br/>/health<br/>/public/echo<br/>/call-others]
            S2PRIV --> S2PV[Private Endpoint<br/>/private/info]
        end
        
        subgraph "Service 3"
            S3PUB[Public Container<br/>service3<br/>Port: 8003:8080]
            S3PRIV[Private Container<br/>service3-private<br/>No external port]
            S3PUB --> S3PE[Public Endpoints<br/>/health<br/>/public/echo<br/>/call-others]
            S3PRIV --> S3PV[Private Endpoint<br/>/private/info]
        end
    end
    
    subgraph "External Access"
        HOST[Host Machine<br/>localhost:8001-8003]
    end
    
    %% Public network connections shown through inter-service communication arrows
    
    %% Inter-service communication (public only)
    S1PE -.->|HTTP calls| S2PE
    S1PE -.->|HTTP calls| S3PE
    S2PE -.->|HTTP calls| S1PE
    S2PE -.->|HTTP calls| S3PE
    S3PE -.->|HTTP calls| S1PE
    S3PE -.->|HTTP calls| S2PE
    
    %% Same-service private connections (allowed)
    S1PE -.->|Internal Access| S1PV
    S2PE -.->|Internal Access| S2PV
    S3PE -.->|Internal Access| S3PV
    
    %% Host access
    HOST -->|8001| S1PUB
    HOST -->|8002| S2PUB
    HOST -->|8003| S3PUB
    
    %% Styling
    classDef serviceBox fill:#b3e5fc,stroke:#0277bd,stroke-width:3px,color:#000000
    classDef privateContainer fill:#ffeb3b,stroke:#f57f17,stroke-width:3px,color:#000000
    classDef endpointBox fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px,color:#000000
    classDef privateBox fill:#ffccbc,stroke:#d84315,stroke-width:2px,color:#000000
    
    class S1PUB,S2PUB,S3PUB serviceBox
    class S1PRIV,S2PRIV,S3PRIV privateContainer
    class S1PE,S2PE,S3PE endpointBox
    class S1PV,S2PV,S3PV privateBox
Loading

Note: The diagram shows only allowed connections. Cross-service private endpoints (e.g., service1 β†’ service2-private) are blocked by network isolation and cannot communicate.

πŸš€ Quick Start

Prerequisites

  • Docker and Docker Compose installed
  • curl and jq (optional, for testing)

1. Start the Environment

./start.sh

This will:

  • Create Docker networks
  • Build and start all services
  • Verify services are healthy
  • Display service endpoints

2. Test the Services

# Run comprehensive tests
./test.sh

# Or test manually
curl http://localhost:8001/health
curl http://localhost:8001/public/echo
curl http://localhost:8001/call-others | jq '.'

3. Stop the Environment

./stop.sh

# Or with cleanup
./stop.sh --clean

πŸ“š Available Endpoints

Public Endpoints (accessible from other services)

  • GET /health - Health check
  • GET/POST /public/echo - Echo service with request data
  • GET /call-others - Test inter-service communication

Private Endpoints (network isolation concept)

  • GET /private/info - Returns sensitive service information

πŸ”¬ What You'll Learn

1. Inter-Service Communication

curl http://localhost:8001/call-others

This endpoint demonstrates:

  • How services discover and communicate with each other
  • DNS resolution within Docker networks
  • Success/failure patterns in distributed systems
  • Same-service private access (βœ… service1 β†’ service1-private)
  • Cross-service isolation (❌ service1 β†’ service2-private)

2. Network Isolation Concepts

The /private/info endpoints demonstrate:

  • True network isolation: Private containers are on separate networks
  • Access control: Public containers return 404 for private endpoints
  • Cross-service blocking: Private endpoints unreachable from other services
  • Educational value: Shows real Docker network isolation in action

3. Service Health Monitoring

curl http://localhost:8001/health
curl http://localhost:8002/health  
curl http://localhost:8003/health

4. Structured API Responses

All endpoints return consistent JSON format:

{
  "service": "service1",
  "endpoint": "/health",
  "timestamp": "2024-01-01T12:00:00Z",
  "data": {
    "status": "healthy",
    "ports": { "public": 8080, "private": 8081 }
  }
}

πŸ§ͺ Testing Scenarios

Manual Testing

# Test service health
curl http://localhost:8001/health

# Test public endpoints
curl http://localhost:8002/public/echo?message=hello

# Test inter-service communication
curl http://localhost:8003/call-others

# Test network isolation (should return 404)
curl http://localhost:8002/private/info

# POST request example
curl -X POST http://localhost:8001/public/echo \
  -H "Content-Type: application/json" \
  -d '{"test": "data"}'

Automated Testing

# Run all tests
./test.sh

# View service logs (shows both public and private containers)
docker-compose -f docker-compose.service1.yml logs -f

πŸ“ Project Structure

.
β”œβ”€β”€ README.md                     # This file
β”œβ”€β”€ REQUIREMENTS.md               # Detailed requirements
β”œβ”€β”€ CLAUDE.md                     # Development guidance
β”œβ”€β”€ docker-compose.networks.yml   # Shared public network definition
β”œβ”€β”€ docker-compose.service1.yml   # Service 1 configuration
β”œβ”€β”€ docker-compose.service2.yml   # Service 2 configuration
β”œβ”€β”€ docker-compose.service3.yml   # Service 3 configuration
β”œβ”€β”€ start.sh                      # Environment startup script
β”œβ”€β”€ stop.sh                       # Environment shutdown script
β”œβ”€β”€ test.sh                       # Automated testing script
β”œβ”€β”€ logs/                         # Log files directory
└── service[1-3]/                 # Service implementation
    β”œβ”€β”€ app.py                    # Flask application
    β”œβ”€β”€ requirements.txt          # Python dependencies
    └── Dockerfile                # Container definition

πŸ› οΈ Development

Adding New Services

  1. Create new service directory
  2. Copy and modify existing service files
  3. Create corresponding docker-compose.serviceN.yml
  4. Update network configurations
  5. Test inter-service communication

Modifying Endpoints

Edit the Flask applications in service*/app.py:

  • Follow existing endpoint patterns
  • Maintain consistent JSON response format
  • Add appropriate logging

Network Isolation

The current implementation demonstrates true network isolation:

  1. Shared public network: Defined in docker-compose.networks.yml (external)
  2. Private networks: Each service creates its own private network
  3. Public containers: Connected to both public_network and their own service_private
  4. Private containers: Connected only to their service-specific private network
  5. APP_MODE environment variable: Controls endpoint availability per container
  6. Result: Private endpoints truly isolated at the network level

πŸ” Monitoring

View Logs

# All services (public and private containers)
docker-compose -f docker-compose.service1.yml logs
docker-compose -f docker-compose.service2.yml logs
docker-compose -f docker-compose.service3.yml logs

# Follow logs for specific service
docker-compose -f docker-compose.service1.yml logs -f

# View specific container logs
docker logs service1        # Public container
docker logs service1-private # Private container

Network Inspection

# List networks
docker network ls

# Inspect public network
docker network inspect public_network

# View container networks
docker inspect service1 | grep NetworkMode

Service Status

# Container status (should show 6 containers total)
docker ps

# Resource usage
docker stats

# Test network isolation
docker exec service1 python3 -c "import requests; requests.get('http://service2-private:8081/private/info')"
# Should fail with connection error

πŸŽ“ Learning Exercises

  1. Modify Response Format - Change the JSON structure and test compatibility
  2. Add Authentication - Implement token-based auth between services
  3. Implement Circuit Breaker - Add failure handling patterns
  4. Add Metrics - Integrate Prometheus metrics collection
  5. Database Integration - Add shared or dedicated databases
  6. Load Balancing - Scale services and add load balancers

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test thoroughly with ./test.sh
  5. Submit a pull request

πŸ“„ License

This project is open source and available under the MIT License.

πŸ†˜ Troubleshooting

Services Won't Start

# Check Docker status
docker info

# View build logs
docker-compose -f docker-compose.service1.yml up --build

# Clean and rebuild
./stop.sh --clean
./start.sh

Network Issues

# Reset networks
./stop.sh
docker network prune -f
./start.sh

Port Conflicts

Check if ports 8001-8003 are available:

lsof -i :8001
lsof -i :8002  
lsof -i :8003

Happy Dockering! 🐳

For detailed implementation information, see REQUIREMENTS.md.

About

(This project is my experiment of vibe coding)

Topics

Resources

Stars

Watchers

Forks

Contributors 2

  •  
  •