Publisert - 07.05.2026

Deployment

Local Development

Prerequisites

  • .NET 10 SDK
  • Docker and Docker Compose

Start all services

docker-compose up -d

This starts:

  • MongoDB on port 27017
  • Mongo Express (admin UI) on port 8081
  • API on port 5069
  • Frontend on port 5173

To start only the database services:

docker-compose up -d mongodb mongo-express

Configure API keys

Copy or edit appsettings.Development.json:

{
  "Sync": {
    "UpstreamApiKey": "your-upstream-api-key"
  },
  "ApiKeys": [
    "dev-test-key-1"
  ]
}

Run the API

cd Api
dotnet run

The API starts on http://localhost:5069 (see Properties/launchSettings.json).

Test endpoints

Use the provided Api.http file (works with VS Code REST Client or JetBrains HTTP Client):

# Trigger sync
curl -X POST http://localhost:5069/api/internal/sync \
  -H "X-API-KEY: dev-test-key-1"

# Fetch treatment groups
curl http://localhost:5069/api/v1/treatmentGroup \
  -H "X-API-KEY: dev-test-key-1"

MongoDB Indexes

Indexes are created automatically on application startup via AppDbContext.EnsureIndexesAsync():

Collection Index Type
TreatmentGroups BusinessKey Unique
TreatmentGroups Version Ascending
ReimbursementGroups BusinessKey Unique
ReimbursementGroups Version Ascending

These indexes ensure:

  • Upserts by BusinessKey are efficient
  • Queries with ?sinceVersion=N are fast (version index)

Kubernetes Deployment

API Deployment

Standard ASP.NET Core deployment. Key environment variables:

env:
  - name: ConnectionStrings__DefaultConnection
    valueFrom:
      secretKeyRef:
        name: nompd-secrets
        key: mongodb-connection-string
  - name: Sync__UpstreamApiKey
    valueFrom:
      secretKeyRef:
        name: nompd-secrets
        key: upstream-api-key
  - name: ApiKeys__0
    valueFrom:
      secretKeyRef:
        name: nompd-secrets
        key: client-api-key-1

Sync CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: nompd-sync
spec:
  schedule: "0 2 * * *"   # Every night at 02:00
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 5
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      backoffLimit: 3
      template:
        spec:
          containers:
          - name: sync
            image: curlimages/curl
            command:
            - curl
            - -X POST
            - -H "X-API-KEY: $(SYNC_API_KEY)"
            - -f
            - --retry 3
            - --retry-delay 10
            - https://nompd-api.internal/api/internal/sync
          restartPolicy: OnFailure
          envFrom:
          - secretRef:
              name: nompd-sync-secrets

Key settings:

  • concurrencyPolicy: Forbid prevents overlapping syncs
  • backoffLimit: 3 retries failed jobs
  • curl -f makes curl return non-zero exit code on HTTP errors, so K8s knows the job failed

Health Checks

Consider adding a health check endpoint (not API key protected) for K8s liveness/readiness probes:

GET /health → 200 OK

Docker Build

The API Dockerfile uses a multi-stage build with layer caching for NuGet restore. Note that docker-compose.yaml sets context: ./Api, so paths are relative to the Api directory.

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY Api.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app

FROM mcr.microsoft.com/dotnet/aspnet:10.0
WORKDIR /app
COPY --from=build /app .
EXPOSE 8080
ENV ASPNETCORE_URLS=http://+:8080
ENTRYPOINT ["dotnet", "Api.dll"]

Søk i Utviklerportalen

Søket er fullført!