HomeBlogFleet Management
Fleet Management · Engineering

Deploying Fleet Management Software with Docker and Kubernetes: A Practical Guide

CG
Cloudkasten GmbH
Mar 08, 20265 min read
mobilitymanager.io/en/blog/fleet-software-docker-kubernetes-deployment/
Deploying Fleet Management Software with Docker and Kubernetes: A Practical Guide

Most fleet management software documentation assumes you’ll deploy to a Windows Server and call it done. For organizations running container-based infrastructure — Docker, Kubernetes, or hybrid setups — that’s not good enough. This guide covers what containerized deployment of fleet management software actually looks like in practice.

Why Container Deployment Matters for Fleet Software

The shift to containerized infrastructure in enterprise IT is well underway. Organizations running Kubernetes clusters for their workloads don’t want to carve out a dedicated Windows VM for every business application. And they shouldn’t have to.

Container-based fleet software deployment offers:

  • Infrastructure consistency: Same deployment process across dev, staging, and production
  • Portability: Runs on any cloud provider, on-premise hardware, or hybrid setup
  • Automatic recovery: The orchestrator restarts a failed container on its own
  • Simplified updates: Pull a new image, roll it out, roll back if needed
  • GitOps-friendly: Declarative configuration in version control

MobilityManager in a Container

MobilityManager is built on .NET 10 and Angular 21. One official image contains both the API and the web interface:

  • One image, one port: cloudkasten/mobilitymanager on Docker Hub, built for linux/amd64, listening on port 8080 and running as a non-root user
  • Both database backends: SQL Server and PostgreSQL, selected with a single setting
  • Health endpoints: /livez and /readyz for Kubernetes probes, /healthz for monitoring
  • Configured through environment variables: ASP.NET Core’s Section__Key convention, no config file editing in the container
  • Schema migrations on start: a new version updates its databases when the container starts

Docker Compose Setup

A minimal docker-compose.yml for MobilityManager with PostgreSQL:

services:
  mobilitymanager:
    image: cloudkasten/mobilitymanager:1.13.0   # pin a release instead of "latest"
    ports:
      - "8080:8080"
    environment:
      ASPNETCORE_ENVIRONMENT: Production
      DatabaseProvider: PostgreSQL
      ConnectionStrings__SystemConnection: Host=db;Database=mobilitymanager_system;Username=mm_user;Password=${DB_PASSWORD}
      ConnectionStrings__DefaultConnection: Host=db;Database=mobilitymanager_tenant;Username=mm_user;Password=${DB_PASSWORD}
      Jwt__Key: ${JWT_KEY}
      DocumentStorage__LocalEncryptionKey: ${DOCUMENT_ENCRYPTION_KEY}
      License__PublicKey: ${LICENSE_PUBLIC_KEY}
    volumes:
      - appdata:/app/data
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: mm_user
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: mobilitymanager_system
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U mm_user -d mobilitymanager_system"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  appdata:
  pgdata:

Key configuration notes:

  • Secrets (DB_PASSWORD, JWT_KEY, DOCUMENT_ENCRYPTION_KEY) belong in a .env file or a secret manager — never in the compose file. The application refuses to start in production with a weak or well-known JWT key, and it requires the document encryption key (a base64-encoded 32-byte value) while encryption at rest is on.
  • LICENSE_PUBLIC_KEY is the public half of the license signing key. It is the same for every installation; without it the application rejects every license.
  • Mount a volume at /app/data and point the local document storage path at it in the document storage settings, or store documents in Azure Blob Storage or S3 instead. Otherwise uploaded documents live inside the container.
  • The depends_on with service_healthy ensures the database is ready before the app starts, and restart: unless-stopped brings it back after host reboots.

Kubernetes Deployment

The same image runs in any Kubernetes cluster. A plain Deployment and Service are enough. Keep secrets in a Kubernetes Secret and documents on a persistent volume or in object storage:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mobilitymanager
  namespace: fleet-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mobilitymanager
  template:
    metadata:
      labels:
        app: mobilitymanager
    spec:
      containers:
        - name: mobilitymanager
          image: cloudkasten/mobilitymanager:1.13.0
          ports:
            - containerPort: 8080
          env:
            - name: ASPNETCORE_ENVIRONMENT
              value: Production
            - name: DatabaseProvider
              value: PostgreSQL
          envFrom:
            - secretRef:
                name: mobilitymanager-secrets   # connection strings, Jwt__Key, DocumentStorage__LocalEncryptionKey
          volumeMounts:
            - name: appdata
              mountPath: /app/data
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              memory: 1Gi
      volumes:
        - name: appdata
          persistentVolumeClaim:
            claimName: mobilitymanager-data
---
apiVersion: v1
kind: Service
metadata:
  name: mobilitymanager
  namespace: fleet-system
spec:
  selector:
    app: mobilitymanager
  ports:
    - port: 80
      targetPort: 8080

Put your cluster’s ingress controller in front of the Service for HTTPS. Start with one replica: the application runs its scheduled background work (reminders, imports, e-mail dispatch) inside the same process. Talk to us before running several replicas.

Health Probes Configuration

MobilityManager exposes three health endpoints:

livenessProbe:
  httpGet:
    path: /livez
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 15

readinessProbe:
  httpGet:
    path: /readyz
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5

startupProbe:
  httpGet:
    path: /healthz
    port: 8080
  failureThreshold: 30
  periodSeconds: 10
  • /livez — the application process is alive (Kubernetes restarts the container if it fails)
  • /readyz — the application is ready to receive traffic
  • /healthz — the combined status of all registered checks

The probes report the state of the application process. Monitor the database server separately with your usual tooling.

Database Configuration

PostgreSQL (recommended for new deployments):

DatabaseProvider=PostgreSQL
ConnectionStrings__SystemConnection=Host=db;Port=5432;Database=mobilitymanager_system;Username=mm_user;Password=secret;Pooling=true
ConnectionStrings__DefaultConnection=Host=db;Port=5432;Database=mobilitymanager_tenant;Username=mm_user;Password=secret;Pooling=true

SQL Server:

DatabaseProvider=SqlServer
ConnectionStrings__SystemConnection=Server=db,1433;Database=mobilitymanager_system;User Id=mm_user;Password=secret;TrustServerCertificate=true
ConnectionStrings__DefaultConnection=Server=db,1433;Database=mobilitymanager_tenant;User Id=mm_user;Password=secret;TrustServerCertificate=true

The system database holds users, tenants and settings; each tenant gets its own database. When you add a tenant, MobilityManager can create that database on the same server, provided the database user has the right to create databases. The schema is migrated automatically on start.

TLS Termination

In Kubernetes, handle TLS at the ingress level (nginx-ingress, Traefik, or your cloud provider’s ingress controller). MobilityManager itself runs HTTP internally; the ingress handles HTTPS termination.

For Docker Compose in smaller setups, terminate TLS with a reverse proxy (nginx, Caddy, Traefik) upstream from the application container.

What running it on your own infrastructure actually requires — Docker, Kubernetes or classic on-premise — is set out on the self-hosted fleet management page.

Conclusion

Fleet management software has no business requiring a dedicated Windows Server in 2026. MobilityManager ships as one container image configured through environment variables, so it fits organizations running modern infrastructure — whether that’s a simple Docker Compose setup on a VM, or a Kubernetes cluster with your own ingress, secrets and storage.

Request a technical demo with your infrastructure team →

Bereit für professionelles Flottenmanagement?

Entdecken Sie MobilityManager in einer persönlichen Demo. On-Premise Installation in Ihrem Rechenzentrum, Self-Service Buchungen für Ihre Mitarbeiter, intelligente Auto-Zuweisung, volle DSGVO-Konformität – Made in Germany.

Jetzt kostenlose Demo vereinbaren