Skip to main content

Overview

The Tournament Management App is fully containerized using Docker, enabling consistent deployments across development, staging, and production environments. The application uses a multi-stage Docker build to create optimized production images.

Prerequisites

Docker Engine

Version 20.10 or higher

Docker Compose

Version 2.0 or higher
Install Docker Desktop for your operating system:

Quick Start with Docker Compose

The fastest way to deploy is using Docker Compose:
1

Clone the repository

git clone https://github.com/AlexanderAsprilla98/Tournament-Management-App.git
cd Tournament-Management-App
2

Build and start the container

docker-compose up -d
Starts the application on http://localhost:5000 with Development environment settings.
3

Access the application

  • Development: Navigate to http://localhost:5000
  • Production: Navigate to http://localhost:80
The database is automatically initialized with the required schema during container startup.
4

Verify health

Check the application health endpoint:
curl http://localhost:5000/health
You should receive a Healthy response.

Docker Compose Configuration

Development Environment

docker-compose.yml
services:
  torneo-app:
    container_name: torneo-app
    build:
      context: .
      dockerfile: ./Dockerfile
    environment:
      ASPNETCORE_ENVIRONMENT: Development
    ports:
      - "5000:80"
    networks:
      - torneo-network

networks:
  torneo-network:
    driver: bridge

volumes:
  sqldata:
The Development configuration enables detailed error pages, developer exception pages, and hot reload capabilities.

Production Environment

docker-compose.prod.yml
services:
  torneo-app:
    container_name: torneo-app
    build:
      context: .
      dockerfile: ./Dockerfile
    environment:
      ASPNETCORE_ENVIRONMENT: Production
    ports:
      - "80:80"
    networks:
      - torneo-network

networks:
  torneo-network:
    driver: bridge

volumes:
  sqldata:
Production mode disables detailed error messages and enables performance optimizations. Always use HTTPS in production with proper SSL certificates.

Dockerfile Structure

The application uses a multi-stage build for optimal image size and security:

Stage 1: Build

Dockerfile (Build Stage)
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app

# Install Entity Framework tools
RUN dotnet tool install --global dotnet-ef --version 8

ENV PATH="${PATH}:/root/.dotnet/tools"
ENV DATABASE_CONNECTION_STRING="Data Source=/app/Torneo.db"

COPY ["Torneo.App/", "./"]

# Create solution, restore, build, and run migrations
RUN dotnet new sln -n Torneo.App \
    && dotnet sln Torneo.App.sln add \
        Torneo.App.Dominio/Torneo.App.Dominio.csproj \
        Torneo.App.Persistencia/Torneo.App.Persistencia.csproj \
        Torneo.App.Consola/Torneo.App.Consola.csproj \
        Torneo.App.Frontend/Torneo.App.Frontend.csproj \
    && dotnet restore Torneo.App.sln \
    && dotnet build Torneo.App.sln -c Release --no-restore \
    # DataContext migrations
    && dotnet ef migrations add InitialCreate \
        --project Torneo.App.Persistencia/Torneo.App.Persistencia.csproj \
        --startup-project Torneo.App.Frontend/Torneo.App.Frontend.csproj \
        --context Torneo.App.Persistencia.DataContext \
        --no-build --configuration Release \
    && dotnet ef database update \
        --project Torneo.App.Persistencia/Torneo.App.Persistencia.csproj \
        --startup-project Torneo.App.Frontend/Torneo.App.Frontend.csproj \
        --context Torneo.App.Persistencia.DataContext \
    # IdentityDataContext migrations
    && dotnet ef migrations add CreateIdentitySchema \
        --project Torneo.App.Frontend/Torneo.App.Frontend.csproj \
        --context Torneo.App.Frontend.Areas.Identity.Data.IdentityDataContext \
        --no-build --configuration Release \
    && dotnet ef database update \
        --project Torneo.App.Frontend/Torneo.App.Frontend.csproj \
        --startup-project Torneo.App.Frontend/Torneo.App.Frontend.csproj \
        --context Torneo.App.Frontend.Areas.Identity.Data.IdentityDataContext \
    # Publish and cleanup
    && dotnet publish Torneo.App.sln -c Release -o /app/publish --no-restore --no-build \
    && dotnet nuget locals all --clear
The build stage:
  • Uses the full .NET SDK (8.0) for compilation
  • Installs Entity Framework Core tools
  • Creates a solution and adds all projects
  • Restores NuGet dependencies
  • Builds in Release configuration
  • Runs migrations for both database contexts
  • Publishes the optimized application
  • Cleans up unnecessary files to reduce image size

Stage 2: Runtime

Dockerfile (Runtime Stage)
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app

# Copy published files and database
COPY --from=build /app/publish .
COPY --from=build /app/Torneo.db .

# Configure globalization and port
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=0
ENV PORT=80
EXPOSE 80

ENTRYPOINT ["dotnet", "Torneo.App.Frontend.dll", "--urls", "http://0.0.0.0:80"]
The runtime stage:
  • Uses the lightweight ASP.NET runtime (no SDK)
  • Copies only the published application
  • Includes the pre-initialized SQLite database
  • Exposes port 80 for HTTP traffic
  • Configures the entry point for the web application

Container Management

View Running Containers

docker ps
Expected output:
CONTAINER ID   IMAGE                        STATUS         PORTS                    NAMES
abc123def456   tournament-management-app    Up 2 minutes   0.0.0.0:5000->80/tcp     torneo-app

View Container Logs

docker logs torneo-app
For continuous log streaming:
docker logs -f torneo-app

Stop the Container

docker-compose down
To remove volumes as well:
docker-compose down -v

Restart the Container

docker-compose restart

Execute Commands Inside Container

# Open a shell inside the container
docker exec -it torneo-app /bin/bash

# Run a specific command
docker exec torneo-app ls /app

Building Custom Images

If you need to customize the Docker image:
# Build the image
docker build -t torneo-app:custom .

# Tag for a registry
docker tag torneo-app:custom myregistry.com/torneo-app:1.0.0

# Push to registry
docker push myregistry.com/torneo-app:1.0.0

Environment Variables

You can override environment variables in docker-compose.yml:
services:
  torneo-app:
    environment:
      ASPNETCORE_ENVIRONMENT: Production
      DATABASE_CONNECTION_STRING: "Data Source=/app/Torneo.db"
      DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "0"
For SQLite databases, the connection string should point to a file path. For SQL Server, use a full connection string with server, database, and credentials.

Data Persistence

The SQLite database is created inside the container at /app/Torneo.db. To persist data across container restarts, you can mount a volume:
services:
  torneo-app:
    volumes:
      - torneo-data:/app
    
volumes:
  torneo-data:

Cloud Deployment

The application includes a render.yaml configuration for deployment to Render.com:
render.yaml
services:
  - type: web
    name: tournament-management-app
    env: docker
    dockerfilePath: ./Dockerfile
    envVars:
      - key: ASPNETCORE_ENVIRONMENT
        value: Production

Render

One-click deployment from GitHub

Azure

Azure Container Instances

AWS

Amazon ECS or App Runner

Troubleshooting

Solution: Check container logs for errors:
docker logs torneo-app
Common issues:
  • Port 5000 or 80 already in use
  • Insufficient memory or disk space
  • Database migration failures
Solution: The Dockerfile runs migrations automatically during build. If the database is missing:
# Rebuild the image
docker-compose build --no-cache
docker-compose up -d
Solution: Ensure the container is healthy:
curl http://localhost:5000/health
If unhealthy, check that the database is accessible and properly initialized.
Solution: Rebuild the image after code changes:
docker-compose build
docker-compose up -d

Next Steps

Database Setup

Learn about database configuration and migrations

Configuration

Configure environment variables and settings

Managing Teams

Start managing your tournament teams

User Authentication

Set up user accounts and permissions

Build docs developers (and LLMs) love