Hop3 Cheat Sheet¶
A quick reference for Hop3 users.
Mental Model¶
Hop3 is a single-server PaaS (Platform as a Service). Think of it as:
Key concepts:
- Apps are deployable units. Each app has a name, source code, config, and runtime.
- Configuration comes from three layers (lowest to highest priority):
- Defaults (provided by Hop3)
Procfile(convention, Heroku-compatible)hop3.toml(full configuration)- Addons are backing services (databases, caches) that attach to apps.
- Environment variables configure runtime behavior.
- The CLI talks to the server via JSON-RPC; most commands run remotely.
Quick Reference: Commands¶
Setup & Authentication¶
# First time: initialize connection and create admin
hop3 init --ssh root@hop3.example.com
# Log in to existing server
hop3 login --ssh root@hop3.example.com
# Check who you're logged in as
hop3 auth whoami
# Get version
hop3 version
Context Management (Multiple Servers)¶
# Add server contexts
hop3 context add staging --server ssh://root@staging.example.com
hop3 context add production --server ssh://root@prod.example.com --protected
# List contexts (* = current)
hop3 context list
# Show current context and source
hop3 context current
# Switch context (safe - prints export command)
hop3 context use production
# Output: export HOP3_CONTEXT=production
# Switch context for this project (run from inside the project tree;
# writes .hop3-local.toml, auto-gitignored — ADR 042)
cd myproject/
hop3 context use staging
# Switch context globally (affects all terminals - use with caution!)
hop3 context use production --global
# Use context for single command
hop3 --context production apps
# Remove context
hop3 context remove old-staging
Context priority (highest to lowest):
1. --context flag
2. HOP3_CONTEXT environment variable
3. .hop3-local.toml [current].context (per project checkout, ADR 042)
4. Global config
Application Lifecycle¶
# Create app from git repository
hop3 app launch <git-url> <app-name>
# Deploy (from project directory)
hop3 deploy <app-name>
# Deploy from a specific directory
hop3 deploy <app-name> /path/to/app
# Check status
hop3 app status <app>
# View logs (streaming)
hop3 app logs <app>
# Build logs
hop3 app build-logs <app>
# Start / Stop / Restart
hop3 app start <app>
hop3 app stop <app>
hop3 app restart <app>
# List all apps
hop3 apps
# Destroy app (requires confirmation)
hop3 app destroy <app>
# Scriptable destroy — no prompt, still safe
hop3 app destroy oldapp --confirm=oldapp
Sticky App (implicit --app)¶
Most app-scoped commands don't need --app if one is resolvable from the
current shell or directory.
# Bind an app to the current context
hop3 use myapp
hop3 app logs # no positional needed
hop3 app restart
hop3 config show
# Or set for a single shell
export HOP3_APP=myapp
# Or drop a .hop3-app file in your project
echo myapp > .hop3-app
# Debug the chain
hop3 --why logs
Resolution order: --app → $HOP3_APP → .hop3-app → hop3.toml [cli].app → context default. See CLI Reference: App Resolution.
Configuration / Environment¶
# View all env vars
hop3 config show <app>
# Get single var
hop3 config get <app> VAR_NAME
# Set vars (one or multiple)
hop3 config set <app> VAR1=value1 VAR2=value2
# Remove var
hop3 config unset <app> VAR_NAME
# Live runtime config
hop3 config live <app>
# Migrate Procfile to hop3.toml
hop3 config migrate procfile /path/to/app --dry-run
Addons (Backing Services)¶
hop3 addons # List addons (alias for `addon list`)
hop3 addon create postgres my-db # Create addon
hop3 addon attach my-db --app <app> # Attach (sets DATABASE_URL)
hop3 addon detach my-db --app <app> # Detach from app
hop3 addon show my-db # Addon info
hop3 addon destroy my-db # Destroy addon
See CLI Reference: Services for complete documentation.
Backups¶
hop3 backup create <app> # Create backup
hop3 backup list <app> # List backups
hop3 backup info <backup-id> # Backup details
hop3 backup restore <backup-id> # Restore
hop3 app restart <app> # Restart after restore
hop3 backup destroy <backup-id> # Delete backup
See Backup and Restore Guide for complete documentation.
Process Scaling¶
System & Admin¶
# System info
hop3 system info
hop3 system status
hop3 system uptime
# List all server processes
hop3 system ps
# Server logs
hop3 system logs
# User management (admin only)
hop3 user list
hop3 user add <username> <email> --password-file ./pw.txt
hop3 user set-password <username> --stdin # pipe new password in
hop3 user disable <username>
hop3 user enable <username>
hop3 user grant-admin <username>
hop3 user remove <username> --confirm=<username>
Help¶
# General help
hop3 help
# All commands
hop3 help --all
# Help for specific command
hop3 <command> --help
CLI Flags¶
| Flag | Effect |
|---|---|
--json |
JSON output (for scripting; includes error.exit_code) |
--quiet / -q |
Suppress non-essential output |
--verbose / -v |
More detail (stackable: -vv = debug) |
-y / --yes / --force |
Skip confirmations |
--confirm=<name> |
Scriptable typed-name confirmation (safer than --yes) |
--no-input |
Refuse to prompt; fail fast with a hint |
--context <name> / -c |
Use a specific server context |
--app <name> / -a |
Override the resolved app |
--why |
Print app/context/alias resolution trace to stderr |
--no-alias |
Bypass the alias table (run the typed command literally) |
--help / -h |
Show help |
Exit codes (ADR 036 D16)¶
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Generic error |
2 |
Usage / syntax error |
3 |
Resolution error (app / context not found) |
4 |
Authentication |
5 |
Authorization |
6 |
Conflict (already exists) |
7 |
Network / server error |
8 |
Deployment failure |
9 |
Plugin error |
10 |
Confirmation declined or non-tty blocked |
130 |
Interrupted (SIGINT) |
Scripting examples¶
# Get app state in JSON (with structured exit-code on error)
hop3 app status myapp --json | jq '.data.state'
# Safer scripted destroy: typed-name match + still runs safety checks
hop3 app destroy myapp --confirm=myapp
# CI: refuse to block on prompts — fail fast with instructions
hop3 user add alice alice@ex.com --password-file ./pw --no-input
# Distinguish "user declined" from other failures
hop3 app destroy myapp
case $? in
0) echo "destroyed" ;;
10) echo "declined or non-tty" ;;
3) echo "no such app" ;;
*) echo "other error" ;;
esac
Helpful diagnostics¶
# Why did the CLI pick that app / context?
hop3 --why logs
# What aliases are active?
hop3 aliases
# What commands were meant? (Levenshtein suggestion)
hop3 deplo myapp # -> "Did you mean 'deploy'?"
Configuration Files¶
Procfile (Simple / Heroku-compatible)¶
Location: Procfile in project root.
web: gunicorn app:app --workers 4
worker: celery -A myapp worker
prebuild: pip install -r requirements.txt
prerun: python manage.py migrate
| Key | Purpose |
|---|---|
web |
Main process (receives HTTP traffic) |
worker |
Background worker |
prebuild |
Runs before build |
prerun |
Runs before start |
hop3.toml (Full Configuration)¶
Location: hop3.toml in project root (or src/hop3.toml).
[metadata]
id = "myapp"
version = "1.0.0"
title = "My Application"
[build]
before-build = "pip install -r requirements.txt"
build = "npm run build"
test = "pytest"
packages = ["nodejs", "gcc"]
[run]
start = "gunicorn app:app --workers 4"
before-run = "python manage.py migrate"
packages = ["postgresql-client"]
[env]
LOG_LEVEL = "info"
[port]
web = 8000
[healthcheck]
path = "/health/"
timeout = 30
interval = 60
[backup]
enabled = true
schedule = "0 2 * * *"
retention = 7
[[provider]]
name = "postgres"
plan = "standard"
Key Sections¶
| Section | Purpose |
|---|---|
[metadata] |
App ID, version, title, author |
[build] |
Build commands, packages |
[run] |
Start command, runtime setup |
[env] |
Default environment variables |
[port] |
Port mappings |
[healthcheck] |
Health monitoring |
[backup] |
Automated backup config |
[[provider]] |
Required services (postgres, redis) |
See hop3.toml Reference for complete documentation.
Precedence¶
hop3.tomlvalues override Procfile- Non-conflicting values are merged
- You can use both together
Common Workflows¶
Deploy a New App¶
# 1. Create project with hop3.toml or Procfile
cd myapp
# 2. Initialize hop3 (first time)
hop3 init --ssh root@hop3.example.com
# 3. Deploy (app-name is required)
hop3 deploy myapp
# 4. Check status
hop3 app status myapp
Update an Existing App¶
# 1. Make code changes
# 2. (Optional) Create backup first
hop3 backup create myapp
# 3. Deploy
hop3 deploy myapp
# 4. If something breaks, restore
hop3 backup restore <backup-id>
hop3 app restart myapp
Add a Database¶
# 1. Create the addon
hop3 addon create postgres myapp-db
# 2. Attach to app (sets DATABASE_URL)
hop3 addon attach myapp-db --app myapp
# 3. Restart to pick up new env var
hop3 app restart myapp
Debug a Problem¶
# Check app status
hop3 app status myapp
# View logs
hop3 app logs myapp
# Build logs
hop3 app build-logs myapp
# Full debug info
hop3 app debug myapp
# Check environment
hop3 config show myapp
Scale for Traffic¶
Best Practices¶
Configuration¶
- Don't hardcode secrets in
hop3.tomlor Procfile - For app-internal random secrets (
SECRET_KEY,APP_KEY, …), declareKEY = { generate = "hex", length = 32 }in[env]— generated once on first deploy, persisted, never committed - Use
hop3 config setfor externally-supplied secrets (API keys, passwords) - Keep
hop3.tomlin version control (without secrets) - Use
[env]for non-sensitive defaults only
Deployment¶
- Back up before deploying to production:
hop3 backup create <app> - Test locally first when possible
- Use
--dry-runwhen available - Check logs after deploy:
hop3 app logs <app>
Backups¶
- Back up before deploying to production:
hop3 backup create <app> - Enable automated backups in
hop3.toml: - Test restore procedures periodically
- See Backup and Restore Guide for retention policies
Environment Variables¶
- Restart after changing config:
hop3 app restart <app> - Use consistent naming:
DATABASE_URL,REDIS_URL,SECRET_KEY - Keep production and development configs separate
Working with Multiple Servers¶
- Mark production as protected:
hop3 context add production --server ... --protected - Use environment variable for safety:
export HOP3_CONTEXT=stagingin your shell - Per-project contexts (ADR 042):
cdinto the project tree and runhop3 context use <name>— the project-scoped verb writes.hop3-local.tomland adds it to.gitignoreautomatically. The legacy--localflag was retired in Step 7. - Avoid global context switches: Don't use
--globalfor production contexts - Create shell aliases:
Process Management¶
- Start with
web=1, scale as needed - Monitor with
hop3 app logsandhop3 app status - Use health checks to catch failures early
Quick Heroku → Hop3 Translation¶
| Heroku | Hop3 |
|---|---|
heroku create |
hop3 app launch <repo> <name> |
git push heroku main |
hop3 deploy |
heroku config set |
hop3 config set |
heroku addon create heroku-postgresql |
hop3 addon create postgres |
heroku logs -t |
hop3 app logs |
heroku ps |
hop3 ps |
heroku restart |
hop3 app restart |
heroku destroy |
hop3 app destroy |
Getting Help¶
hop3 help # General help
hop3 help --all # All commands
hop3 <command> --help # Help for specific command
Related Guides¶
- User Guide - Core concepts and daily operations
- CLI Reference - Complete command documentation
- hop3.toml Reference - Full configuration file reference
- Backup and Restore - Comprehensive backup documentation
- Troubleshooting - Diagnose and fix common issues