Skip to content

Backend Operations

Eric Slutz edited this page Jun 24, 2026 · 7 revisions

Backend Operations

PumpSync Backend runs the same ASP.NET Core container image for hosted service and self-host/demo distribution, with different configuration.

Hosted Mode

Hosted PumpSync runs on Azure Container Apps with Azure Table Storage.

  • PumpSync__BackendMode=Hosted
  • PumpSync__DataSourceMode=TandemSource
  • PumpSync__StorageProvider=AzureTableStorage
  • Azure Container Apps scale minimum: 0
  • Public app base URL includes /api
  • App Store Server Notification URL is /api/v1/app-store/notifications

Infrastructure

infra/bicep/main.subscription.bicep creates or updates:

  • Resource group.
  • Azure Container Apps managed environment.
  • Backend container app.
  • User-assigned managed identity.
  • Key Vault.
  • App Configuration store.
  • Application Insights and Log Analytics.
  • Storage account and Table Storage tables.
  • Optional managed identity role assignments.

Build the templates:

az bicep build --file infra/bicep/main.bicep
az bicep build --file infra/bicep/main.subscription.bicep

Deploy with the GitHub Deploy Backend workflow. The workflow restores, builds, tests, builds and pushes the Docker image to GitHub Container Registry, deploys Bicep with that image, runs smoke tests, and prints the hosted API base URL and App Store Server Notification URL.

Image Registry Policy

Image use Registry Visibility Notes
Hosted production/nonprod API GitHub Container Registry Private Published as ghcr.io/eslutz/pumpsync-backend:latest for Container Apps runtime pulls, with commit SHA tags also published for traceability.
Self-host/demo distribution image GitHub Container Registry Public Published as ghcr.io/eslutz/pumpsync-backend-self-hosted:latest for Docker Compose and demo deployments.

The iOS app does not choose a registry. It only stores a backend base URL.

Hosted Environment Validation

Public docs intentionally avoid listing live hosted backend endpoint values. Use the Deploy Backend workflow output, Azure Container Apps configuration, App Configuration, or trusted operator notes to retrieve the current hosted base URL.

Current hosted image recorded in backend docs:

ghcr.io/eslutz/pumpsync-backend:latest

Smoke test:

curl --fail <hosted-api-base-url>/v1/capabilities
curl --silent --output /tmp/status.json --write-out '%{http_code}' <hosted-api-base-url>/v1/status

The unauthenticated status call should return 401.

Hosted Synthetic Demo

Hosted demo API base URL:

https://demo.pumpsync.ericslutz.dev/api

Current demo Container App recorded in backend docs:

ca-pumpsync-demo-api

Current demo image recorded in backend docs:

ghcr.io/eslutz/pumpsync-backend-self-hosted:latest

The demo Container App pulls the public self-host/demo GHCR image without registry credentials.

Private GHCR Pull Token

Hosted Container Apps pulls from private GitHub Container Registry with a classic GitHub token that has only read:packages.

Do not grant:

  • repo
  • write:packages
  • delete:packages

The runtime token is stored in Key Vault as GitHubContainerRegistry--PullToken and exposed to Container Apps through a Key Vault-backed secret named ghcr-pull-token.

Data Deletion Tooling

The data deletion tool is in tools/PumpSync.DataDeletionRequest.

Build:

dotnet build tools/PumpSync.DataDeletionRequest/PumpSync.DataDeletionRequest.csproj

Hosted dry run:

dotnet run --project tools/PumpSync.DataDeletionRequest -- \
  --installation-id <installation-id> \
  --environment nonprod

Hosted execute:

DataDeletion__AuditHashSalt=<salt> \
dotnet run --project tools/PumpSync.DataDeletionRequest -- \
  --installation-id <installation-id> \
  --environment nonprod \
  --execute

Use --environment prod for production. Configure Azure storage with AzureStorage__AccountName plus Azure CLI/managed identity credentials, or with AzureStorage__ConnectionString.

Self-host execution uses SQLite configuration and should only run after backing up the SQLite database.

Clone this wiki locally