Rexec gives you instantly-available, network-isolated Linux terminals in the cloud. Perfect for development, testing, and secure remote access.
Installation Methods
Choose Your Deployment Method
Select the installation method that best fits your needs: Docker Compose (Recommended)
Manual Setup
Quick Demo (Guest Mode)
# Clone the repository
git clone https://github.com/brimblehq/rexec.git
cd rexec/docker
# Start the stack
docker compose up --build
Docker Compose is the fastest way to get started. It includes PostgreSQL, Redis, and all dependencies configured automatically.
Access the Dashboard
Once your deployment is running, open your browser: Default Credentials:
Username: admin
Password: admin
Change the default password immediately in production! Go to Settings > Profile after logging in.
Create Your First Container
From the dashboard, click “New Container” and configure:
Image : Choose from ubuntu:24.04, alpine:latest, node:20, python:3.12, or use a custom image
Name : Give it a memorable name (auto-generated if left blank)
Role : Select pre-configured environments:
barebone - Minimal setup (fastest)
webdev - Node.js, npm, yarn
python - Python 3, pip, venv
devops - kubectl, helm, terraform
database - PostgreSQL client, Redis CLI
Click Create and your terminal will be ready in seconds! Container names are auto-generated using fun combinations like swift-tiger-42 if you don’t specify one.
Connect and Use Your Terminal
Your terminal opens automatically with a full-featured shell: # Try some commands
echo "Hello from Rexec!"
# Install packages (Ubuntu example)
apt update && apt install -y curl
# Create files (persistent across restarts)
echo "data" > /workspace/myfile.txt
# Check resources
free -h
df -h
All data in /workspace is persistent across container stops/starts. Other directories are ephemeral.
Docker Compose Configuration
The complete docker-compose.yml sets up Rexec with all dependencies:
version : "3.8"
services :
# Rexec API (connects to remote Docker daemon)
rexec :
build :
context : ../
dockerfile : Dockerfile
ports :
- "8080:8080"
- "22:22" # SSH Gateway (optional, enable with SSH_GATEWAY_ENABLED=true)
environment :
- PORT=8080
- JWT_SECRET=${JWT_SECRET:-rexec-dev-secret-change-me}
- DATABASE_URL=postgres://rexec:${POSTGRES_PASSWORD:-rexec_dev_password}@postgres:5432/rexec?sslmode=disable
- REDIS_URL=redis://redis:6379
# Remote Docker daemon configuration
- DOCKER_HOST=${DOCKER_HOST}
- DOCKER_TLS_VERIFY=${DOCKER_TLS_VERIFY:-1}
- DOCKER_CA_CERT=${DOCKER_CA_CERT}
- DOCKER_CLIENT_CERT=${DOCKER_CLIENT_CERT}
- DOCKER_CLIENT_KEY=${DOCKER_CLIENT_KEY}
# SSH Gateway configuration
- SSH_GATEWAY_ENABLED=${SSH_GATEWAY_ENABLED:-false}
- SSH_GATEWAY_HOST_KEY=/app/.ssh/host_key
depends_on :
postgres :
condition : service_healthy
redis :
condition : service_started
volumes :
- recordings-data:/app/recordings
- ssh-keys:/app/.ssh # SSH host keys (persistent)
restart : unless-stopped
networks :
- rexec-network
healthcheck :
test : [ "CMD" , "curl" , "-f" , "http://localhost:8080/health" ]
interval : 30s
timeout : 10s
retries : 3
start_period : 10s
# Redis for session management
redis :
image : redis:7-alpine
volumes :
- redis-data:/data
restart : unless-stopped
networks :
- rexec-network
# PostgreSQL for user data
postgres :
image : postgres:16-alpine
environment :
- POSTGRES_USER=rexec
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-rexec_dev_password}
- POSTGRES_DB=rexec
volumes :
- postgres-data:/var/lib/postgresql/data
healthcheck :
test : [ "CMD-SHELL" , "pg_isready -U rexec -d rexec" ]
interval : 5s
timeout : 5s
retries : 5
restart : unless-stopped
networks :
- rexec-network
volumes :
redis-data :
postgres-data :
recordings-data :
ssh-keys :
networks :
rexec-network :
driver : bridge
Using the API
Rexec provides a REST API for programmatic container management.
Authentication
First, obtain an API token:
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "admin"
}'
Response:
{
"token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"user" : {
"id" : "user-123" ,
"email" : "[email protected] "
}
}
Create a Container
curl -X POST http://localhost:8080/api/containers \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"image": "ubuntu:24.04",
"name": "api-sandbox",
"role": "webdev",
"shell": {
"enhanced": true,
"theme": "dracula",
"use_tmux": false
},
"memory_mb": 2048,
"cpu_shares": 1024,
"disk_mb": 8192
}'
Response:
{
"id" : "abc123def456" ,
"name" : "api-sandbox" ,
"image" : "ubuntu:24.04" ,
"status" : "creating" ,
"async" : true ,
"message" : "Container is being created. This may take a moment if the image needs to be pulled." ,
"resources" : {
"memory_mb" : 2048 ,
"cpu_shares" : 1024 ,
"disk_mb" : 8192
}
}
List Containers
curl -X GET http://localhost:8080/api/containers \
-H "Authorization: Bearer YOUR_TOKEN"
Execute Commands
Connect to the WebSocket terminal endpoint:
ws://localhost:8080/ws/terminal/{containerId}?token=YOUR_TOKEN
Manage Container Lifecycle
Start Container
Stop Container
Delete Container
Update Settings
curl -X POST http://localhost:8080/api/containers/{id}/start \
-H "Authorization: Bearer YOUR_TOKEN"
Using the SDKs
Rexec provides official SDKs for multiple languages.
Go SDK
Install:
go get github.com/brimblehq/rexec-go
Example:
package main
import (
" context "
" fmt "
" log "
rexec " github.com/brimblehq/rexec-go "
)
func main () {
// Create client
client := rexec . NewClient ( "https://your-rexec-instance.com" , "your-api-token" )
ctx := context . Background ()
// Create a container
container , err := client . Containers . Create ( ctx , & rexec . CreateContainerRequest {
Image : "ubuntu:24.04" ,
Name : "my-sandbox" ,
})
if err != nil {
log . Fatal ( err )
}
fmt . Printf ( "Created container: %s \n " , container . ID )
// Connect to terminal
term , err := client . Terminal . Connect ( ctx , container . ID )
if err != nil {
log . Fatal ( err )
}
defer term . Close ()
// Send a command
term . Write ([] byte ( "echo 'Hello from Rexec!' \n " ))
// Read output
output , _ := term . Read ()
fmt . Printf ( "Output: %s \n " , output )
// Clean up
client . Containers . Delete ( ctx , container . ID )
}
JavaScript/TypeScript SDK
Install:
npm install @pipeopshq/rexec
Example:
import { RexecClient } from '@pipeopshq/rexec' ;
const client = new RexecClient ({
baseURL: 'https://your-rexec-instance.com' ,
token: 'your-api-token'
});
// Create a container
const container = await client . containers . create ({
image: 'ubuntu:24.04' ,
name: 'my-sandbox'
});
console . log ( `Created container: ${ container . id } ` );
// Connect to terminal
const terminal = await client . terminal . connect ( container . id );
terminal . onData (( data ) => {
console . log ( 'Output:' , data );
});
terminal . write ( 'echo "Hello from Rexec!" \n ' );
// Clean up
await client . containers . delete ( container . id );
Integration with xterm.js
For web applications, integrate with xterm.js:
import { Terminal } from 'xterm' ;
import { RexecClient } from '@pipeopshq/rexec' ;
const xterm = new Terminal ();
xterm . open ( document . getElementById ( 'terminal' ));
const client = new RexecClient ({
baseURL: 'https://your-rexec-instance.com' ,
token: 'your-api-token'
});
const container = await client . containers . create ({ image: 'ubuntu:24.04' });
const rexecTerminal = await client . terminal . connect ( container . id , {
cols: xterm . cols ,
rows: xterm . rows
});
// Connect xterm to rexec terminal
rexecTerminal . onData (( data ) => {
xterm . write ( data );
});
xterm . onData (( data ) => {
rexecTerminal . write ( data );
});
xterm . onResize (({ cols , rows }) => {
rexecTerminal . resize ( cols , rows );
});
Configuration
Rexec is configured via environment variables:
Variable Description Default PORTAPI listen port 8080DATABASE_URLPostgreSQL connection string postgres://...JWT_SECRETRequired. Secret for signing auth tokens(Random if unset) REDIS_URLRedis connection string redis://localhost:6379GIN_MODEWeb framework mode (debug or release) debugDOCKER_HOSTRemote Docker daemon address (Uses local Docker socket) SSH_GATEWAY_ENABLEDEnable SSH gateway on port 22 falseS3_BUCKETS3 bucket for storing session recordings (Optional) S3_REGIONS3 region us-east-1
Create a .env file in the project root to set these variables. See .env.example for a complete list.
Next Steps
Connect Your Machines Install the Rexec Agent on your infrastructure for secure remote access
Session Recording Record and replay terminal sessions for documentation
API Reference Explore the complete API documentation
Security Learn about MFA, audit logging, and security features
Troubleshooting
Container creation fails with 'image pull' error
This usually means Docker couldn’t pull the image. Check:
Docker daemon is running: docker ps
Internet connectivity: docker pull ubuntu:24.04
Docker Hub rate limits (use authenticated pulls)
Custom image names are valid: registry.example.com/image:tag
Can't connect to terminal WebSocket
Verify:
Container status is running: Check dashboard or API
WebSocket proxy configuration (if behind nginx/traefik)
JWT token is valid and not expired
Firewall allows WebSocket connections on port 8080
Database connection errors
Ensure PostgreSQL is healthy: docker compose logs postgres
docker compose exec postgres pg_isready -U rexec
Check DATABASE_URL format: postgres://user:password@host:5432/database?sslmode=disable
Containers have resource limits based on your tier:
Free: 2GB RAM, 2 vCPU
Pro: 4GB RAM, 4 vCPU
Enterprise: Custom limits
Upgrade your plan or adjust limits in container settings.
Need help? Join the community: