This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/DISTRIBUTION.md
Jeffrey Smith f0dd43144e rebrand: Switchboard Core → Armature
- Rename Go module switchboard-core → armature (155+ files)
- Rename Docker image → gobha/armature
- Rename K8s resources, secrets, deployments
- Rename Prometheus metrics switchboard_* → armature_*
- Rename env vars SWITCHBOARD_ADMIN_* → ARMATURE_ADMIN_*
- Rename DB names switchboard_core* → armature*
- Update all frontend branding, notification templates, docs
- Update CI scripts, e2e tests, Keycloak realm, nginx conf
- Rename scripts/switchboard-ca.sh → scripts/armature-ca.sh
- Rename k8s/switchboard.yaml → k8s/armature.yaml
- Rename chart alerting/dashboard files
- Fix: DockerHub push uses env: binding for secret injection
- Helm chart updated (name, labels, template functions, dashboard, alerting)
- Replace favicon/icon assets with Armature brand

No functional changes. Pure mechanical rename + CI fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 21:39:58 +00:00

228 lines
7.4 KiB
Markdown

# Distribution Guide
## Quick Start
```bash
docker pull ghcr.io/armature/armature:latest
docker run -p 8080:80 \
-e ARMATURE_ADMIN_USERNAME=admin \
-e ARMATURE_ADMIN_PASSWORD=changeme \
ghcr.io/armature/armature:latest
```
On first run, bundled packages are automatically installed — workflows, surfaces, and extensions are ready to use immediately.
## Bundled Packages
The production Docker image ships with pre-built packages. A **curated default set** is auto-installed on first boot; additional packages ship in the image and can be opted-in via `BUNDLED_PACKAGES`.
#### Default Set (auto-installed)
| Package | Type | Description |
|---------|------|-------------|
| notes | surface | Markdown notes with graph view |
| chat | surface | Real-time chat surface |
| chat-core | library | Conversations, messages, read cursors |
| mermaid-renderer | extension | Diagram rendering |
| schedules | surface | Cron task management UI |
#### Opt-in (ship in image, require `BUNDLED_PACKAGES` to enable)
| Package | Type | Description |
|---------|------|-------------|
| tasks | full | Kanban/list task manager with webhooks |
| workflow-chat | extension | Chat integration for workflow stages |
| dashboard | surface | Dashboard surface |
| workflow-demo | surface | Interactive walkthrough with diagrams |
| bug-report-triage | workflow | Public entry, severity routing, SLA timers |
| content-approval | workflow | Multi-party signoff example |
| employee-onboarding | workflow | Automated provisioning + manager signoff |
| editor | surface | Rich markdown editor |
| hello-dashboard | surface | Welcome/getting started surface |
| team-activity-log | surface | Team activity feed |
| webhook-notifier | workflow | HTTP outbound via connections + Starlark |
| csv-table | extension | CSV table renderer |
| diff-viewer | extension | Diff visualization |
| git-board | surface | Git board interface |
| gitea-client | library | Gitea API integration library |
| js-sandbox | extension | JavaScript sandbox |
| katex-renderer | extension | LaTeX rendering |
| regex-tester | extension | Regex testing tool |
| icd-test-runner | surface | E2E API test suite |
| sdk-test-runner | surface | SDK feature test suite |
### Behavior
- **First boot**: Curated default packages are installed and enabled automatically.
- **Subsequent boots**: No-op — already-installed packages are skipped.
- **Admin uninstalls a package**: It stays uninstalled. Bundled packages are never force-reinstalled.
- **To re-install**: Delete the package from the database, then restart the container.
### Selecting Packages (Allowlist)
Set `BUNDLED_PACKAGES` to control which packages are installed:
```bash
# Install ALL packages (everything in the image)
docker run -p 8080:80 \
-e BUNDLED_PACKAGES="*" \
ghcr.io/armature/armature:latest
# Install specific packages only
docker run -p 8080:80 \
-e BUNDLED_PACKAGES="notes,tasks,schedules" \
ghcr.io/armature/armature:latest
```
Empty (default) installs the curated default set. Use `*` to install all packages. This is useful for Helm charts where different environments need different packages.
### Disabling Auto-Install
Set `SKIP_BUNDLED_PACKAGES=true` to prevent bundled packages from being installed:
```bash
docker run -p 8080:80 \
-e SKIP_BUNDLED_PACKAGES=true \
ghcr.io/armature/armature:latest
```
### Custom Bundle Directory
Override the default bundled packages location with `BUNDLED_PACKAGES_DIR`:
```bash
docker run -p 8080:80 \
-e BUNDLED_PACKAGES_DIR=/custom/packages \
-v /host/packages:/custom/packages \
ghcr.io/armature/armature:latest
```
## Builder Image
The builder image pre-caches Go modules and Node dependencies for faster custom builds.
```bash
docker pull ghcr.io/armature/builder:latest
```
### What It Caches
- Go module cache (`go mod download` for all server dependencies)
- Node modules for the CM6 editor bundle
- Vendor library tarballs (marked, DOMPurify, mermaid, KaTeX)
- Build tools (zip, Node.js runtime)
### Using in Custom Builds
Reference the builder image as a base stage in your Dockerfile:
```dockerfile
FROM ghcr.io/armature/builder:latest AS builder
WORKDIR /app
COPY server/ .
RUN go build -ldflags="-s -w" -o /bin/armature .
```
### Building Locally
```bash
docker build -f Dockerfile.builder -t armature-builder .
```
## Custom Build Guide
### Adding Custom Packages
1. Create your package in `packages/your-package/` with a `manifest.json`
2. Build all packages: `cd packages && bash build.sh all`
3. Build the Docker image: `docker build -t my-armature .`
The Dockerfile automatically builds all packages in the `packages/` directory and bundles them into the production image.
### Removing Bundled Packages
To exclude specific packages from the bundle, either:
- Remove them from `packages/` before building
- Set `SKIP_BUNDLED_PACKAGES=true` and install packages manually via the admin UI
### Forking for Custom Builds
```bash
git clone https://github.com/armature/armature.git
cd armature
# Add/modify packages
cp -r my-extension packages/my-extension/
# Build with builder image for faster compilation
docker build -t my-armature .
```
## Production Deployment
### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `PORT` | `8080` | Backend API port |
| `DB_DRIVER` | (auto) | `postgres` or `sqlite` |
| `DATABASE_URL` | | PostgreSQL connection string |
| `JWT_SECRET` | `dev-secret-change-me` | **Must change in production** |
| `ENCRYPTION_KEY` | | AES-256 key for credential encryption |
| `AUTH_MODE` | `builtin` | `builtin`, `mtls`, or `oidc` |
| `STORAGE_BACKEND` | (auto) | `pvc` or `s3` |
| `STORAGE_PATH` | `/data/storage` | PVC mount point |
| `BASE_PATH` | | URL prefix (e.g. `/armature`) |
| `SKIP_BUNDLED_PACKAGES` | `false` | Disable auto-install of bundled packages |
| `BUNDLED_PACKAGES` | (empty = defaults) | `""` curated defaults, `"*"` all, or comma-separated IDs |
| `BUNDLED_PACKAGES_DIR` | `/app/bundled-packages` | Override bundled packages location |
| `LOG_FORMAT` | `text` | `text` or `json` |
| `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error` |
### Database
PostgreSQL is recommended for production. SQLite is suitable for single-instance evaluation.
```bash
# PostgreSQL (recommended)
docker run -p 8080:80 \
-e DATABASE_URL="postgres://user:pass@host:5432/armature?sslmode=require" \
-e JWT_SECRET="$(openssl rand -hex 32)" \
-e ENCRYPTION_KEY="$(openssl rand -hex 32)" \
ghcr.io/armature/armature:latest
# SQLite (evaluation only)
docker run -p 8080:80 \
-e DB_DRIVER=sqlite \
-v armature-data:/data \
ghcr.io/armature/armature:latest
```
### Storage
Object storage is required for file uploads and package asset extraction.
```bash
# PVC (auto-detected if path is writable)
docker run -v armature-storage:/data/storage ...
# S3-compatible (MinIO, AWS S3, Ceph)
docker run \
-e STORAGE_BACKEND=s3 \
-e S3_BUCKET=armature \
-e S3_ENDPOINT=https://minio.corp:9000 \
-e S3_ACCESS_KEY=... \
-e S3_SECRET_KEY=... \
-e S3_FORCE_PATH_STYLE=true \
...
```
### Kubernetes
See the `k8s/` directory for example manifests. Key considerations:
- Use `POSTGRES_HOST`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` env vars (assembled into DSN automatically)
- Set liveness probe to `/healthz/live`, readiness probe to `/healthz/ready`
- Mount a PVC at `/data/storage` for file storage, or configure S3
- Set `JWT_SECRET` and `ENCRYPTION_KEY` via Kubernetes Secrets