A simplified guide to containerizing and running the OrderFlow.Core application with Docker.
- ⚡ Quick Start
- 📋 Docker Compose Files Overview
- 💻 Development Setup (Recommended)
- 🚀 Full Stack Setup
- 🔧 Understanding the Configuration
- ⌨️ Common Commands
- 🔍 Troubleshooting
Run only RabbitMQ in Docker, debug your app in Visual Studio:
# Start RabbitMQ
docker-compose -f docker-compose.dev.yml up -d
# Access RabbitMQ Management UI
# 🌐 http://localhost:15672 (admin/admin123)
# Run your app from Visual Studio (F5)Run both RabbitMQ and the application in Docker:
# Start all services
docker-compose up -d
# 🌐 Access Application: http://localhost:8080
# 📖 Access Swagger: http://localhost:8080/swagger
# 🐰 Access RabbitMQ UI: http://localhost:15672| File | Purpose | What Runs | When to Use |
|---|---|---|---|
docker-compose.dev.yml |
💻 Development | RabbitMQ only | Debugging in Visual Studio |
docker-compose.yml |
🚀 Full Stack | RabbitMQ + App | Testing complete system |
Best for: Day-to-day development and debugging
Benefits:
- ✅ Run app directly in Visual Studio with full debugging
- ✅ Hot reload and fast code changes
- ✅ RabbitMQ runs in Docker (consistent environment)
- ✅ No need to rebuild Docker images for code changes
services:
rabbitmq:
image: rabbitmq:3-management
container_name: orderflow-rabbitmq-dev
hostname: rabbitmq-dev
ports:
- "5672:5672" # Message broker port
- "15672:15672" # Management UI port
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin123
healthcheck:
test: rabbitmq-diagnostics -q ping
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
volumes:
- rabbitmq_dev_data:/var/lib/rabbitmq
networks:
- orderflow-dev-network
networks:
orderflow-dev-network:
driver: bridge
volumes:
rabbitmq_dev_data:
name: orderflow_rabbitmq_dev_datarabbitmq:
image: rabbitmq:3-management # Official RabbitMQ with web UI
container_name: orderflow-rabbitmq-dev # Easy to identify
hostname: rabbitmq-dev # Used for DNS resolutionKey Points:
- 🐰 Uses official RabbitMQ image with management plugin
- 🏷️ Container gets a friendly name for easy reference
- 🌐 Hostname allows connection via name instead of IP
ports:
- "5672:5672" # Your app connects here
- "15672:15672" # Web UI for monitoringWhat This Means:
- 📨 Port 5672: Application sends/receives messages
- 🖥️ Port 15672: Browser access to RabbitMQ dashboard
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin123Why Needed:
- 🚫 Default
guest/guestonly works from localhost - 🔑 Custom credentials allow Docker containers to connect
⚠️ Note: Change password for production!
healthcheck:
test: rabbitmq-diagnostics -q ping
interval: 10s
timeout: 5s
retries: 5
start_period: 30sPurpose:
- ✅ Ensures RabbitMQ is fully ready before app connects
- 🛡️ Prevents "connection refused" errors on startup
- ⏱️ 30-second grace period for initialization
Health Check Timeline:
0s → 🟡 Container starts
30s → 🔵 First health check
40s → 🔄 Retry if needed
50s → 🟢 Usually healthy by now
volumes:
- rabbitmq_dev_data:/var/lib/rabbitmqWhat Gets Saved:
- 📦 Queues and exchanges
- 📧 Messages (if persistent)
- 👤 User accounts
- ⚙️ Configuration
Why Important:
# ❌ Without volume
docker-compose down # All data lost!
# ✅ With volume
docker-compose down # Data preserved
docker-compose up # Everything restorednetworks:
- orderflow-dev-networkHow It Works:
- 🔒 Creates isolated network for containers
- 🔍 Enables DNS-based service discovery
- 🏷️ Containers use names instead of IPs
When running from Visual Studio, your appsettings.json should use:
{
"RabbitMq": {
"HostName": "localhost", // ← Use localhost (app not in container)
"Port": 5672,
"UserName": "admin",
"Password": "admin123"
}
}# 1. Start RabbitMQ
docker-compose -f docker-compose.dev.yml up -d
# 2. Verify it's running
docker-compose -f docker-compose.dev.yml ps
# Should show: orderflow-rabbitmq-dev (healthy) ✅
# 3. Check logs if needed
docker-compose -f docker-compose.dev.yml logs -f rabbitmq
# 4. Open Visual Studio and press F5 to debug 🐛
# 5. When done, stop RabbitMQ
docker-compose -f docker-compose.dev.yml downBest for: Integration testing, demos, production-like testing
Benefits:
- ✅ Complete system in Docker
- ✅ Test exactly as it will run in production
- ✅ No local dependencies needed
- ✅ Easy to share entire setup
services:
rabbitmq:
image: rabbitmq:3-management
container_name: orderflow-rabbitmq
hostname: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin123
healthcheck:
test: rabbitmq-diagnostics -q ping
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
- orderflow-network
orderflow-core:
build:
context: .
dockerfile: Dockerfile
container_name: orderflow-core
hostname: orderflow-core
ports:
- "8080:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_HTTP_PORTS=8080
- ASPNETCORE_URLS=http://+:8080
- RabbitMq__HostName=rabbitmq # ← Uses service name
- RabbitMq__Port=5672
- RabbitMq__UserName=admin
- RabbitMq__Password=admin123
- RabbitMq__ExchangeName=order_exchange
- RabbitMq__ExchangeType=topic
depends_on:
rabbitmq:
condition: service_healthy
networks:
- orderflow-network
restart: unless-stopped
networks:
orderflow-network:
driver: bridge
volumes:
rabbitmq_data:
name: orderflow_rabbitmq_dataorderflow-core:
build:
context: .
dockerfile: DockerfileWhat Happens:
- 🔨 Builds your application from source
- 📦 Creates optimized container image
- 🚀 Runs application inside Docker
depends_on:
rabbitmq:
condition: service_healthyStartup Order:
1. 🟡 Start RabbitMQ
2. ⏳ Wait for health check to pass
3. 🟢 Start OrderFlow.Core
4. ✅ App connects successfully
environment:
- RabbitMq__HostName=rabbitmq # ← Different from dev!Why Different:
- 🌐 Both services in same Docker network
- 🏷️ Use service name, not
localhost - 🔍 Docker DNS resolves
rabbitmqto correct container
Double Underscore Syntax:
RabbitMq__HostName=rabbitmqMaps to:
{
"RabbitMq": {
"HostName": "rabbitmq"
}
}restart: unless-stoppedBehavior:
- 💥 App crashes → Docker restarts automatically
- 🛑 Manual stop → Stays stopped
- 🔄 Machine reboots → Services start automatically
┌─────────────────────────────────────────────────────────┐
│ 🐳 Docker Environment │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ 🐰 RabbitMQ │ │ 🚀 OrderFlow │ │
│ │ │ │ Core │ │
│ │ Port: 5672 │◄────────│ (.NET 8) │ │
│ │ UI: 15672 │ │ Port: 8080 │ │
│ │ User: admin │ │ Swagger: /swagger│ │
│ └──────────────────┘ └──────────────────┘ │
│ │ │ │
│ └────────┬───────────────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ 🌐 Docker Network│ │
│ │ (Bridge Driver) │ │
│ └───────────────────┘ │
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ 💾 Volume: rabbitmq_data │ │
│ │ (Persistent Storage) │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│ │
│ │
localhost:15672 localhost:8080
(🐰 RabbitMQ UI) (🌐 API/Swagger)
| Service | Container Port | Host Port | Access From |
|---|---|---|---|
| 🐰 RabbitMQ AMQP | 5672 | 5672 | 📱 Application |
| 🖥️ RabbitMQ UI | 15672 | 15672 | 🌐 Browser |
| 🚀 OrderFlow API | 8080 | 8080 | 🌐 Browser/Postman |
Port Format: "HOST:CONTAINER"
ports:
- "8080:8080" # localhost:8080 → container:8080Inside Docker Network:
orderflow-core connects to: rabbitmq:5672
From Your Computer:
🌐 Browser connects to: localhost:8080
💻 App (Visual Studio) connects to: localhost:5672
❌ Bad (Using IP addresses):
RabbitMq__HostName: 172.18.0.2 # Can change on restart!✅ Good (Using service names):
RabbitMq__HostName: rabbitmq # Always resolves correctly1. Start RabbitMQ
2. Create queues and messages
3. docker-compose down
4. Start again
→ 💥 All data LOST!1. Start RabbitMQ
2. Create queues and messages
3. docker-compose down
4. Start again
→ 🎉 All data RESTORED!# List all volumes
docker volume ls
# Inspect volume details
docker volume inspect orderflow_rabbitmq_data
# Remove volume (deletes data!)
docker volume rm orderflow_rabbitmq_data
# Backup volume
docker run --rm \
-v orderflow_rabbitmq_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/rabbitmq-backup.tar.gz -C /data .# Start RabbitMQ only (for development)
docker-compose -f docker-compose.dev.yml up -d
# View logs
docker-compose -f docker-compose.dev.yml logs -f rabbitmq
# Check status
docker-compose -f docker-compose.dev.yml ps
# Stop RabbitMQ
docker-compose -f docker-compose.dev.yml down
# Stop and remove data
docker-compose -f docker-compose.dev.yml down -v# Start all services
docker-compose up -d
# Start and rebuild
docker-compose up -d --build
# View all logs
docker-compose logs -f
# View specific service logs
docker-compose logs -f orderflow-core
# Check status
docker-compose ps
# Restart a service
docker-compose restart orderflow-core
# Stop all services
docker-compose down
# Stop and remove volumes (data loss!)
docker-compose down -v# Execute command in container
docker-compose exec orderflow-core bash
# View container resource usage
docker-compose stats
# Remove unused images and containers
docker system prune -a
# View container IP address
docker inspect orderflow-core | grep IPAddressCheck logs:
docker-compose logs orderflow-coreCommon causes:
- 🔴 Port already in use
- 🔴 Build errors
- 🔴 Missing environment variables
Solution:
# Check what's using the port
netstat -ano | findstr :8080
# Rebuild from scratch
docker-compose down
docker-compose build --no-cache
docker-compose up -dVerify RabbitMQ is healthy:
docker-compose ps
# Should show "healthy" status ✅Check logs:
docker-compose logs rabbitmqCommon causes:
- ⏳ RabbitMQ still starting (wait 30-60 seconds)
- 🔴 Wrong hostname in configuration
- 🔴 Wrong credentials
Solution for Visual Studio (dev):
{
"RabbitMq": {
"HostName": "localhost", // ← Must be localhost
"UserName": "admin",
"Password": "admin123"
}
}Solution for Docker (full stack):
environment:
- RabbitMq__HostName=rabbitmq # ← Must be service nameError:
Error: Bind for 0.0.0.0:8080 failed: port is already allocated
Solutions:
Option 1: Change host port
ports:
- "8081:8080" # Use different portOption 2: Find and stop conflicting process
# Windows
netstat -ano | findstr :8080
taskkill /PID <PID> /F
# Linux/Mac
lsof -i :8080
kill -9 <PID>Error:
failed to solve: process "/bin/sh -c dotnet restore" did not complete
Solutions:
-
Check internet connection (NuGet needs to download packages) 🌐
-
Clear Docker cache:
docker-compose build --no-cache- Build locally first:
dotnet restore
dotnet build
docker-compose buildCause: Volumes not configured or removed
Check volumes:
docker volume ls | grep orderflowEnsure volume is defined:
volumes:
- rabbitmq_data:/var/lib/rabbitmq
volumes:
rabbitmq_data:
name: orderflow_rabbitmq_dataAvoid:
# ⚠️ This deletes volumes!
docker-compose down -vCause: Large build context
Solution: Create .dockerignore file:
**/.vs
**/.vscode
**/bin
**/obj
**/node_modules
**/.git
**/publish
-
Use docker-compose.dev.yml for development
- 🚀 Faster development cycle
- 🐛 Better debugging experience
-
Pin image versions in production
image: rabbitmq:3.12-management
-
Use environment variables for configuration
- 🚫 No hardcoded values in code
- ⚙️ Easy to change per environment
-
Always use health checks for dependencies
- 🛡️ Prevents startup errors
- ✅ Ensures services are ready
-
Use named volumes for data persistence
- 📦 Easy to manage
- 💾 Survives container restarts
-
Don't use
docker-compose down -vunless you want to delete data -
Don't hardcode IPs in configuration
RabbitMq__HostName: 172.18.0.2 # Bad!
-
Don't skip health checks
depends_on: - rabbitmq # Unsafe!
-
Don't commit sensitive credentials
- 🔐 Use environment variables
- 🔑 Use secrets management
-
Don't expose unnecessary ports
ports: - "5432:5432" # Only if needed externally
| Scenario | File | Command |
|---|---|---|
| 💻 Daily development | docker-compose.dev.yml |
docker-compose -f docker-compose.dev.yml up -d |
| 🧪 Integration testing | docker-compose.yml |
docker-compose up -d |
| 🎪 Demo/presentation | docker-compose.yml |
docker-compose up -d |
| Environment | HostName | Why |
|---|---|---|
| 💻 Visual Studio (dev) | localhost |
App runs on host machine |
| 🐳 Docker (full stack) | rabbitmq |
App runs in container |
| 🌐 Production | Service name or FQDN | Varies by platform |
| Service | URL | Credentials |
|---|---|---|
| 🚀 API | http://localhost:8080 | None |
| 📖 Swagger | http://localhost:8080/swagger | None |
| 🐰 RabbitMQ UI | http://localhost:15672 | admin/admin123 |
-
Two Setup Options:
- 💻
docker-compose.dev.yml: RabbitMQ only (best for development) - 🚀
docker-compose.yml: Full stack (best for testing)
- 💻
-
Health Checks Are Critical:
- ✅ Ensure services are ready before connections
- 🛡️ Prevent startup failures
-
Named Volumes Preserve Data:
- 💾 Data survives container restarts
- 📦 Easy to backup and restore
-
Service Names for DNS:
- 🏷️ Use service names in Docker networks
- 💻 Use
localhostwhen app runs outside Docker
-
Environment Variables for Configuration:
- 🚫 No code changes needed
- ⚙️ Easy to adapt to different environments
- 📘 Docker Compose Documentation
- 🐰 RabbitMQ Docker Hub
- 🚀 ASP.NET Core Docker Documentation
- 🌐 Docker Networking
- 💾 Docker Volumes
🐳 OrderFlow.Core - Containerized with Docker
Simple. Scalable. Ready for Development and Production.
✨ Built with .NET 8 | 🐰 RabbitMQ | 🐳 Docker