chore: add Docker deployment setup and health check wiring
Some checks failed
Dev Build / build-test (push) Failing after 1m1s
Dev Build / deploy-dev (push) Has been skipped
Dev Build / notify-success (push) Has been skipped
Dev Build / notify-failure (push) Successful in 4s

- Add multi-stage Dockerfile for backend (SDK build → ASP.NET runtime,
  non-root user, /health HEALTHCHECK)
- Add docker-compose.dev.yml orchestrating extrudex-api + control-center-web
- Add deploy.sh convenience script wrapping docker compose up --build
- Wire ASP.NET health checks: AddHealthChecks().AddNpgSql() + MapHealthChecks("/health")
- Add backend .dockerignore (comprehensive pattern list)
- Exclude frontend/dist, frontend/node_modules, frontend/.angular from git

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 17:28:06 +00:00
parent ff1fb621d7
commit 7d0369b8e9
7 changed files with 148 additions and 1 deletions

7
.gitignore vendored
View File

@@ -2,4 +2,9 @@ bin/
obj/ obj/
*.user *.user
*.suo *.suo
.vs/ .vs/
# Frontend build artifacts
frontend/dist/
frontend/node_modules/
frontend/.angular/

27
backend/.dockerignore Normal file
View File

@@ -0,0 +1,27 @@
# Build artifacts
bin/
obj/
# IDE / editor
.vs/
.vscode/
*.user
*.suo
.idea/
# Environment & secrets
appsettings.Development.json
.env
.env.*
# Docker
Dockerfile
.dockerignore
# OS
.DS_Store
Thumbs.db
# Misc
*.md
*.log

34
backend/Dockerfile Normal file
View File

@@ -0,0 +1,34 @@
# ── Stage 1: Build ──────────────────────────────────────────
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
# Copy csproj first for layer caching — restores before copying source
COPY Extrudex.csproj .
RUN dotnet restore
# Copy the rest of the source
COPY . .
RUN dotnet publish Extrudex.csproj \
-c Release \
-o /app/publish \
--no-restore
# ── Stage 2: Runtime ────────────────────────────────────────
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
WORKDIR /app
# Non-root user for security
RUN adduser --disabled-password --gecos "" appuser
USER appuser
# Copy published output from build stage
COPY --from=build /app/publish .
# ASP.NET Core listens on 8080 by default in .NET 8+
EXPOSE 8080
# Health check against /health endpoint
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl --fail http://localhost:8080/health || exit 1
ENTRYPOINT ["dotnet", "Extrudex.dll"]

View File

@@ -9,6 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="9.0.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" /> <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3" />

View File

@@ -69,6 +69,10 @@ builder.Services.AddCors(options =>
// ── SignalR (real-time printer updates) ──────────────────── // ── SignalR (real-time printer updates) ────────────────────
builder.Services.AddSignalR(); builder.Services.AddSignalR();
// ── Health Checks ───────────────────────────────────────────
builder.Services.AddHealthChecks()
.AddNpgSql(connectionString);
var app = builder.Build(); var app = builder.Build();
// ── Middleware ────────────────────────────────────────────── // ── Middleware ──────────────────────────────────────────────
@@ -85,6 +89,9 @@ app.MapControllers();
// ── Hub Endpoints ─────────────────────────────────────────── // ── Hub Endpoints ───────────────────────────────────────────
app.MapHub<PrinterHub>("/hubs/printer"); app.MapHub<PrinterHub>("/hubs/printer");
// ── Health Check Endpoint ──────────────────────────────────
app.MapHealthChecks("/health");
app.Run(); app.Run();
// Helper: builds a connection string from individual env vars. // Helper: builds a connection string from individual env vars.

33
deploy.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/bin/bash
set -e
echo "🔧 Deploying Extrudex Docker runtime..."
# Check if Docker Compose is available
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
echo "❌ Docker Compose is not installed"
exit 1
fi
COMPOSE_CMD="docker compose"
if command -v docker-compose &> /dev/null; then
COMPOSE_CMD="docker-compose"
fi
echo "📦 Building and starting services..."
$COMPOSE_CMD -f docker-compose.dev.yml up -d --build
echo "⏳ Waiting for services to become healthy..."
sleep 10
echo "✅ Deployment complete!"
echo ""
echo "Services running:"
echo " • Extrudex API: http://localhost:5080"
echo " • Control Center Web: http://localhost:5081"
echo ""
echo "To view logs:"
echo " $COMPOSE_CMD -f docker-compose.dev.yml logs -f"
echo ""
echo "To stop:"
echo " $COMPOSE_CMD -f docker-compose.dev.yml down"

40
docker-compose.dev.yml Normal file
View File

@@ -0,0 +1,40 @@
version: '3.8'
services:
extrudex-api:
build:
context: ./backend
dockerfile: Dockerfile
container_name: extrudex-api
ports:
- "5080:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:8080
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- extrudex-network
control-center-web:
build:
context: ../Control-Center/frontend
dockerfile: Dockerfile
container_name: control-center-web
ports:
- "5081:80"
depends_on:
extrudex-api:
condition: service_healthy
restart: unless-stopped
networks:
- extrudex-network
networks:
extrudex-network:
driver: bridge