Skip to content

Services & Ports

Complete reference for all services and ports used in the Club Wilo development environment.

Application Services

ServicePortDescriptionCommand
Wilo.Api5000.NET 10 Backend APIbun run api:run
Wilo.App5173Vue 3 SPA (Vite dev server)bun run app:dev
Wilo.Email3050Email renderer (Hono/Bun)bun run email:dev
Wilo.Pdf3060PDF renderer (Hono/Bun)bun run pdf:dev
Wilo.Docs5173VitePress documentationbun run docs:dev

INFO

Wilo.App and Wilo.Docs both default to port 5173 — run them separately or Vite will auto-increment to the next available port.

Docker Compose Services

All infrastructure services are defined in docker-compose.yml and started with bun run docker:up.

Persistence

ServiceContainerPort(s)Image
PostgreSQLpostgresdb5432postgres:18.1-alpine
ClickHouseclickhouse8123 (HTTP)clickhouse/clickhouse-server:24.12-alpine
  • PostgreSQL — Main relational database. Used with EF Core, NodaTime types, and snake_case naming convention.
  • ClickHouse — Analytical database for immutable audit logs (MergeTree engine). HTTP interface on port 8123.

Cache

ServiceContainerPort(s)Image
Redisredis6379redis:8.4-alpine
Redis Insightredis-insight5540redis/redisinsight
  • Redis — Distributed cache backend for FusionCache (L1 memory + L2 Redis + backplane).
  • Redis Insight — Web-based GUI for inspecting Redis keys and monitoring.

Object Storage

ServiceContainerPort(s)Image
MinIOminio9000 (API), 9001 (console)minio/minio:RELEASE.2025-04-22T22-12-26Z
  • MinIO — S3-compatible object storage (AGPL-3.0, pinned to RELEASE.2025-04-22T22-12-26Z, never internet-exposed). Three buckets: wilo-documents, wilo-images, wilo-temp. Console at http://localhost:9001.

Email

ServiceContainerPort(s)Image
Email Rendererwilo-email3050Built from services/Wilo.Email/Dockerfile
Mailpitmailpit1025 (SMTP), 8025 (web UI)axllent/mailpit
  • Email Renderer — React Email template rendering service (Hono HTTP server on Bun runtime). The API sends template data to this service, which returns rendered HTML.
  • Mailpit — Development email capture. All SMTP traffic on port 1025 is captured and viewable at http://localhost:8025.

Dockerfile Locations

Each deployable service owns its Dockerfile inside its project directory. Dockerfiles are never placed at the monorepo root.

ServiceDockerfileBuild context
wilo-apisrc/Wilo.Api/Dockerfile. (repo root)
wilo-frontendsites/Wilo.App/Dockerfile./sites/Wilo.App
wilo-mobilesites/Wilo.Mobile/Dockerfile./sites/Wilo.Mobile
wilo-emailservices/Wilo.Email/Dockerfile./services/Wilo.Email

The API build context is the repo root because the Dockerfile copies from multiple src/ subdirectories. Its dockerignore is named src/Wilo.Api/Dockerfile.dockerignore (Docker's per-Dockerfile naming convention). The frontend and mobile apps use a standard .dockerignore in their respective directories since the build context is scoped to each project folder.

Observability

ServiceContainerPort(s)Image
Aspire Dashboardaspire-dashboard18888 (UI), 18889 (OTLP)mcr.microsoft.com/dotnet/aspire-dashboard
  • Aspire Dashboard — OpenTelemetry visualization dashboard for traces, metrics, and structured logs. The API exports telemetry via OTLP gRPC to port 18889. Dashboard UI at http://localhost:18888.

Health Check Endpoints

The API exposes three health check endpoints:

EndpointPurposeChecks
GET /healthAggregated status (cached 10s)All dependencies
GET /health/liveLiveness probeNone (process responsive)
GET /health/readyReadiness probe (3s timeout)PostgreSQL, Redis, MinIO, ClickHouse, Email Renderer

Response format:

json
{
  "status": "Healthy",
  "totalDuration": "00:00:01.234",
  "entries": {
    "postgres": { "status": "Healthy" },
    "redis": { "status": "Healthy" },
    "storage": { "status": "Healthy" },
    "clickhouse": { "status": "Healthy" },
    "email-renderer": { "status": "Healthy" }
  }
}

Service Dependencies

Wilo.Api ──┬── PostgreSQL (persistence)
           ├── Redis (cache)
           ├── MinIO (file storage)
           ├── ClickHouse (audit logs)
           ├── Email Renderer ── Mailpit (SMTP)
           └── Aspire Dashboard (telemetry)

Production Network Security

In production, no database, cache, analytics, or internal service port is exposed to the Internet. The only entry points accessible from outside are the reverse proxy (HTTPS 443) for the frontend and API, and optionally MinIO (9000) if external S3 access is required.

Port exposure policy

ServiceDevProductionNotes
Frontend (Nginx)3000443 (via reverse proxy)TLS terminated by reverse proxy
API5000443 (via reverse proxy)Internal port 5000 not exposed directly
MinIO API9000Optional (9000)Only if external S3 access is needed
MinIO Console9001❌ NeverAdmin UI always internal only
PostgreSQL5432 ⚠️❌ NeverFlagged ## REMOVE ON PRODUCTION in compose file
Redis6379❌ NeverInternal Docker network only
ClickHouse8123❌ NeverInternal Docker network only
Redis Insight5540❌ NeverDev tool, not deployed to production
Mailpit1025 / 8025❌ NeverDev tool, not deployed to production
Email Renderer3050❌ NeverInternal Docker network only
Aspire Dashboard18888 / 18889Optional (internal)OTLP receiver may be needed; UI is internal

WARNING

docker-compose.yml exposes PostgreSQL on 5432:5432 for local development convenience. This line is explicitly marked ## REMOVE ON PRODUCTION and must be removed or commented out before deploying to any public server.

SSH tunnel for direct database access in production

Direct access to databases and internal services in production is performed exclusively through an SSH tunnel. Never expose these ports to the Internet.

bash
# PostgreSQL
ssh -L 15432:postgresdb:5432 deploy@your-server
# Connect with: psql -h localhost -p 15432 -U wilo

# Redis
ssh -L 16379:redis:6379 deploy@your-server
# Connect with: redis-cli -p 16379

# ClickHouse
ssh -L 18123:clickhouse:8123 deploy@your-server
# Connect with: curl http://localhost:18123/ping

# MinIO Console (if not exposed externally)
ssh -L 19001:minio:9001 deploy@your-server
# Open: http://localhost:19001

# Redis Insight (if deployed)
ssh -L 15540:redis-insight:5540 deploy@your-server
# Open: http://localhost:15540

# Aspire Dashboard (if deployed)
ssh -L 18888:aspire-dashboard:18888 deploy@your-server
# Open: http://localhost:18888

The container names used above (postgresdb, redis, clickhouse, etc.) are the Docker Compose service names — they resolve correctly within the Docker network on the server.

Docker Commands

CommandDescription
bun run docker:upStart all infrastructure services
bun run docker:downStop all infrastructure services
bun run docker:logsFollow logs from all services
docker compose psCheck service status
docker compose logs -f <service>Follow logs for a specific service
docker compose restart <service>Restart a specific service

Environment Variables

All service credentials are configured via .env (copied from .env.example). Key variables:

VariableServicePurpose
POSTGRES_USER / POSTGRES_PASSWORDPostgreSQLDatabase credentials
REDIS_PASSWORDRedisCache authentication
STORAGE_ACCESS_KEY / STORAGE_SECRET_KEYMinIOObject storage credentials