feat(backend/infra): add Docker configuration for Phase 3
- Create Dockerfile for backend (.NET 9.0 multi-stage build) - Create Dockerfile for frontend (Node + Nginx multi-stage build) - Create nginx.conf for frontend with API proxy - Create docker-compose.yml with db, backend, frontend services - Add .dockerignore files for backend, frontend, and root - Configure health checks for all services - Configure PostgreSQL volume for persistent data Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
7ac5f1259b
commit
79a59bccc4
7 changed files with 318 additions and 0 deletions
40
.dockerignore
Normal file
40
.dockerignore
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Root .dockerignore for the entire solution
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Docker files
|
||||||
|
Dockerfile
|
||||||
|
docker-compose*
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
**/bin/
|
||||||
|
**/obj/
|
||||||
|
**/dist/
|
||||||
|
|
||||||
|
# Node modules
|
||||||
|
**/node_modules/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Test results
|
||||||
|
**/TestResults/
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
**/appsettings.Development.json
|
||||||
|
**/secrets.json
|
||||||
|
**/.env*
|
||||||
31
GermanApp/.dockerignore
Normal file
31
GermanApp/.dockerignore
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# .NET Core
|
||||||
|
**/bin/
|
||||||
|
**/obj/
|
||||||
|
|
||||||
|
# User secrets
|
||||||
|
**/appsettings.Development.json
|
||||||
|
**/secrets.json
|
||||||
|
|
||||||
|
# NuGet packages
|
||||||
|
**/packages/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vs/
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Test results
|
||||||
|
**/TestResults/
|
||||||
54
GermanApp/Dockerfile
Normal file
54
GermanApp/Dockerfile
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
# GermanApp Backend Dockerfile
|
||||||
|
# .NET 9.0 Web API Application
|
||||||
|
# Multi-stage build for production optimization
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Build Stage
|
||||||
|
# ============================================
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:9.0.204-alpine3.19 AS build
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
# Copy project file and restore dependencies
|
||||||
|
COPY ["GermanApp/GermanApp.csproj", "GermanApp/"]
|
||||||
|
RUN dotnet restore "GermanApp/GermanApp.csproj"
|
||||||
|
|
||||||
|
# Copy everything else and build
|
||||||
|
COPY . .
|
||||||
|
WORKDIR "/src/GermanApp"
|
||||||
|
RUN dotnet build "GermanApp.csproj" -c Release -o /app/build
|
||||||
|
|
||||||
|
# Publish the application
|
||||||
|
RUN dotnet publish "GermanApp.csproj" -c Release -o /app/publish \
|
||||||
|
--no-restore \
|
||||||
|
-p:PublishReadyToRun=true \
|
||||||
|
-p:PublishSingleFile=false \
|
||||||
|
-p:PublishTrimmed=true
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Publish Stage
|
||||||
|
# ============================================
|
||||||
|
FROM build AS publish
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Runtime Stage
|
||||||
|
# ============================================
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:9.0.4-alpine3.19 AS runtime
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy published app from publish stage
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
|
||||||
|
ENV ASPNETCORE_URLS=http://+:8080
|
||||||
|
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8080/health || exit 1
|
||||||
|
|
||||||
|
# Entry point
|
||||||
|
ENTRYPOINT ["dotnet", "GermanApp.dll"]
|
||||||
68
docker-compose.yml
Normal file
68
docker-compose.yml
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# PostgreSQL Database
|
||||||
|
db:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: deutschlernen-db
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: DeutschLernen
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U postgres -d DeutschLernen"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# Backend API
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ./GermanApp
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: deutschlernen-backend
|
||||||
|
environment:
|
||||||
|
ASPNETCORE_ENVIRONMENT: Development
|
||||||
|
ASPNETCORE_URLS: http://+:8080
|
||||||
|
ConnectionStrings__DefaultConnection: Host=db;Port=5432;Database=DeutschLernen;Username=postgres;Password=postgres
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ./german-app-frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: deutschlernen-frontend
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
depends_on:
|
||||||
|
backend:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
41
german-app-frontend/.dockerignore
Normal file
41
german-app-frontend/.dockerignore
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Node modules
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# npm cache
|
||||||
|
npm-cache/
|
||||||
|
|
||||||
|
# Dist directory (will be built in container)
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Test coverage
|
||||||
|
coverage/
|
||||||
43
german-app-frontend/Dockerfile
Normal file
43
german-app-frontend/Dockerfile
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# GermanApp Frontend Dockerfile
|
||||||
|
# React 19 + TypeScript + Vite Application
|
||||||
|
# Multi-stage build for production optimization
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Build Stage
|
||||||
|
# ============================================
|
||||||
|
FROM node:20-alpine AS build
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy source files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Runtime Stage
|
||||||
|
# ============================================
|
||||||
|
FROM nginx:alpine AS runtime
|
||||||
|
WORKDIR /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy built files from build stage
|
||||||
|
COPY --from=build /app/dist .
|
||||||
|
|
||||||
|
# Copy nginx configuration
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
|
||||||
|
|
||||||
|
# Entry point (nginx runs by default)
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
41
german-app-frontend/nginx.conf
Normal file
41
german-app-frontend/nginx.conf
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
server {
|
||||||
|
listen 3000;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
# Root directory
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# Handle React Router - return index.html for all requests
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# API proxy to backend (when running in Docker Compose)
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://backend:8080;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Error pages
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue