Deployment Pipeline

ContentGrid applications are deployed through a fully automated pipeline that transforms high-level application models into running services. The deployment process is managed by the Management Platform and executed in the Runtime Platform.

Deployment Overview

The deployment pipeline bridges two environments:

Management Platform: Where you define application models, configure settings, and initiate deployments. This is the control plane.

Runtime Platform: Where applications actually run, serving APIs to end-users. This is the data plane.

The pipeline ensures consistent, repeatable deployments with zero manual intervention required for the deployment mechanics.

Management Platform Components

The deployment pipeline is orchestrated by three Management Platform components:

  • Architect: Source of truth for application models (entities, permissions, configurations)
  • Scribe: Transforms models into deployable artifacts (migrations, policies, OpenAPI specs)
  • Captain: Orchestrates infrastructure provisioning and Kubernetes deployment

For complete details on how these components work together, their responsibilities, and operational characteristics, see Management Platform.

Deployment Architecture

flowchart TD
    S3Artifact[S3 Artifact Bucket]

    subgraph Management Platform
        Arch[Architect<br/>Model Definition]
        Scr[Scribe<br/>Artifact Generator]
        Cap[Captain<br/>Orchestrator]
        Arch --> Scr
        Cap -->|Request Artifact| Scr
        Scr -->|Generated ZIP| Cap
    end

    subgraph Runtime Platform
        K8s[Kubernetes API]
        AS[Application Server]
    end

    CB[(S3 Content Bucket)]
    DB[(PostgreSQL Database)]
    Cap -->|Upload Artifact| S3Artifact
    Cap -->|Create/Update Resources| K8s
    K8s -->|Deploy| AS
    AS -->|Fetch Artifact| S3Artifact
    AS -->|Metadata| DB
    AS -->|Content| CB
    AS -->|Serve API| Users[Clients]

Deployment Lifecycle

The end-to-end deployment process follows these steps:

sequenceDiagram
    autonumber
    participant Architect
    participant Scribe
    participant Captain
    participant S3 as S3 Artifact Storage
    participant CB as S3 Content Bucket
    participant K8s as Kubernetes
    participant App as Application Server
    Captain ->> Scribe: Request artifact for application X
    Scribe ->> Architect: Fetch application model
    Architect -->> Scribe: Model JSON
    Scribe -->> Captain: ZIP (model.json, migrations/, policies.rego)
    Captain ->> S3: Upload artifact ZIP
    Captain ->> K8s: Create/Update Deployment/Service/ConfigMaps/Secrets
    K8s -->> App: Start application server pod
    App ->> S3: Fetch artifact ZIP
    App ->> App: Unpack artifact (model, migrations, policies)
    App ->> App: Run DB migrations, Serve Rego files
    App -->> Users: Serve API for application X

Step-by-Step Breakdown

1. Artifact Request

Captain initiates deployment by requesting Scribe to generate an artifact for a specific application. This happens when the user triggers a deployment via the Console.

2. Model Retrieval

Scribe fetches the current application model from Architect. The model includes all entity definitions, permissions, constraints, and configuration.

3. Artifact Generation

Scribe processes the model:

  • Migration Generation: Compares the current model to the previous version (if it exists) and generates SQL DDL statements to migrate the schema.
  • Policy Compilation: Converts permission rules (defined in a user-friendly format in Architect) into Rego policies that OPA understands.
  • Model Serialization: Serializes the model to JSON in the format expected by the Application Server.
  • Manifest File: Containing information about the artifact.
  • Packaging: Bundles everything into a ZIP with a consistent structure.

4. Artifact Upload

Captain uploads the artifact to a shared artifact storage bucket (S3). The artifact is stored with a path including the application ID and version, enabling:

  • Rollback: Previous artifacts remain available for reverting deployments
  • Audit: Complete history of what was deployed when
  • Distribution: All Application Server replicas fetch from the same location

5. Infrastructure Provisioning

For new applications, Captain provisions:

  • PostgreSQL Database: Creates a new database with credentials stored in a Kubernetes Secret
  • S3 Content Bucket: Creates a bucket with appropriate access policies
  • Keycloak Realm: Creates or configures a realm for authentication, sets up OIDC clients

6. Kubernetes Resource Creation

Captain creates or updates Kubernetes resources:

Deployment:

  • Specifies the Application Server container image (same for all applications)
  • Configures environment variables pointing to the artifact location
  • Sets resource limits (CPU, memory)
  • Configures health check endpoints

Service:

  • Exposes the Application Server pods to the Gateway
  • Labels with application ID and service type for discovery

ConfigMaps:

  • Gateway configuration (domains, CORS settings)
  • Webapp configuration (OIDC settings)

Secrets:

  • Database credentials
  • S3 bucket access keys
  • Gateway authentication credentials for Keycloak

7. Application Server Startup

Kubernetes starts the Application Server pod(s):

Init Phase:

  • Application Server downloads the artifact from S3
  • Unpacks the artifact to the local filesystem
  • Runs Flyway migrations against the database

Runtime Phase:

  • Loads the application model into memory
  • Starts the HTTP server
  • Registers health check endpoints
  • Begins serving API requests

The init phase ensures the database schema matches the model before serving traffic. If migrations fail, the pod won’t become ready, and Kubernetes won’t route traffic to it.

8. Service Readiness

Once health checks pass, Kubernetes marks the pod as ready and begins routing traffic.

Artifact Structure

A typical artifact has this structure:

application-artifact.zip
β”œβ”€β”€ manifest.json                    # Metadata
β”œβ”€β”€ application-model.json           # Model definition
β”œβ”€β”€ policies.rego                    # Access control policies
└── migrations/                      # Flyway migrations
    β”œβ”€β”€ V1__initial_schema.sql
    β”œβ”€β”€ V2__add_invoices.sql
    └── V3__add_status_column.sql

manifest.json:

{
  "organizationId": "org-123",
  "organizationName": "Acme Corp",
  "projectId": "proj-456",
  "projectName": "Invoice Management",
  "version": "1.2.3",
  "changeset": "abc123def456",
  "timestamp": "2026-01-28T10:30:00Z",
  "scribeVersion": "2.1.0"
}

application-model.json:

The model JSON follows a published schema and includes complete entity definitions, attributes, relations, and constraints. This is the single source of truth for the Application Server’s runtime behavior.

policies.rego:

Rego policies define authorization rules. These are loaded by OPA and queried by the Application Server for every request.

migrations:

Flyway migration scripts are numbered sequentially. Flyway tracks which migrations have executed in a special database table (flyway_schema_history), ensuring each migration runs exactly once.

Update Strategy

When updating an existing application:

Update:

  • Captain deletes the old Deployment
  • Captain creates a new Deployment with the updated artifact
  • Kubernetes starts new pods with the updated artifact
  • New pods run migrations (only new migrations execute)
  • Health checks pass, new pods become ready

Database Migrations:

  • Flyway migrations are forward-onlyβ€”there are no automatic rollbacks
  • Migrations should be backward-compatible when possible (e.g., adding nullable columns)
  • Breaking changes require coordination between schema and code deployments

Rollback:

  • Captain can redeploy a previous artifact version
  • Even if the database migrations ran, the old schema is still available, and the old version of the model will still run

Deployment Observability

Health Checks:

Application Server exposes health endpoints:

  • /actuator/health/liveness: Is the process alive?
  • /actuator/health/readiness: Is the application ready to serve traffic?

Kubernetes uses these for liveness probes (restart if unhealthy) and readiness probes (route traffic only when ready).

Logs:

All components log to stdout/stderr, collected by Kubernetes:

  • Captain logs deployment activities and decisions
  • Application Server logs startup, migrations, and request handling
  • OPA logs policy evaluation (if enabled)

Centralized logging (e.g., Elasticsearch, Loki) aggregates logs for analysis.

Metrics:

Application Server exposes Prometheus metrics:

  • Request counts and latencies
  • Database query performance
  • OPA policy evaluation times
  • Content storage access patterns

Monitoring dashboards provide visibility into application behavior.

Deployment Security

Principle of Least Privilege:

  • Captain has credentials to provision infrastructure but not to access application data
  • Application Server has credentials to access its own database and bucket, but not others
  • Keycloak realms isolate authentication between organizations

Secret Management:

  • Kubernetes Secrets store sensitive credentials
  • Secrets are injected as mounted files
  • Secrets are not included in artifacts or logged

Artifact Integrity:

  • Artifacts are versioned and immutable once created
  • Only Captain can upload artifacts to the shared bucket

Summary

The ContentGrid deployment pipeline provides a fully automated path from application model to running service:

  • Artifact Generation: Scribe transforms models into deployable artifacts with migrations and policies
  • Orchestration: Captain provisions infrastructure and coordinates Kubernetes deployments
  • Observability: Health checks, logs, and metrics provide visibility into deployment status and application health

The pipeline’s design enables rapid iterationβ€”model changes deploy quickly and consistently. The use of a shared container image simplifies operations while maintaining application isolation through configuration and infrastructure separation.