Aller au contenu principal

Docker et Caddy multi-projets

Peut-être avez-vous plusieurs projets à déployer. Si c'est le cas, il vous faudra modifier la configuration de Caddy, docker-compose.yml, en plus de créer un Dockerfile additionnel.

De plus, il vous faudra un domaine additionnel. Je vous suggère d'utiliser un sous-domaine pour simplifier le tout. Par exemple, assumons que vous avez déjà déployé un site sous mondomaine.com et que vous vouliez déployer une API. Utilisez api.mondomaine.com pour déployer l'API.

Créer un sous-domaine

Chez votre registrar (là où vous avez enregistré votre nom de domaine), créez une nouvelle entrée DNS qui pointe vers votre serveur. Créez cette entrée avec le type A Record.

img

Configurer le projet

  1. Créer un fichier Dockerfile dans le nouveau projet et mettre les instructions de compilation. Le fichier devrait être très près de ce que vous avez déjà.

    Snowfall.Web.Api/Dockerfile
    # Use the ASP.NET runtime as base
    FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
    WORKDIR /app
    EXPOSE 8080

    # Build the app
    FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
    WORKDIR /src
    COPY ["Snowfall.Web.Api/Snowfall.Web.Api.csproj", "Snowfall.Web.Api/"]
    RUN dotnet restore "Snowfall.Web.Api/Snowfall.Web.Api.csproj"
    COPY . .
    RUN dotnet publish "Snowfall.Web.Api/Snowfall.Web.Api.csproj" -c Release -o /app/publish

    FROM base AS final
    WORKDIR /app
    COPY --from=build /app/publish .
    ENTRYPOINT ["dotnet", "Snowfall.Web.Api.dll"]
  2. Modifiez le fichier docker-compose.yml pour ajouter le nouveau service.

    docker-compose.yml
    services:
    postgres:
    image: postgres:17-alpine
    container_name: snowfall_postgres
    environment:
    - POSTGRES_DB=${POSTGRES_DB}
    - POSTGRES_USER=${POSTGRES_USER}
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
    - pgdata:/var/lib/postgresql/data
    healthcheck:
    test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
    interval: 5s
    timeout: 5s
    retries: 5
    restart: unless-stopped

    client:
    build:
    context: .
    dockerfile: Snowfall.Web.Mvc/Dockerfile
    container_name: snowfall_client
    environment:
    - ASPNETCORE_HTTP_PORTS=${ASPNETCORE_HTTP_PORTS}
    - DossierStorage=/storage-images
    - ConnectionStrings__AppDatabaseConnection=${APP_DATABASE_CONNECTION}
    expose:
    - "8080"
    volumes:
    - shared-images:/storage-images
    depends_on:
    postgres:
    condition: service_healthy
    restart: unless-stopped

    api:
    build:
    context: .
    dockerfile: Snowfall.Web.Api/Dockerfile
    container_name: snowfall_api
    environment:
    - ASPNETCORE_HTTP_PORTS=5000
    - DossierStorage=/storage-images
    - ConnectionStrings__AppDatabaseConnection=${APP_DATABASE_CONNECTION}
    - JwtSecurityKey=${JWT_SECURITY_KEY}
    - JwtIssuer=${JWT_ISSUER}
    - JwtAudience=${JWT_AUDIENCE}
    - JwtExpirationJours=${JWT_EXPIRATION_JOURS}
    expose:
    - "5000"
    volumes:
    - shared-images:/storage-images
    depends_on:
    postgres:
    condition: service_healthy
    restart: unless-stopped

    caddy:
    image: caddy:alpine
    container_name: snowfall_caddy
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - ./Caddyfile:/etc/caddy/Caddyfile:ro
    - caddy_data:/data
    - caddy_config:/config
    depends_on:
    - client
    - api
    restart: unless-stopped

    volumes:
    pgdata:
    shared-images:
    caddy_data:
    caddy_config:
  3. Modifiez le Caddyfile pour ajouter le nouveau domaine.

    snowfallweb.com {
    reverse_proxy client:8080
    }

    api.snowfallweb.com {
    reverse_proxy api:5000
    }
    attention

    Remplacez snowfallweb.com et api.snowfallweb.com par vos noms de domaine.

    Caddy obtiendra automatiquement un certificat SSL pour chaque domaine configuré.

info

Le service api utilise le même fichier .env que le service client. En effet, Docker Compose lit le fichier .env situé à la racine de la solution (au même niveau que docker-compose.yml), et non dans le dossier de chaque projet. Les variables comme APP_DATABASE_CONNECTION sont donc partagées entre tous les services.

  1. Ajoutez les variables supplémentaires requises par l'API dans votre fichier .env (local et sur le serveur). Par exemple, si votre API utilise JWT:

    .env
    POSTGRES_DB=snowfall_db
    POSTGRES_USER=snowfall_user
    POSTGRES_PASSWORD=motdepasse
    ASPNETCORE_HTTP_PORTS=8080
    DossierStorage=/storage-images
    APP_DATABASE_CONNECTION="Host=postgres;Port=5432;Database=snowfall_db;Username=snowfall_user;Password=motdepasse"

    # JWT (API)
    JWT_SECURITY_KEY=une-cle-secrete-forte
    JWT_ISSUER=https://snowfallweb.com
    JWT_AUDIENCE=https://snowfallweb.com
    JWT_EXPIRATION_JOURS=30
    attention

    Les valeurs dans appsettings.Development.json ne sont pas chargées en production (Docker utilise l'environnement Production). C'est pourquoi il faut passer ces valeurs via les variables d'environnement.

Construire la nouvelle image

  1. git pull les derniers changements
  2. docker compose stop pour arrêter le conteneur
  3. docker compose build api pour seulement construire la nouvelle image
  4. docker compose up -d pour démarrer tous les services