Skip to content

Local Setup

This guide walks you through setting up a complete development environment for Rack Gateway.

Before starting, ensure you have these tools installed:

ToolVersionPurpose
Go1.22+Backend development
DockerLatestContainer runtime
Node.js20+Web frontend tooling
Bun1.3+Package manager and runtime
Task3.0+Task runner
miseLatestEnvironment variable management
Terminal window
# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Go
brew install go
# Install Docker Desktop
brew install --cask docker
# Install Node.js
brew install node
# Install Bun
curl -fsSL https://bun.sh/install | bash
# Install Task
brew install go-task
# Install mise
brew install mise
  1. Clone the repository

    Terminal window
    git clone https://github.com/docspring/rack-gateway.git
    cd rack-gateway
  2. Install dependencies

    Terminal window
    # Install tooling and dependencies
    task dev-setup
    task go:deps
    task web:deps
    task mock-oauth:deps
  3. Configure environment

    Terminal window
    # Create local configuration
    cp mise.local.toml.example mise.local.toml
    # Edit with your Google OAuth credentials (optional for mock mode)
    # See "Google OAuth Setup" section below
  4. Start development environment

    Terminal window
    task dev
  5. Verify services are running

    Terminal window
    # Gateway health
    curl http://localhost:8447/api/v1/health
    # Expected: {"status":"ok"}
    # Open Web UI
    open http://localhost:5223

Rack Gateway uses mise for environment variable management. Configuration is layered:

FilePurposeGit Status
mise.tomlDefault configurationChecked in
mise.local.tomlLocal overridesGitignored

Create your local configuration:

Terminal window
cp mise.local.toml.example mise.local.toml
mise.local.toml
[env]
# Google OAuth (optional - mock OAuth works by default)
GOOGLE_CLIENT_ID = "your-client-id.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET = "your-client-secret"
GOOGLE_ALLOWED_DOMAIN = "yourdomain.com"
# Debug logging
LOG_LEVEL = "debug"
# Custom session secret (optional)
APP_SECRET_KEY = "your-local-session-secret"

The development environment uses PostgreSQL in Docker. Connection details:

SettingValue
Hostlocalhost
Port55432
Databasegateway_dev
Userpostgres
Passwordpostgres
Terminal window
# Connect to development database
docker exec -it rack-gateway-postgres-1 psql -U postgres -d gateway_dev
# Run migrations manually
task db:migrate

For testing with real Google OAuth (instead of mock):

  1. Create Google Cloud Project

  2. Enable Google+ API

    • Navigate to “APIs & Services” → “Library”
    • Search for “Google+ API”
    • Click “Enable”
  3. Configure OAuth Consent Screen

    • Go to “APIs & Services” → “OAuth consent screen”
    • Choose “Internal” for Google Workspace users
    • Fill required fields:
      • App name: “Rack Gateway (Dev)”
      • Support email: your email
    • Add scopes: openid, email, profile
  4. Create OAuth Credentials

    • Go to “APIs & Services” → “Credentials”
    • Click ”+ CREATE CREDENTIALS” → “OAuth client ID”
    • Choose “Web application”
    • Add redirect URI: http://localhost:8447/api/v1/auth/cli/callback
    • Save credentials
  5. Update Configuration

    mise.local.toml
    [env]
    GOOGLE_CLIENT_ID = "your-client-id.apps.googleusercontent.com"
    GOOGLE_CLIENT_SECRET = "your-client-secret"
    GOOGLE_ALLOWED_DOMAIN = "yourdomain.com"
    # Disable mock OAuth
    MOCK_OAUTH_ENABLED = "false"
Terminal window
# Start all services (Gateway, Web UI, Mock OAuth, Mock Convox)
task dev
# View logs
task dev:logs
# Stop all services
task dev:down

For debugging specific components:

Terminal window
# Build all binaries
task build
# Run gateway server directly
./bin/rack-gateway-api
# Run CLI commands
./bin/rack-gateway login local http://localhost:8447
./bin/rack-gateway convox apps
  1. Start development environment

    Terminal window
    task dev
  2. Login via Web UI

    • Open http://localhost:5223
    • Click “Login with Google”
    • Complete OAuth flow (mock OAuth auto-approves)
  3. Login via CLI

    Terminal window
    # Build CLI
    task go:build:cli
    # Login to local gateway
    ./bin/rack-gateway login local http://localhost:8447
    # Browser opens for OAuth, then CLI stores token
  4. Test proxied commands

    Terminal window
    ./bin/rack-gateway convox rack
    ./bin/rack-gateway convox apps
    ./bin/rack-gateway convox ps -a myapp
Terminal window
# Start just the web dev server (assumes gateway is running)
cd web && bun run dev
# Run web tests
task web:test
# Run E2E tests
task web:e2e
Terminal window
# Run migrations
task db:migrate
# Reset database (deletes all data)
task db:reset
# Access psql
docker exec -it rack-gateway-postgres-1 psql -U postgres -d gateway_dev

If ports are already in use:

Terminal window
# Find process using a port
lsof -i :8447
# Kill process
kill -9 <PID>
# Or change ports in mise.local.toml
Terminal window
# Restart Docker containers
task docker:down
task docker:up
# Rebuild images
task docker:reset
# Check container logs
docker logs rack-gateway-postgres-1
  • “redirect_uri mismatch”: Ensure the redirect URI in Google Cloud Console exactly matches http://localhost:8447/api/v1/auth/cli/callback
  • “Invalid client”: Verify GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in mise.local.toml

The CLI stores configuration in different locations:

EnvironmentLocation
Development./config/cli/
Production~/.config/rack-gateway/

In development, set:

Terminal window
export GATEWAY_CLI_CONFIG_DIR=./config/cli
Terminal window
# Verify PostgreSQL is running
docker ps | grep postgres
# Test connection
docker exec -it rack-gateway-postgres-1 psql -U postgres -c "SELECT 1"
# Check database exists
docker exec -it rack-gateway-postgres-1 psql -U postgres -c "\l"

Recommended extensions:

  • Go - Go language support
  • ESLint - JavaScript/TypeScript linting
  • Prettier - Code formatting
  • Docker - Docker support

Settings (.vscode/settings.json):

{
"go.lintTool": "golangci-lint",
"go.lintFlags": ["--fast"],
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[go]": {
"editor.defaultFormatter": "golang.go"
}
}
  • Enable “Go Modules” integration
  • Configure golangci-lint as external tool
  • Set up Biome for TypeScript