Run Opencode instances your way. GitTerm supports multiple cloud providers of servers or sandboxes for remote Opencode sessions.
- Cloud workspaces for remote Opencode sessions
- Browser-accessible TTYD for the Opencode TUI
- Server-only Opencode URLs for desktop or local clients
The fastest way to self-host:
- Click the deploy button above.
- Set the required env vars Railway asks for, especially
ADMIN_EMAILandADMIN_PASSWORD. - If you want subdomain routing, give the
proxyservice a wildcard domain like*.your-domain.com. - Configure your workspace providers in the admin panel before users create workspaces.
Required services:
| Service | Purpose |
|---|---|
| PostgreSQL | Database |
| Redis | Cache and pub/sub |
| server | Main API |
| web | Dashboard and auth UI |
| proxy | Caddy reverse proxy |
| listener | Webhook and event ingress |
| worker | Background jobs |
Recommended worker cron:
| Worker | Schedule | Purpose |
|---|---|---|
idle-reaper |
*/10 * * * * |
Stops idle workspaces and enforces quotas |
Caddy can route workspaces either by path or subdomain:
https://your-domain.com/ws/{workspace-subdomain}/
https://{workspace-subdomain}.your-domain.com
https://{port}-{workspace-subdomain}.your-domain.com
Path routing is useful when you do not control wildcard DNS. Subdomain routing is usually better for apps that rely on relative asset paths.
Provider configuration is driven by packages/schema/src/provider-registry.ts. Current provider definitions include Railway, AWS, Daytona, Cloudflare Sandbox, and E2B.
Open the admin panel and add the required values for each provider you want to offer.
Webhook endpoints depend on how you expose GitTerm:
- Through the public proxy:
https://<your-base-domain>/listener/trpc/... - Directly to the listener service:
https://<listener-base-url>/trpc/...
If your listener service is not public, use the proxy form.
Set these values in the admin panel:
- optional:
API URL(defaults tohttps://backboard.railway.app/graphql/v2) API TokenProject IDEnvironment ID- optional:
Default Region - optional:
Public Railway Domains
Webhook setup:
- Endpoint via proxy:
https://<your-base-domain>/listener/trpc/railway.handleWebhook - Endpoint via listener:
https://<listener-base-url>/trpc/railway.handleWebhook - Accept these Railway events:
Deployment Failed,Deployment Deploying,Deployment Slept,Deployment Deployed
E2B is configured from the GitTerm admin panel and the E2B dashboard at https://e2b.dev/.
Set these values in the admin panel:
API KEYWebhook Secret
In E2B, create or update a sandbox lifecycle webhook and use:
- Endpoint via proxy:
https://<your-base-domain>/listener/trpc/e2b.handleWebhook - Endpoint via listener:
https://<listener-base-url>/trpc/e2b.handleWebhook - Signature secret: use the same value you saved as
Webhook Secretin GitTerm
Minimum events GitTerm currently uses:
sandbox.lifecycle.pausedsandbox.lifecycle.resumedsandbox.lifecycle.killed
Daytona is configured from the GitTerm admin panel.
Set these values in the admin panel:
API KeyDefault Target Region(usoreu)
Cloudflare Sandbox (WIP)
Set these values in the admin panel:
Worker URLCallback Secret
Deploy the worker from packages/api/src/providers/cloudflare/agent-worker/src/index.ts:
cd packages/api
bun run wrangler:deployGitHub integration is optional. It allows users to connect repositories and perform git actions from their workspaces.
Set these env vars on the server service:
GITHUB_APP_IDGITHUB_APP_PRIVATE_KEY
Set both or neither.
GitHub App setup:
- Callback URL:
https://<api-url>/api/github/callback - Webhook via proxy:
https://<your-base-domain>/listener/trpc/github.handleInstallationWebhook - Webhook via listener:
https://<listener-base-url>/trpc/github.handleInstallationWebhook
See CONTRIBUTING.md for local setup and service URLs.
Common commands:
bun run dev
bun run build
bun run check-types
bun run db:push
bun run db:studio
bun run db:generate
bun run db:migrate- Website: https://gitterm.dev
- OpenCode: https://opencode.ai
- CLI: https://www.npmjs.com/package/gitterm
- GitHub: https://github.com/OpeOginni/gitterm
MIT. See LICENSE.
