-
Notifications
You must be signed in to change notification settings - Fork 0
Backend Operations
PumpSync.backend runs the same ASP.NET Core container image for hosted service and self-host/demo distribution, with different configuration.
Hosted PumpSync runs on Azure Container Apps with Azure Table Storage.
PumpSync__BackendMode=HostedPumpSync__DataSourceMode=TandemSourcePumpSync__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
infra/bicep/main.subscription.bicep creates or updates:
- Resource group.
- Azure Container Apps managed environment.
- Backend container app (with HTTP liveness/readiness probes against
/health). - User-assigned managed identity.
- Key Vault.
- Application Insights and Log Analytics.
- Storage account and Table Storage tables.
- Optional managed identity role assignments.
An App Configuration store from an earlier iteration is no longer part of the template; nothing reads or writes it, so any live instance can be deleted.
Build the templates:
az bicep build --file infra/bicep/main.bicep
az bicep build --file infra/bicep/main.subscription.bicepDeploy 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 use | Registry | Visibility | Notes |
|---|---|---|---|
| Hosted production/nonprod API | GitHub Container Registry | Private |
ghcr.io/eslutz/pumpsync-backend. The deploy workflow deploys the immutable commit-SHA tag to Container Apps and also pushes floating nonprod-latest/prod-latest tags; a bare latest is pushed only on prod deploys. |
| Self-host/demo distribution image | GitHub Container Registry | Public |
ghcr.io/eslutz/pumpsync-backend-self-hosted, published by the Publish Self-Host Image workflow (SHA + latest) on every backend change that lands on main. Used by Docker self-hosters and the demo Container App. |
The iOS app does not choose a registry. It only stores a backend base URL.
Public docs intentionally avoid listing live hosted backend endpoint values. Use the Deploy Backend workflow output, Azure Container Apps configuration, or trusted operator notes to retrieve the current hosted base URL.
The Container App runs the commit-SHA image tag printed by the deploy workflow, not :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/statusThe unauthenticated status call should return 401.
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.
Hosted Container Apps pulls from private GitHub Container Registry with a classic GitHub token that has only read:packages.
Do not grant:
repowrite:packagesdelete: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.
The data deletion tool is in tools/PumpSync.DataDeletionRequest.
Build:
dotnet build tools/PumpSync.DataDeletionRequest/PumpSync.DataDeletionRequest.csprojHosted dry run:
dotnet run --project tools/PumpSync.DataDeletionRequest -- \
--installation-id <installation-id> \
--environment nonprodHosted execute:
DataDeletion__AuditHashSalt=<salt> \
dotnet run --project tools/PumpSync.DataDeletionRequest -- \
--installation-id <installation-id> \
--environment nonprod \
--executeUse --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.
PumpSync documentation: iOS repository · Backend repository · Issues