A self-hosted PaaS (Platform as a Service) for deploying Verb applications.
| Package | Description |
|---|---|
| Verb | Fast web framework for Bun |
| Hull | Ecto-inspired database toolkit |
| Allow | Authentication library |
| Hoist | Deployment platform (this repo) |
- Docker-based deployments - Build and run containers from your code
- Managed PostgreSQL - Per-app databases with automatic provisioning
- Environment variables - Secure configuration management
- Custom domains - Add domains with automatic SSL
- Shelves storage - S3-compatible object storage for files and media
- Real-time logs - Stream application logs
- Reverse proxy - Automatic routing to your containers
| Package | Description |
|---|---|
@verb-js/hoist |
CLI for deployments |
@verb-js/hoist-sdk |
SDK for storage and database clients |
api |
HTTP API server |
web |
React dashboard |
proxy |
Reverse proxy for routing |
bun add -g @verb-js/hoisthoist login# In your project directory with a Dockerfile
hoist deploy# Authentication
hoist login # Log in to Hoist
hoist logout # Log out
hoist token # Show current token
# Apps
hoist apps list # List all apps
hoist apps create <name> # Create new app
hoist apps info <name> # Show app details
hoist apps delete <name> # Delete an app
# Deployments
hoist deploy # Deploy current directory
hoist deploy --app <name># Deploy to specific app
# Environment Variables
hoist env list # List env vars
hoist env set KEY value # Set env var
hoist env unset KEY # Remove env var
# Databases
hoist db create # Create PostgreSQL database
hoist db info # Show database details
# Domains
hoist domains add <domain> # Add custom domain
hoist domains verify <domain> # Verify DNS configuration
hoist domains list # List domains
# Storage
hoist storage create <name> # Create storage bucket
hoist storage keys # Show access credentials
# Logs
hoist logs # View recent logs
hoist logs -f # Stream logs in real-timeimport { createStorage } from "@verb-js/hoist-sdk"
const storage = createStorage({
accessKey: process.env.HOIST_ACCESS_KEY,
secretKey: process.env.HOIST_SECRET_KEY,
endpoint: process.env.HOIST_STORAGE_URL,
})
// Upload a file
await storage.put("images/photo.jpg", buffer, {
contentType: "image/jpeg",
})
// Download a file
const data = await storage.get("images/photo.jpg")
// Get public URL
const url = await storage.getUrl("images/photo.jpg")Hoist is a self-hosted PaaS. This section covers how to set up your own Hoist server.
- Bun >= 1.0.0 (install)
- Docker with Docker Compose
- PostgreSQL 16+ (or use the included Docker image)
- Shelves - S3-compatible storage (part of Verb ecosystem, included)
# Clone the repository
git clone https://github.com/verbjs/hoist.git
cd hoist
# Install dependencies
bun install
# Copy environment file and configure
cp .env.example .env
# Start PostgreSQL with Docker
docker compose up -d postgres
# Run database migrations
bun run db:migrate
# Start all services
bun run devServices will be available at:
- Web Dashboard: http://localhost:3000
- API: http://localhost:3001
- Proxy: http://localhost:80 (routes
*.hoist.localto containers)
Create a .env file from the example:
# Database (required)
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/hoist
# Domain for deployed apps (apps accessible at {slug}.{HOIST_DOMAIN})
HOIST_DOMAIN=hoist.local
# Shelves Storage (required for file uploads and static sites)
S3_ENDPOINT=http://localhost:9000
S3_REGION=us-east-1
S3_BUCKET=hoist-storage
S3_ACCESS_KEY_ID=hoistadmin
S3_SECRET_ACCESS_KEY=hoistadmin
# Security - CHANGE IN PRODUCTION
ENCRYPTION_KEY=change-this-to-a-secure-32-char-key
# Ports
PORT=3001
PROXY_PORT=80For local development, add entries to /etc/hosts:
# Add to /etc/hosts
127.0.0.1 hoist.local
127.0.0.1 myapp.hoist.localOr use a wildcard DNS tool like dnsmasq to route all *.hoist.local to localhost.
For production, use Docker Compose to run all services:
# Build and start all services
docker compose up -d
# Run migrations
docker compose exec api bun run db:migrate-
Set secure environment variables
- Generate
ENCRYPTION_KEY:openssl rand -hex 16 - Use strong database password
- Configure Shelves credentials (or other S3-compatible storage)
- Generate
-
Configure DNS
- Point
hoist.yourdomain.comto your server - Set up wildcard DNS:
*.hoist.yourdomain.com→ same server - Update
HOIST_DOMAIN=hoist.yourdomain.com
- Point
-
Set up SSL/TLS
- Use a reverse proxy (nginx, Caddy, Traefik) in front of Hoist
- Configure automatic SSL with Let's Encrypt
-
Secure Docker socket
- The API needs Docker socket access to manage containers
- Consider using Docker socket proxy for added security
# Development mode (with hot reload)
bun run dev:api # API on :3001
bun run dev:web # Web UI on :3000
bun run dev:proxy # Proxy on :80
# Database migrations
bun run db:migrate
bun run db:rollbackAfter starting Hoist, visit http://localhost:3000 to create your first account. The first user registered becomes the admin.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ CLI │────▶│ API │────▶│ PostgreSQL │
└─────────────┘ └─────────────┘ └─────────────┘
│
┌─────────────┐ │ ┌─────────────┐
│ Web UI │────────────┘ ┌───▶│ Docker │
└─────────────┘ │ └─────────────┘
│
┌─────────────┐ ┌─────────────┐│ ┌─────────────┐
│ Request │────▶│ Proxy │┴───▶│ Containers │
└─────────────┘ └─────────────┘ └─────────────┘
│
┌─────────────┐
│ Shelves │
└─────────────┘
# Run individual services
bun run dev:api # API on :3001
bun run dev:web # Web UI on :3000
bun run dev:proxy # Proxy on :80
# Database migrations
bun run db:migrate
bun run db:rollbackMIT