Feat v0.3.8 distribution (#21)
All checks were successful
All checks were successful
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #21.
This commit is contained in:
202
docs/DISTRIBUTION.md
Normal file
202
docs/DISTRIBUTION.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Distribution Guide
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/switchboard-core/switchboard-core:latest
|
||||
docker run -p 8080:80 \
|
||||
-e SWITCHBOARD_ADMIN_USERNAME=admin \
|
||||
-e SWITCHBOARD_ADMIN_PASSWORD=changeme \
|
||||
ghcr.io/switchboard-core/switchboard-core: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 that are auto-installed on first boot:
|
||||
|
||||
| Package | Type | Description |
|
||||
|---------|------|-------------|
|
||||
| bug-report-triage | workflow | Public entry, severity routing, SLA timers |
|
||||
| content-approval | workflow | Multi-party signoff example |
|
||||
| employee-onboarding | workflow | Automated provisioning + manager signoff |
|
||||
| webhook-notifier | workflow | HTTP outbound via connections + Starlark |
|
||||
| workflow-demo | surface | Interactive walkthrough with diagrams |
|
||||
| hello-dashboard | surface | Welcome/getting started surface |
|
||||
| schedules | surface | Cron task management UI |
|
||||
| tasks | full | Kanban/list task manager with webhooks |
|
||||
| team-activity-log | surface | Team activity feed |
|
||||
| gitea-client | library | Gitea API integration library |
|
||||
| icd-test-runner | surface | E2E API test suite |
|
||||
| sdk-test-runner | surface | SDK feature test suite |
|
||||
|
||||
### Behavior
|
||||
|
||||
- **First boot**: All bundled 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 a comma-separated list of package IDs to install only a subset:
|
||||
|
||||
```bash
|
||||
# K8s / Helm — install only core surfaces, no demo/test packages
|
||||
docker run -p 8080:80 \
|
||||
-e BUNDLED_PACKAGES="tasks,schedules,hello-dashboard" \
|
||||
ghcr.io/switchboard-core/switchboard-core:latest
|
||||
```
|
||||
|
||||
Empty (default) means install all bundled 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/switchboard-core/switchboard-core: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/switchboard-core/switchboard-core:latest
|
||||
```
|
||||
|
||||
## Builder Image
|
||||
|
||||
The builder image pre-caches Go modules and Node dependencies for faster custom builds.
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/switchboard-core/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/switchboard-core/builder:latest AS builder
|
||||
WORKDIR /app
|
||||
COPY server/ .
|
||||
RUN go build -ldflags="-s -w" -o /bin/switchboard .
|
||||
```
|
||||
|
||||
### Building Locally
|
||||
|
||||
```bash
|
||||
docker build -f Dockerfile.builder -t switchboard-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-switchboard .`
|
||||
|
||||
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/switchboard-core/switchboard-core.git
|
||||
cd switchboard-core
|
||||
|
||||
# Add/modify packages
|
||||
cp -r my-extension packages/my-extension/
|
||||
|
||||
# Build with builder image for faster compilation
|
||||
docker build -t my-switchboard .
|
||||
```
|
||||
|
||||
## 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. `/switchboard`) |
|
||||
| `SKIP_BUNDLED_PACKAGES` | `false` | Disable auto-install of bundled packages |
|
||||
| `BUNDLED_PACKAGES` | (empty = all) | Comma-separated allowlist of package IDs to install |
|
||||
| `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/switchboard?sslmode=require" \
|
||||
-e JWT_SECRET="$(openssl rand -hex 32)" \
|
||||
-e ENCRYPTION_KEY="$(openssl rand -hex 32)" \
|
||||
ghcr.io/switchboard-core/switchboard-core:latest
|
||||
|
||||
# SQLite (evaluation only)
|
||||
docker run -p 8080:80 \
|
||||
-e DB_DRIVER=sqlite \
|
||||
-v switchboard-data:/data \
|
||||
ghcr.io/switchboard-core/switchboard-core:latest
|
||||
```
|
||||
|
||||
### Storage
|
||||
|
||||
Object storage is required for file uploads and package asset extraction.
|
||||
|
||||
```bash
|
||||
# PVC (auto-detected if path is writable)
|
||||
docker run -v switchboard-storage:/data/storage ...
|
||||
|
||||
# S3-compatible (MinIO, AWS S3, Ceph)
|
||||
docker run \
|
||||
-e STORAGE_BACKEND=s3 \
|
||||
-e S3_BUCKET=switchboard \
|
||||
-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
|
||||
Reference in New Issue
Block a user