constructive-deployment

📁 constructive-io/constructive-skills 📅 Today
8
总安装量
4
周安装量
#34356
全站排名
安装命令
npx skills add https://github.com/constructive-io/constructive-skills --skill constructive-deployment

Agent 安装分布

windsurf 4
mcpjam 3
claude-code 3
junie 3
kilo 3
zencoder 3

Skill 文档

Constructive Deployment

How to deploy the Constructive platform — local development with Docker Compose, database migrations with pgpm, and production container builds.

When to Apply

Use this skill when:

  • Setting up the Constructive monorepo for local development
  • Running Docker Compose services (Postgres, MinIO, API servers)
  • Building the Constructive Docker image
  • Deploying database migrations to local or remote Postgres
  • Understanding the Makefile targets and service architecture

Local Development Setup

Prerequisites

  • Docker and Docker Compose
  • Node.js 22+ with pnpm
  • pgpm CLI (available from the constructive monorepo)

Quick Start

# 1. Start Postgres and MinIO containers
make up
# OR: docker-compose up -d

# 2. Bootstrap database roles (ensure PG env vars are loaded — see pgpm-env skill)
pgpm admin-users bootstrap --yes

# 3. Deploy all database modules
pgpm deploy --createdb --workspace --all --yes

Stopping

# Stop and remove containers + volumes
make down
# OR: docker-compose down -v

Docker Compose Services

Core Services (docker-compose.yml)

Service Container Image Port Purpose
postgres postgres ghcr.io/constructive-io/docker/postgres-plus:17 5432 PostgreSQL database
minio minio minio/minio 9000 S3-compatible object storage

Postgres credentials: postgres / password (local dev only)

Application Services (docker-compose.jobs.yml)

Service Container Port Purpose
constructive-admin-server constructive-admin-server 3002 Internal admin GraphQL API (header-based routing)
constructive-server constructive-server 3000 Public GraphQL API (domain-based routing)
send-email-link send-email-link — Email function (invite, password reset, verification)

Running Application Services

The application services require a built Docker image:

# Build the constructive image
docker-compose -f docker-compose.jobs.yml build

# Start all application services
docker-compose -f docker-compose.jobs.yml up -d

Postgres Images

Image Use Case
ghcr.io/constructive-io/docker/postgres-plus:17 Recommended — includes all extensions needed by constructive
pyramation/postgres:17 Lightweight alternative with common extensions

PostgreSQL 17+ is required for security_invoker views. Older images will fail with “unrecognized parameter security_invoker” errors.

Database Deployment

Deploy to Local Database

Prerequisite: Ensure PostgreSQL is running and PG env vars are loaded. See pgpm-docker and pgpm-env skills.

pgpm deploy --createdb --workspace --all --yes

Deploy to Remote Database

Point pgpm at a remote Postgres instance via environment variables:

export PGHOST=remote-host.example.com
export PGPORT=5432
export PGUSER=postgres
export PGPASSWORD=secure-password
export PGDATABASE=constructive

pgpm deploy --workspace --all --yes

Verify Deployment

pgpm verify

Revert (Rollback)

# Revert last change
pgpm revert --yes

# Revert to a tagged release
pgpm revert --to @v1.0.0 --yes

# Revert everything
pgpm revert --all --yes

Docker Image Build

The Constructive monorepo builds a multi-stage Docker image:

Build Stages

  1. build stage — Node.js 22, installs pnpm, runs pnpm install --frozen-lockfile and pnpm run build
  2. constructive stage — Runtime image with built artifacts, PostgreSQL client, and CLI shims

CLI Shims

The Docker image exposes three CLI commands:

Command Maps To
constructive node /app/packages/cli/dist/index.js
cnc node /app/packages/cli/dist/index.js
pgpm node /app/pgpm/pgpm/dist/index.js

Building Locally

docker build -t constructive:dev .

Makefile Targets

Target Command Purpose
make up docker-compose up -d Start Postgres + MinIO
make down docker-compose down -v Stop and clean up
make ssh docker exec -it postgres /bin/bash Shell into Postgres container
make roles pgpm admin-users bootstrap/add Bootstrap database roles
make install docker exec postgres /sql-bin/install.sh Run install script in container

Environment Variables

Server Configuration

Variable Description Example
API_IS_PUBLIC true for public API, false for admin (header-based) true
API_EXPOSED_SCHEMAS Comma-separated schemas to expose via GraphQL metaschema_public,services_public
API_ANON_ROLE PostgreSQL role for unauthenticated requests anonymous
API_ROLE_NAME PostgreSQL role for authenticated requests authenticated
API_ENABLE_SERVICES Enable services schema (admin only) true
API_META_SCHEMAS Meta schemas for validation and routing metaschema_public,services_public
SERVER_HOST Server bind address 0.0.0.0
SERVER_ORIGIN CORS origin *
SERVER_TRUST_PROXY Trust reverse proxy headers true
SERVER_STRICT_AUTH Enforce strict authentication false

Database Connection

Variable Description Default
PGHOST PostgreSQL host localhost
PGPORT PostgreSQL port 5432
PGUSER PostgreSQL user postgres
PGPASSWORD PostgreSQL password password
PGDATABASE Target database name —

Admin vs Public API

The Constructive platform runs two API servers:

  • Admin server (API_IS_PUBLIC=false, port 3002) — uses header-based routing (X-Api-Name, X-Database-Id, X-Meta-Schema). Used internally by the Constructive admin UI.
  • Public server (API_IS_PUBLIC=true, port 3000) — uses domain-based routing. Serves external client applications.

Networking

All Docker Compose services share the constructive-net network, allowing inter-service communication by container name (e.g., postgres:5432 from within the constructive-server container).

Troubleshooting

Issue Cause Fix
Port 5432 in use Another Postgres instance running Stop it or change the port in docker-compose.yml
security_invoker error Postgres version < 17 Use postgres-plus:17 or pyramation/postgres:17 image
role "authenticated" does not exist Missing bootstrap Run pgpm admin-users bootstrap --yes
Container not on network Network mismatch Check docker network ls for constructive-net
Build fails at pnpm install Lockfile mismatch Run pnpm install locally first to update lockfile