Short guide for running the app on a Docker-capable Linux VPS (Phase 4). For build/run on a dev machine see USAGE.md.
From the repository root:
docker build -t insurance-integration .The multi-stage Dockerfile restores/publishes with the .NET 10 SDK image and runs on the smaller ASP.NET runtime image as a non-root user.
docker run -d \
--name insurance-integration \
-p 8080:8080 \
-v insurance-data:/data \
--restart unless-stopped \
insurance-integrationKey facts:
- The app listens on port 8080 inside the container (
ASPNETCORE_URLS=http://+:8080). - The SQLite database is written to
/data/integration.db(overridden viaConnectionStrings__Integration). The named volumeinsurance-datakeeps data across container replacement; migrations run automatically on startup. - Environment defaults to
Production, which disables Swagger UI, the development data seeder, and the read-only DB browser at/database. Set-e ASPNETCORE_ENVIRONMENT=Developmentto get them back (not for real exposure), or-e DatabaseBrowser__Enabled=trueto force-enable just the DB browser. - A container
HEALTHCHECKprobesGET /health.
Verify:
curl http://localhost:8080/health-
Provision a Linux VPS with root access (Docker requires it; shared/cPanel hosting will not work).
-
Install Docker Engine: https://docs.docker.com/engine/install/ (pick your distro).
-
Copy the repo to the VPS (
git cloneorscp), then build and run as above. -
Put a reverse proxy with TLS in front (Caddy is the least-config option):
# /etc/caddy/Caddyfile your-domain.example { reverse_proxy localhost:8080 }Caddy obtains and renews Let's Encrypt certificates automatically. Nginx + certbot works too.
-
Do not expose the app without a proxy/firewall. The read-only DB browser at
/databaseis now gated: it is off by default outside Development and returns404(seePROGRESS.md). To deliberately expose it, setDatabaseBrowser__Enabled=true- and even then put auth in front at the proxy (e.g. basic auth or IP allowlist on/database).
git pull
docker build -t insurance-integration .
docker stop insurance-integration && docker rm insurance-integration
# re-run the docker run command above; data persists in the insurance-data volumeThe whole database is one SQLite file:
docker run --rm -v insurance-data:/data -v "$PWD":/backup alpine \
cp /data/integration.db /backup/integration-$(date +%F).db