Files
the-biergarten-app/docs/docker.md
2026-02-21 05:02:22 -05:00

6.7 KiB

Docker Guide

This document covers Docker deployment, configuration, and troubleshooting for The Biergarten App.

Overview

The project uses Docker Compose to orchestrate multiple services:

  • SQL Server 2022 database
  • Database migrations runner (DbUp)
  • Database seeder
  • .NET API
  • Test runners

See the deployment diagram for visual representation.

Docker Compose Environments

1. Development (docker-compose.dev.yaml)

Purpose: Local development with persistent data

Features:

  • Persistent SQL Server volume
  • Hot reload support
  • Swagger UI enabled
  • Seed data included
  • CLEAR_DATABASE=true (drops and recreates schema)

Services:

sqlserver           # SQL Server 2022 (port 1433)
database.migrations # DbUp migrations
database.seed      # Seed initial data
api.core           # Web API (ports 8080, 8081)

Start Development Environment:

docker compose -f docker-compose.dev.yaml up -d

Access:

Stop Environment:

# Stop services (keep volumes)
docker compose -f docker-compose.dev.yaml down

# Stop and remove volumes (fresh start)
docker compose -f docker-compose.dev.yaml down -v

2. Testing (docker-compose.test.yaml)

Purpose: Automated CI/CD testing in isolated environment

Features:

  • Fresh database each run
  • All test suites execute in parallel
  • Test results exported to ./test-results/
  • Containers auto-exit after completion
  • Fully isolated testnet network

Services:

sqlserver           # Test database
database.migrations # Fresh schema
database.seed      # Test data
api.specs          # Reqnroll BDD tests
repository.tests   # Repository unit tests
service.auth.tests # Service unit tests

Run Tests:

# Run all tests
docker compose -f docker-compose.test.yaml up --abort-on-container-exit

# View results
ls -la test-results/
cat test-results/api-specs/results.trx
cat test-results/repository-tests/results.trx
cat test-results/service-auth-tests/results.trx

# Clean up
docker compose -f docker-compose.test.yaml down -v

3. Production (docker-compose.prod.yaml)

Purpose: Production-ready deployment

Features:

  • Production logging levels
  • No database clearing
  • Optimized build configurations
  • Health checks enabled
  • Restart policies (unless-stopped)
  • Security hardening

Services:

sqlserver          # Production SQL Server
database.migrations # Schema updates only
api.core          # Production API

Deploy Production:

docker compose -f docker-compose.prod.yaml up -d

Service Dependencies

Docker Compose manages startup order using health checks:

sqlserver (health check)
    ↓
database.migrations (completes successfully)
    ↓
database.seed (completes successfully)
    ↓
api.core / tests (start when ready)

Health Check Example (SQL Server):

healthcheck:
  test: ['CMD-SHELL', "sqlcmd -S localhost -U sa -P '${DB_PASSWORD}' -C -Q 'SELECT 1'"]
  interval: 10s
  timeout: 5s
  retries: 12
  start_period: 30s

Dependency Configuration:

api.core:
  depends_on:
    database.seed:
      condition: service_completed_successfully

Volumes

Persistent Volumes

Development:

  • sqlserverdata-dev - Database files persist between restarts
  • nuget-cache-dev - NuGet package cache (speeds up builds)

Testing:

  • sqlserverdata-test - Temporary, typically removed after tests

Production:

  • sqlserverdata-prod - Production database files
  • nuget-cache-prod - Production NuGet cache

Mounted Volumes

Test Results:

volumes:
  - ./test-results:/app/test-results

Test results are written to host filesystem for CI/CD integration.

Code Volumes (development only):

volumes:
  - ./src:/app/src # Hot reload for development

Networks

Each environment uses isolated bridge networks:

  • devnet - Development network
  • testnet - Testing network (fully isolated)
  • prodnet - Production network

Environment Variables

All containers are configured via environment variables from .env files:

env_file: '.env.dev' # or .env.test, .env.prod

environment:
  ASPNETCORE_ENVIRONMENT: 'Development'
  DOTNET_RUNNING_IN_CONTAINER: 'true'
  DB_SERVER: '${DB_SERVER}'
  DB_NAME: '${DB_NAME}'
  DB_USER: '${DB_USER}'
  DB_PASSWORD: '${DB_PASSWORD}'
  JWT_SECRET: '${JWT_SECRET}'

For complete list, see Environment Variables.

Common Commands

View Services

# Running services
docker compose -f docker-compose.dev.yaml ps

# All containers (including stopped)
docker ps -a

View Logs

# All services
docker compose -f docker-compose.dev.yaml logs -f

# Specific service
docker compose -f docker-compose.dev.yaml logs -f api.core

# Last 100 lines
docker compose -f docker-compose.dev.yaml logs --tail=100 api.core

Execute Commands in Container

# Interactive shell
docker exec -it dev-env-api-core bash

# Run command
docker exec dev-env-sqlserver /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'password' -C

Restart Services

# Restart all services
docker compose -f docker-compose.dev.yaml restart

# Restart specific service
docker compose -f docker-compose.dev.yaml restart api.core

# Rebuild and restart
docker compose -f docker-compose.dev.yaml up -d --build api.core

Build Images

# Build all images
docker compose -f docker-compose.dev.yaml build

# Build specific service
docker compose -f docker-compose.dev.yaml build api.core

# Build without cache
docker compose -f docker-compose.dev.yaml build --no-cache

Clean Up

# Stop and remove containers
docker compose -f docker-compose.dev.yaml down

# Remove containers and volumes
docker compose -f docker-compose.dev.yaml down -v

# Remove containers, volumes, and images
docker compose -f docker-compose.dev.yaml down -v --rmi all

# System-wide cleanup
docker system prune -af --volumes

Dockerfile Structure

Multi-Stage Build

# Stage 1: Build
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY ["Project/Project.csproj", "Project/"]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release

# Stage 2: Runtime
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
WORKDIR /app
COPY --from=build /app/build .
ENTRYPOINT ["dotnet", "Project.dll"]

Additional Resources