Docker et nginx multi-projets
Peut-être avez-vous plusieurs projets à déployer. Si c'est le cas, il vous faudra modifier la configuration de nginx
, 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
.
Configurer le projet
- 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:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
# Build the app
FROM mcr.microsoft.com/dotnet/sdk:7.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 /app/publish .
ENTRYPOINT ["dotnet", "Snowfall.Web.Api.dll"] - Modifiez le fichier
docker-compose.yml
pour ajouter le nouveau service.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
client:
build:
context: .
dockerfile: Snowfall.Web.Mvc/Dockerfile
container_name: snowfall_client
environment:
- ASPNETCORE_URLS=${ASPNETCORE_URLS}
- DossierStorage=${DossierStorage}
- ConnectionStrings__AppDatabaseConnection=${APP_DATABASE_CONNECTION}
expose:
- "80"
volumes:
- shared-images:/storage-images
depends_on:
- postgres
api:
build:
context: .
dockerfile: Snowfall.Web.Api/Dockerfile # Chemin vers le Dockerfile de l'API
container_name: snowfall_api
environment:
- ASPNETCORE_URLS=http://+:5000 # Port interne pour l'API
- DossierStorage=${DossierStorage}
- ConnectionStrings__AppDatabaseConnection=${APP_DATABASE_CONNECTION}
expose:
- "5000" # Expose le port interne
volumes:
- shared-images:/storage-images
depends_on:
- postgres
reverse-proxy:
image: nginx:alpine
container_name: reverse_proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- certs:/etc/letsencrypt
- certs-data:/data/letsencrypt
depends_on:
- client
- api # Ajouter l'API comme dépendance
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certs:/etc/letsencrypt
- certs-data:/data/letsencrypt
volumes:
pgdata:
shared-images:
certs:
certs-data: - Modifiez
nginx.conf
pour ajouter le nouveau servicenginx.confevents { }
http {
upstream client_app {
server client:80;
}
upstream api_app {
server api:5000;
}
# Bloc pour les requêtes HTTP
server {
listen 80;
server_name snowfallweb.com www.snowfallweb.com api.snowfallweb.com;
# Pour Certbot
location /.well-known/acme-challenge/ {
root /data/letsencrypt;
}
# Redirige le reste des requêtes vers HTTPS
location / {
return 301 https://$host$request_uri;
}
}
# Bloc pour les requêtes HTTPS
server {
listen 443 ssl;
server_name snowfallweb.com www.snowfallweb.com;
ssl_certificate /etc/letsencrypt/live/snowfallweb.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/snowfallweb.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Permet également le challenge pour HTTPS
location /.well-known/acme-challenge/ {
root /data/letsencrypt;
}
location / {
proxy_pass http://client_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# Bloc pour les requêtes HTTPS pour l'API
server {
listen 443 ssl;
server_name api.snowfallweb.com;
ssl_certificate /etc/letsencrypt/live/api.snowfallweb.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.snowfallweb.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Permet également le challenge pour HTTPS
location /.well-known/acme-challenge/ {
root /data/letsencrypt;
}
location / {
proxy_pass http://api_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Construire la nouvelle image
git pull
les derniers changementsdocker compose stop
pour arrêter le conteneurdocker compose build api
pour seulement construire la nouvelle image.
Demander un certificat
Nous avons un enjeu! Pour demander un certificat, il faut partir le conteneur, mais le conteneur (nginx) s'attend à un fichier de certificat SSL. Bref, le serveur ne pourra pas partir et donc on ne pourra pas demander de certificat.
Nous allons ainsi suivre les étapes suivantes:
- Modifier temporairement le fichier nginx.conf pour exclure le sous-domaine.
- Redémarrer Nginx pour qu’il ne tente plus de charger le certificat manquant.
- Utiliser Certbot pour générer le certificat SSL.
- Réintégrer le bloc serveur pour le sous-domaine API dans nginx.conf.
- Redémarrer Nginx pour appliquer les changements.
**Vous pouvez faire toutes ces modifs directement sur le serveur.
- Ouvrez le fichier
nginx.conf
nano nginx.conf
- Mettez en commentaire toute la portion "serveur" en lien avec le nouveau projet/domaine
# server {
# listen 443 ssl;
# server_name api.snowfallweb.com;
# ssl_certificate /etc/letsencrypt/live/api.snowfallweb.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/api.snowfallweb.com/privkey.pem;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location /.well-known/acme-challenge/ {
# root /data/letsencrypt;
# }
# location / {
# proxy_pass http://api_app;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# }
# } - Enregistrez le fichier (CTRL+X et ensuite, Y)
- Démarrez le conteneur
docker compose up -d
- Demandez un certificat pour le sous-domaine
docker compose run certbot certonly --webroot --webroot-path=/data/letsencrypt -d api.snowfallweb.com
- Confirmez que le certificat a été généré
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/api.snowfallweb.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/api.snowfallweb.com/privkey.pem
This certificate expires on 2025-04-27.
These files will be updated when the certificate renews. - Réactivez la zone "Server" qui a été mise en commentaire précédemment
- Repartez le service
nginx
docker compose restart reverse-proxy