Skip to main content

Deploying a Siter Environment

This guide walks through deploying a Siter environment using Docker Compose. A standard deployment consists of four services:

  • Siter API — the backend application server
  • Siter UI — the frontend web application
  • PostgreSQL — the primary database (with PostGIS for spatial data)
  • Pufferfish API — the analysis engine for facility evaluation

Optionally, you can also add:

  • MongoDB — enables bug report, test case, and criteria reference features in Pufferfish, as well as MongoDB log shipping
  • Grafana Loki — centralized log aggregation for Pufferfish

Prerequisites

  • Docker and Docker Compose installed on the host machine
  • Access to the Siter container registry (provided by the Siter team)
  • A valid Siter license (provided by the Siter team)

Base Docker Compose Configuration

Below is a base docker-compose.yaml you can use as a starting point. Copy this file and customize the environment variables for your deployment.

networks:
siter:

services:
# ── Siter API (backend) ──────────────────────────────────────────
siter-api:
image: <provided-by-siter-team>/siterapi:latest
ports:
- 5000:5000
networks:
- siter
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://0.0.0.0:5000
- ConnectionStrings__SITER_DB=Host=siter-db;Port=5432;Database=siterdb;Username=siter;Password=CHANGE_ME
- LoginTypes=20
- multiTenant=false
- corsUrls=["https://siter.example.com"]
- AnalysisOptions__AnalysisUrl=http://pufferfish:26667
- AnalysisOptions__DictionaryUrl=http://pufferfish:26667
- Licensing__PublicKey=PROVIDED_BY_SITER_TEAM
- jwt__AuthDomain=siter
- jwt__AuthKey=CHANGE_ME_TO_A_LONG_RANDOM_STRING
- jwt__AuthMinutes=480
depends_on:
siter-db:
condition: service_healthy
pufferfish:
condition: service_started

# ── Siter UI (frontend) ─────────────────────────────────────────
siter-ui:
image: <provided-by-siter-team>/siterui:latest
ports:
- 80:80
networks:
- siter

# ── PostgreSQL + PostGIS (Siter database) ───────────────────────
siter-db:
image: postgis/postgis:18-3.6
networks:
- siter
ports:
- 5432:5432
volumes:
- siter-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=siterdb
- POSTGRES_USER=siter
- POSTGRES_PASSWORD=CHANGE_ME
healthcheck:
test: ["CMD-SHELL", "pg_isready -U siter -d siterdb"]
interval: 5s
timeout: 5s
retries: 5

# ── Pufferfish API (analysis engine) ────────────────────────────
pufferfish:
image: <provided-by-siter-team>/pufferfish:latest
ports:
- 26667:26667
networks:
- siter
environment:
- PINO_LOG_LEVEL=warn

volumes:
siter-data:
warning

Replace all CHANGE_ME values with secure, unique passwords before deploying. The jwt__AuthKey should be a long, random string used to sign authentication tokens.

Starting the Environment

docker compose up -d

On first startup, Siter will automatically run database migrations to initialize the schema. You can verify the services are running with:

docker compose ps

The API will be available at http://localhost:5000, the UI at http://localhost:80, and the Pufferfish analysis engine at http://localhost:26667.

Environment Variables Reference

All configuration in Siter follows the ASP.NET Core configuration model. Environment variables override values from config files and use double underscores (__) as separators for nested settings (e.g., AnalysisOptions__AnalysisUrl).

Core Application

VariableRequiredDefaultDescription
ASPNETCORE_ENVIRONMENTNoProductionThe application environment name.
ASPNETCORE_URLSNoThe URL(s) for Kestrel to listen on (e.g., http://0.0.0.0:5000).

Database Connection

The database connection can be configured as a full connection string or as individual components. If both are provided, the full connection string takes precedence.

Option A: Full connection string

VariableRequiredDefaultDescription
ConnectionStrings__SITER_DBYes*Full PostgreSQL connection string (e.g., Host=db;Port=5432;Database=siterdb;Username=siter;Password=pass).

Option B: Individual components

VariableRequiredDefaultDescription
SITER_DB_SERVERYes*Database server hostname or IP address.
SITER_DB_USERYes*Database username.
SITER_DB_PWYes*Database password.
SITER_DB_DATAYes*Database name.

* One of Option A or Option B is required.

Database Behavior

VariableRequiredDefaultDescription
SITER_NO_MIGRATIONSNofalseSet to true to disable automatic database migrations on startup. Useful for environments where migrations are applied separately.

Authentication

VariableRequiredDefaultDescription
LoginTypesNo0 (None)Bitmask controlling which authentication methods are enabled. See Login Types below.
jwt__AuthDomainYesThe issuer and audience string used when generating and validating JWT tokens.
jwt__AuthKeyYesThe secret key used to sign JWT tokens. Must be a long, random string.
jwt__AuthMinutesNo480How long (in minutes) JWT tokens remain valid before expiring.

Login Types

LoginTypes is a bitmask (flags enum). Combine values by adding them together.

ValueTypeDescription
1LoginReserved.
2WindowsWindows/Kerberos authentication (NTLM/Negotiate).
4GoogleGoogle OAuth sign-in.
8NoAuthAuto-login without credentials. Development/testing only.
16MicrosoftMicrosoft Entra ID (Azure AD) sign-in.
32Active DirectoryOn-premises Active Directory (LDAP) sign-in.

Common configurations:

ValueMethodsUse Case
12Google + NoAuthDevelopment with quick login
20Google + MicrosoftProduction (typical)
4Google onlyProduction (Google only)
16Microsoft onlyProduction (Microsoft only)
48Microsoft + Active DirectoryProduction (hybrid cloud + on-prem)
32Active Directory onlyAir-gapped / on-premises only

Microsoft Entra ID (Azure AD) SSO

These are required when Microsoft login is enabled (LoginTypes includes 16). See the SSO Setup Guide for detailed instructions on configuring the Azure App Registration.

VariableRequiredDefaultDescription
AzureAd__ClientIdConditionalThe Application (client) ID from your Azure App Registration.
AzureAd__RedirectUriConditionalThe redirect URI configured in your App Registration (must match exactly).
AzureAd__InstanceNohttps://login.microsoftonline.com/The Azure AD authority URL. Change for government clouds (e.g., https://login.microsoftonline.us/).
AzureAd__TenantIdNocommonThe Azure AD tenant ID. Use common for multi-tenant, or a specific tenant GUID to restrict access.

Active Directory (LDAP)

These settings provide default values for Active Directory authentication when no SSO configuration exists for a user's email domain. In most deployments, AD settings are managed per-organization through the Admin > SSO Integrations UI instead.

VariableRequiredDefaultDescription
ActiveDirectory__ServerNoDefault AD domain controller hostname or IP. Only used as fallback when no SSO config matches the user's email domain.
ActiveDirectory__PortNo636LDAP port. Use 636 for LDAPS (recommended) or 389 for plain LDAP.
ActiveDirectory__UseSslNotrueWhether to use TLS for the LDAP connection.
ActiveDirectory__DefaultUpnSuffixNoOptional UPN suffix override. When set, replaces the email domain in the UPN sent to AD (e.g., if users sign in with user@company.com but the AD UPN is user@corp.local).
ActiveDirectory__SkipCertificateValidationNofalseDevelopment only. Set to true to disable TLS certificate validation for LDAP connections. In production, the API container must trust the AD domain controller's CA certificate — see TLS Certificate Setup below.

Active Directory TLS Certificate Setup

AD domain controllers use certificates issued by the organization's internal Certificate Authority (typically AD Certificate Services). The Siter API container must trust this CA for LDAPS connections to succeed.

To configure certificate trust, volume-mount the CA root certificate into the API container and run update-ca-certificates before the application starts:

siter-api:
volumes:
- ./certs/ca-root.crt:/usr/local/share/ca-certificates/ad-ca-root.crt:ro
entrypoint: ["/bin/sh", "-c", "update-ca-certificates && dotnet Siter.Api.dll"]
warning

Do not set ActiveDirectory__SkipCertificateValidation=true in production. This disables certificate validation for all LDAP connections from the API and exposes the connection to man-in-the-middle attacks.

Licensing

VariableRequiredDefaultDescription
multiTenantNofalseSet to true for multi-tenant deployments where each customer/organization has its own license. Set to false for single-tenant deployments with one system-wide license.

Analysis Engine (Pufferfish)

The analysis engine (Pufferfish) provides automated facility evaluation capabilities. When running in the same Docker Compose stack, point these at the internal service name (e.g., http://pufferfish:26667).

VariableRequiredDefaultDescription
AnalysisOptions__AnalysisUrlYesURL of the Pufferfish analysis engine (e.g., http://pufferfish:26667).
AnalysisOptions__DictionaryUrlYesURL of the criteria dictionary service. Typically the same as the analysis URL.
AnalysisOptions__UseWktNofalseSet to true to transmit geometry data as WKT instead of WKB format.

CORS

VariableRequiredDefaultDescription
corsUrlsNoJSON array of allowed CORS origins. Must include the URL where your UI is hosted (e.g., ["https://siter.example.com"]). Required when the UI and API are served from different origins.

Seed Administrator Account

On first startup, you can automatically create a system administrator account.

VariableRequiredDefaultDescription
SITER_SANoCreates a seed SA account. Format: LOGIN::LOGIN_TYPE::DISPLAY_NAME. The LOGIN_TYPE is the numeric value from the Login Types table (e.g., user@example.com::16::Jane Doe for a Microsoft account).

UI and Hosting

These are typically only needed in standalone or self-hosted deployments where the API serves the UI directly.

VariableRequiredDefaultDescription
useDefaultFilesNofalseSet to true to have the API serve static UI files from wwwroot.
wwwRootNoCustom path to the static content folder (when useDefaultFiles is true).
baseHrefNo/Base href for the Angular application.
useResponseCompressionNotrueEnables Brotli/Gzip response compression.

Telemetry and Debugging

VariableRequiredDefaultDescription
EnableTelemetryNotrueEnables internal process statistics collection.
echoRequestsNofalseLogs all incoming HTTP requests to the console. Useful for debugging.
SiterEnableDbContextSensitiveLoggingNofalseEnables Entity Framework sensitive data logging. Do not enable in production as it may log passwords and other sensitive values.

PostgreSQL Container

These variables configure the PostgreSQL container itself (not the Siter application).

VariableRequiredDefaultDescription
POSTGRES_DBYesName of the database to create.
POSTGRES_USERYesDatabase superuser name.
POSTGRES_PASSWORDYesDatabase superuser password.

Pufferfish Container

These variables configure the Pufferfish analysis engine service.

VariableRequiredDefaultDescription
PINO_LOG_LEVELNowarnLogging verbosity. One of debug, info, warn, error.
DB_IPNoHostname of a MongoDB instance. Enables bug report, test case, and criteria reference routes, as well as MongoDB log shipping.
DB_PORTNo27017Port of the MongoDB instance. Only used when DB_IP is set.
LOKI_IPNoHostname of a Grafana Loki instance for centralized log shipping.
LOKI_PORTNoPort of the Loki instance. Required when LOKI_IP is set.
VERSIONNodevelopmentApplication version string (informational).

Configuration Precedence

Siter loads configuration in the following order, where later sources override earlier ones:

  1. appsettings.json (base defaults, built into the image)
  2. appsettings.{ASPNETCORE_ENVIRONMENT}.json (environment-specific overrides)
  3. Environment variables (the primary way to configure deployments)
  4. Command-line arguments

For most deployments, environment variables in the Docker Compose file are the recommended configuration method.

Verifying Your Deployment

After starting the services, verify the deployment:

  1. API health: Navigate to http://localhost:5000/swagger to confirm the API is running.
  2. Database connectivity: Check the API container logs for the DB: log line confirming the connection string.
  3. Analysis engine: Check the Siter API logs for the line listing supported criteria types — this confirms the API can reach Pufferfish. If the engine is unreachable, you'll see a warning — the application will still start but analysis features will be unavailable until the engine is accessible. You can also verify Pufferfish directly at http://localhost:26667.
  4. Authentication: Navigate to the UI and confirm the expected login options appear.