Skip to main content

Hosting and environments

This page explains where and how a Stack9 instance runs: how the container image is built, which AWS services it runs on, how environments are laid out, and where data lives. It is written for developers and architects who need to understand the runtime their configuration lands in.

What is a Stack9 instance at runtime?

Stack9 Core is distributed as a Docker container image. Each client's instance is a dedicated instance image, built by layering the client's own configuration (entities, queries, screens, automations, MCP configs, custom code) on top of the standard Stack9 Core base image.

Two properties follow from this layering:

  • Isolation. Each client's instance is its own image at its own hostname: an isolated application layer.
  • A common upgrade path. April9 rebuilds the base image and each client's instance image centrally, so a platform release applies to a customised instance without being blocked by, or breaking, its customisations. See Release and upgrade model.

What happens when a container starts

Every container start runs the bootstrap in apps/core/src/bootstrap.ts. It applies the framework's own database migrations, then the instance's migrations from its built dist/database/migrations, synchronises the database schema with the instance's entity definitions, registers the Console app, and reconciles cron jobs. Bootstrap is designed to be idempotent: it runs on every restart and must stay safe against a partially completed earlier run. This is what lets a release bring the new schema and the application version that depends on it into service together, without a manual migration step.

Why AWS, and why this shape

Stack9 is built to use AWS-native services by default, and April9 is an AWS partner. The infrastructure pattern follows the AWS Well-Architected Framework and is the same pattern every Stack9 instance runs, so scaling and resilience are properties of the architecture rather than something added per engagement. A named AWS Solutions Architect reviews the cloud architecture, the AI workload deployment and cost optimisation during design and before go-live.

How it works

AWS service stack

ServiceRole
ECSContainer orchestration for Stack9 instances
RDS Aurora (serverless)Database, autoscaling
S3Document binaries and audit record versions
SQSMessage queuing
EventBridgeEvent scheduling
API GatewayConsolidation of external system integrations
CognitoPortal identity layer, fronting the client's identity provider
CloudTrailInfrastructure-level audit
Bedrock AgentCoreRuntime for Stack9 AI Agents
CloudWatchInfrastructure and application monitoring with configurable alert thresholds
AWS WAF and network-level filteringFiltering of distributed denial-of-service and other malicious traffic before it reaches the application tier

The database sits in a secure subnet within a private VPC, with no direct internet exposure: only the application's running containers can reach it.

Deployment models

The container-based architecture supports several deployment models from one codebase.

ModelSummaryWhen it fits
Cloud-native / containerised (recommended)Instances run on AWS ECS and supporting serverless services. The client owns the AWS account; April9 provides managed operationGovernment and enterprise. Offered as a Managed Hosted Service in a dedicated, single-tenant AWS environment in Sydney (ap-southeast-2), with AWS consumption on-charged at cost and the account transferable to the client
PaaSThe same managed ECS model, described as platform-as-a-service for procurement frameworks that ask for itAs above
Hybrid / self-hostedAs a standard Docker image, Stack9 Core can run outside AWSAzure is technically supported with some performance trade-offs. Other infrastructure is not recommended without further validation
SaaS (multi-tenant)Shared hosting resources across clients to reduce costCost-driven workloads only. Not recommended where full infrastructure isolation is required, and not proposed where personal information is in scope

The hosting and deployment pattern is a discovery deliverable, documented in the Technical Solution Design and approved by the client before any environment is provisioned.

Environment layout

A typical instance runs three environments across two AWS accounts:

  • Production sits alone in its own account, so no non-production activity, credential or misconfiguration can reach it.
  • DEV and UAT share the non-production account but are isolated from each other at the application and data layer, each with its own configuration and secrets.
  • All three are provisioned as infrastructure as code from the same definitions through automated pipelines, so they are reproducible and consistent, and a disaster-recovery rebuild is a redeploy rather than a repair.
  • No client production data is used in non-production. Test data is synthetic, generated against the domain model and the agreed test scenarios.
  • UAT and Production can be published under client-issued subdomains (for example solution-uat.client.gov.au), delegated through the client's DNS, with TLS certificates provisioned against the client-issued name.
Tell your tools which environment they are in

Local, DEV, UAT and Production serve identical MCP configs. Each instance's MCP endpoint labels itself with the instance name, ENVIRONMENT_TYPE and host (for example Pages MCP [my-app · UAT · uat-my-app.example.com]), and the built-in stack9_whoami tool returns the same details. Set ENVIRONMENT_TYPE per environment so agents and developers can tell them apart. See Connect Claude Code to a Stack9 MCP endpoint.

Autoscaling

Stack9 instances deploy on fully autoscaling infrastructure:

  • a serverless database (RDS Aurora);
  • serverless containers that scale on memory, CPU or HTTP request volume;
  • queue-based workloads that additionally scale on queue depth and processing load.

Hosting cost therefore follows actual usage rather than capacity sized for peak demand all year. Integrations into a client's own systems can be queued and throttled, so a spike in portal traffic does not become an equivalent spike on the client's systems of record.

Performance targets

TargetPosition
Transactional response within 3 secondsConventional transactions (page and data requests, form-step submissions, validation, saves, document uploads, status queries) complete well within this. Data capture is decoupled from processing: the request is acknowledged once data is safely captured, and longer-running work is queued behind it
AI-generated responsesThe stated exception. An answer involving model inference and retrieval is bounded by the model and can exceed 3 seconds. Responses stream, and AI response times are reported separately from transactional ones
Administrative concurrencyNo limit on concurrent administrative users. Bulk administrative operations run through the queue rather than holding a session

Load and stress testing is run in a production-like environment before go-live, including concurrent administrative load, and pushed past the target profile to the point of degradation so the actual limit is known.

Data residency

ElementLocation
Production workloads, metadata, logsAWS ap-southeast-2 (Sydney)
Backups (point-in-time recovery, daily snapshots, monthly full backups)Replicated to AWS ap-southeast-4 (Melbourne)
Disaster recoveryap-southeast-4 (Melbourne)
AI processing (Stack9 AI Agents on Amazon Bedrock AgentCore): inference, prompts, retrieved content, responses, indexed contentap-southeast-2 (Sydney)
Support accessApril9's onshore Australian team only
Network egressRestricted to Australian regions

All other AWS regions are disabled by default in April9's deployment templates. No data leaves Australian AWS regions: the cross-region replication to Melbourne provides disaster-recovery resilience while keeping all data within Australia.

Operational notes for developers

  • SERVER_BASE_URL must be a usable URL. It is the OAuth issuer and the base of every MCP resource identifier. If it cannot be parsed, the MCP endpoint answers 503 rather than accept tokens it cannot audience-check. See MCP Server.
  • The MCP endpoint is stateless. Every request stands alone, so running several Core replicas needs no sticky routing for MCP traffic.
  • OAuth grant state lives in the cache. Pending authorisation requests, authorisation codes and refresh tokens for MCP clients are held in the instance's cache service (Redis), so it must be shared across replicas.

Limits

  • AWS is where Stack9 is optimised. Azure works with performance trade-offs; anything else needs validation before it is offered.
  • Multi-tenant SaaS trades isolation for cost. It is not offered where infrastructure isolation is required or where personal information is in scope.
  • Load evidence and volume profiling. Autoscaling is a property of the architecture, but volume profiling for a specific new workload is still a discovery activity, and a total-user figure is not a concurrency figure.
  • Latency and availability commitments cover the supplier-controlled path only, not the client's own WAN, carrier or egress.
  • AI response times are model-bound and reported separately.