3 unstable releases
Uses new Rust 2024
| new 0.10.0 | Feb 4, 2026 |
|---|---|
| 0.9.5 | Jan 21, 2026 |
| 0.9.4 | Jan 11, 2026 |
#209 in HTTP server
87KB
2K
SLoC
Capsula Server
A web server for storing, browsing, and managing Capsula runs with a PostgreSQL database backend.
Features
- Web UI for browsing runs and vaults
- REST API for programmatic access
- File upload and storage for captured files
- Hook output storage (pre-run and post-run)
- Vault organization
- Pagination support
Prerequisites
- PostgreSQL 12 or higher
- Rust 1.91 or higher (for building from source)
Database Setup
- Create a PostgreSQL database:
createdb capsula
- The server will automatically run migrations on startup to create the required tables.
Running the Server
From Source
# Basic usage with database URL
cargo run -p capsula-server -- --database-url "postgresql://localhost/capsula"
# Or use environment variable
export DATABASE_URL="postgresql://localhost/capsula"
cargo run -p capsula-server
# Custom host and port
cargo run -p capsula-server -- \
--host 0.0.0.0 \
--port 8080 \
--database-url "postgresql://localhost/capsula"
# All options
cargo run -p capsula-server -- \
--host 0.0.0.0 \
--port 8080 \
--database-url "postgresql://localhost/capsula" \
--storage-path /var/lib/capsula/storage \
--max-connections 10 \
--log-level debug
The server will start on http://127.0.0.1:8500 by default.
Using Docker
# Start PostgreSQL with Docker
docker run -d \
--name capsula-postgres \
-e POSTGRES_DB=capsula \
-e POSTGRES_PASSWORD=password \
-p 5432:5432 \
postgres:16
# Run the server
cargo run -p capsula-server -- \
--host 0.0.0.0 \
--port 8500 \
--database-url "postgresql://postgres:password@localhost:5432/capsula"
Command Line Options
You can view all available options with --help:
cargo run -p capsula-server -- --help
Web server for managing and viewing Capsula runs
Usage: capsula-server [OPTIONS] --database-url <DATABASE_URL>
Options:
-H, --host <HOST>
Host to bind to [env: CAPSULA_HOST=] [default: 127.0.0.1]
-p, --port <PORT>
Port to bind to [env: CAPSULA_PORT=] [default: 8500]
-d, --database-url <DATABASE_URL>
PostgreSQL connection string [env: DATABASE_URL=]
-s, --storage-path <STORAGE_PATH>
Storage directory for captured files [env: STORAGE_PATH=] [default: ./storage]
--max-connections <MAX_CONNECTIONS>
Maximum database connections [env: CAPSULA_MAX_CONNECTIONS=] [default: 5]
-l, --log-level <LOG_LEVEL>
Log level (error, warn, info, debug, trace) [env: RUST_LOG=] [default: info]
-h, --help
Print help
-V, --version
Print version
Configuration
The server can be configured via command-line flags or environment variables. Command-line flags take precedence over environment variables.
Priority order: CLI flags > Environment variables > Default values
Configuration Options
| CLI Flag | Short | Environment Variable | Default | Description |
|---|---|---|---|---|
--host |
-H |
CAPSULA_HOST |
127.0.0.1 |
Host to bind to |
--port |
-p |
CAPSULA_PORT |
8500 |
Port to bind to |
--database-url |
-d |
DATABASE_URL |
(required) | PostgreSQL connection string |
--storage-path |
-s |
STORAGE_PATH |
./storage |
Directory for file storage |
--max-connections |
CAPSULA_MAX_CONNECTIONS |
5 |
Database connection pool size | |
--log-level |
-l |
RUST_LOG |
info |
Logging level |
--max-body-size |
CAPSULA_MAX_BODY_SIZE |
104857600 |
Maximum upload body size in bytes (default: 100MB) |
Configuration Examples
Using CLI flags only:
capsula-server \
--host 0.0.0.0 \
--port 8080 \
--database-url "postgresql://localhost/capsula" \
--storage-path /data/storage \
--log-level debug \
--max-body-size 209715200 # 200MB
Using environment variables only:
export DATABASE_URL="postgresql://localhost/capsula"
export CAPSULA_HOST="0.0.0.0"
export CAPSULA_PORT="8080"
export STORAGE_PATH="/data/storage"
export RUST_LOG="debug"
export CAPSULA_MAX_BODY_SIZE="209715200" # 200MB
capsula-server
Mixed (CLI overrides environment):
export DATABASE_URL="postgresql://localhost/capsula"
export CAPSULA_PORT="8080"
# Override port with CLI flag
capsula-server --port 9000 # Will use port 9000, not 8080
API Endpoints
Runs
GET /api/v1/runs- List all runs- Query params:
vault,limit,offset
- Query params:
POST /api/v1/runs- Create a new runGET /api/v1/runs/{id}- Get run detailsGET /api/v1/runs/{id}/files/{path}- Download captured filePOST /api/v1/upload- Upload files and hook outputs for a run
Vaults
GET /api/v1/vaults- List all vaultsGET /api/v1/vaults/{name}- Get vault info
Health Check
GET /health- Health check endpoint
Web UI
/- Home page/vaults- List all vaults/runs- List all runs- Query params:
vault,page
- Query params:
/runs/{id}- View run details
CLI Integration
Configure the Capsula CLI to push runs to the server:
- Add server URL to
capsula.toml:
[vault]
name = "my-project"
server = "http://localhost:8500"
- Or use environment variable:
export CAPSULA_SERVER_URL="http://localhost:8500"
- Push a run:
# By run ID
capsula push 01HQXYZ...
# By run name
capsula push chubby-back
- List vaults on the server:
capsula vaults list
Database Schema
Runs Table
Stores metadata about each run:
id(TEXT, PRIMARY KEY): ULID identifiername(TEXT): Human-readable nametimestamp(TIMESTAMPTZ): When the run occurredcommand(TEXT): Command that was executedvault(TEXT): Vault nameproject_root(TEXT): Project root directoryexit_code(INTEGER): Exit code of the commandduration_ms(INTEGER): Duration in millisecondsstdout(TEXT): Standard outputstderr(TEXT): Standard errorcreated_at(TIMESTAMPTZ): When the record was createdupdated_at(TIMESTAMPTZ): When the record was last updated
Files Table
Stores captured files:
id(SERIAL, PRIMARY KEY)run_id(TEXT, FOREIGN KEY): References runs(id)file_path(TEXT): Relative path in the run directorycontent(BYTEA): File contentsha256(TEXT): SHA256 hash of content
Hooks Table
Stores hook outputs:
id(SERIAL, PRIMARY KEY)run_id(TEXT, FOREIGN KEY): References runs(id)phase(TEXT): 'pre' or 'post'hook_output(JSONB): Hook output data
Development
Running Tests
# Run all tests
cargo test -p capsula-server
# Run with output
cargo test -p capsula-server -- --nocapture
Database Migrations
Migrations are embedded in the binary and run automatically on startup. See crates/capsula-server/migrations/ for migration files.
Linting
# Run all lints
just lint
# Or individually
cargo clippy -p capsula-server
cargo fmt --check
Troubleshooting
Database Connection Issues
If you see connection errors:
-
Verify PostgreSQL is running:
pg_isready -
Check the DATABASE_URL format:
postgresql://[user[:password]@][host][:port][/database] -
Verify database exists:
psql -l | grep capsula
Port Already in Use
If port 8500 is already in use, set a different port:
capsula-server --port 8080 --database-url "postgresql://localhost/capsula"
# Or with environment variable
CAPSULA_PORT=8080 capsula-server --database-url "postgresql://localhost/capsula"
Migration Errors
If migrations fail, you can reset the database:
dropdb capsula
createdb capsula
cargo run -p capsula-server # Will run migrations
License
MIT OR Apache-2.0
Dependencies
~54–72MB
~1M SLoC