Skip to content

This is a docker file to setup the signalwire SDKs and build a dev / test env for new developers.

Notifications You must be signed in to change notification settings

signalwire/WireStarter

Repository files navigation

WireStarter

A batteries-included Docker development environment for building SignalWire applications.

Screenshot of WireStarter

Features

  • Pre-configured SignalWire SDKs - Python SDK, signalwire-agents, SWML, SWAIG ready to use
  • Automatic tunneling - ngrok or Cloudflare Tunnel for public webhook URLs
  • Persistent storage - Your code, venvs, configs, and credentials survive container rebuilds
  • Interactive setup - TUI menus for configuring credentials and tools
  • Built-in services - Redis, nginx, PostgreSQL, FreeSWITCH available on demand
  • AI coding assistants - Claude Code and Gemini CLI pre-installed with MCP support
  • Developer tools - Git, tmux, editors (vim/emacs/nano/micro/ne), debugging utilities
  • Security - Global gitignore prevents accidental credential commits

Prerequisites

Quick Start

1. Clone and configure

git clone https://github.com/signalwire/WireStarter.git
cd WireStarter
cp env.example .env

Edit .env with your credentials:

SIGNALWIRE_SPACE_NAME=yourspace
SIGNALWIRE_PROJECT_ID=your-project-id
SIGNALWIRE_TOKEN=your-api-token
NGROK_TOKEN=your-ngrok-token
WORKDIR=/path/to/your/workspace

2. Start the container

make up      # Start in background
make enter   # Enter the container

3. First run

On first entry, WireStarter validates your SignalWire credentials and drops you into the SignalWire Shell (swsh). Type exit to access the full bash environment.

Run setup for the interactive configuration menu.

Container Commands

From your host machine

Command Description
make up Build and start container (detached)
make down Stop container
make enter Enter running container
make build Rebuild image (no cache)
make debug Run container in foreground
make clean Stop and prune Docker system
make push Build and push multi-arch image

Inside the Container

Type help for a complete command reference.

Interactive Setup Menu

setup                 # Interactive environment setup menu

The setup menu provides:

Option Description
Setup SignalWire & NGROK Credentials Configure API keys and ngrok token (required)
Start ngrok Tunnel Start/restart the ngrok tunnel
Setup Cloudflare Tunnel Alternative to ngrok using Cloudflare
Setup AI API Keys Configure Claude/Gemini API keys or OAuth
Add MCP Servers Add Model Context Protocol servers to Claude/Gemini
Remove MCP Server Remove configured MCP servers
Setup Git Identity Configure git user, email, and GitHub token
Setup SSH Key Generate ED25519 SSH key for git
Setup Go Install latest Go to /workdir/.go
Setup NVM + Node.js Install NVM and Node.js LTS
Setup PostgreSQL Initialize PostgreSQL in /workdir/postgres
Setup FreeSWITCH Install FreeSWITCH (requires PAT)
Setup Python Dev Tools Install black, pytest, build, twine
Setup Audio Tools Install pydub for audio processing
Setup All Dev Tools Install Go, NVM, PostgreSQL, Python tools
Enable/Disable swsh Toggle SignalWire Shell on login
Show Status Display current environment status
Clean Environment Remove all dev tools and configs

Python Virtual Environments

Venvs are stored in /workdir/.venvs/ and persist across container rebuilds.

venv init             # Create venv for current directory
venv delete           # Delete venv for current directory
venv list             # List all venvs
venv nuke             # Delete currently active venv

Venvs auto-activate when you cd into a directory that has one.

Project Scaffolding

newproject myapp      # Create Flask project with venv
newagent mybot        # Create full SignalWire agent project

The newagent command creates a complete project structure:

  • agents/ - Agent modules with AgentBase patterns
  • skills/ - Reusable skills
  • tests/ - Pytest test scaffolding
  • web/ - Static files with WebRTC calling interface
  • .env - Pre-configured with your SignalWire credentials

Running Applications

up                    # Run app.py in loop (auto-restart on crash)
up server.py          # Run specific script
watch                 # Auto-restart on file changes
serve 5000            # Run Flask dev server

SignalWire Tools

swsh                  # SignalWire Shell - interactive CLI
sw_test               # Test API credentials
sw_numbers            # List phone numbers
swpy                  # Python REPL with SignalWire client loaded

Networking & Debugging

urls                  # Show ngrok tunnel URLs
tunnel                # Print ngrok URL
testapp               # Test local and public endpoints
webhook               # Start webhook catcher (dumps requests)
logs                  # Tail nginx access log
reqs                  # Formatted request log

Process Management

ports                 # Show what's running on 5000, 5001, 9080
killport 5000         # Kill process on port
reload                # Reload nginx
tmux attach -t ngrok  # Attach to ngrok session
tmux attach -t cloudflared  # Attach to Cloudflare tunnel session

Redis

redis                 # Redis CLI
rkeys                 # List all keys
rget mykey            # Get value
rclear                # Flush all data

PostgreSQL

psql                  # Connect to PostgreSQL (auto-configured)

Git Shortcuts

gs                    # git status
gd                    # git diff
gl                    # git log --oneline -20
gp                    # git pull

Navigation

work                  # cd /workdir
public                # cd /workdir/public
..                    # cd ..
...                   # cd ../..

Architecture

Services

On startup, WireStarter runs:

  1. ngrok (if configured) - Tunnels port 9080 to a public URL (runs in tmux)
  2. Cloudflare Tunnel (if configured) - Alternative tunnel to ngrok (runs in tmux)
  3. nginx - Reverse proxy on port 9080
    • / → localhost:5000 (your app)
    • /webhook → localhost:5002 (webhook catcher)
    • /public → /workdir/public (static files)
  4. Redis - Available on default port
  5. PostgreSQL (if configured) - Auto-starts if data directory exists

Persistent Storage

Everything in /workdir persists across container rebuilds. The following files and directories are automatically symlinked from /workdir to their expected locations:

Path Purpose
/workdir/.env Environment variables (SignalWire, ngrok, etc.)
/workdir/.bashrc Custom bash configuration
/workdir/.venvs/ Python virtual environments
/workdir/.ssh/ SSH keys
/workdir/.gitconfig Git configuration
/workdir/.git-credentials Git credential storage
/workdir/.gitignore_global Global gitignore (auto-created)
/workdir/.go/ Go installation
/workdir/.nvm/ NVM + Node.js
/workdir/.npm/ NPM cache
/workdir/.npmrc NPM configuration
/workdir/.claude/ Claude Code auth & session data
/workdir/.claude.json Claude Code MCP configuration
/workdir/.gemini/ Gemini CLI auth & config
/workdir/.cloudflared/ Cloudflare Tunnel config & token
/workdir/.config/ XDG config (GitHub Copilot, etc.)
/workdir/.emacs Emacs configuration
/workdir/.vimrc Vim configuration
/workdir/.nanorc Nano configuration
/workdir/.pypirc PyPI configuration
/workdir/.swsh_history SignalWire Shell history
/workdir/postgres/ PostgreSQL data directory
/workdir/public/ Static files (served at tunnel URL/public)

Security Features

Global Gitignore: WireStarter automatically creates /workdir/.gitignore_global to prevent accidentally committing secrets. The following patterns are globally ignored in all git repositories:

  • .env, .env.*, *.env, .envrc
  • credentials.json, *_credentials.json
  • *.pem, *.key
  • id_rsa, id_ed25519
  • .npmrc
  • .claude.json, .claude.json.backup

Token Storage: Sensitive tokens (like Cloudflare Tunnel) are stored in dedicated files with restricted permissions (chmod 600) rather than in .env.

Pre-installed Packages

System: git, curl, wget, jq, tmux, screen, ffmpeg, sox, sqlite3, ncdu, cloudflared

Editors: vim, emacs, nano, micro, ne

Python: signalwire, signalwire-agents, signalwire-swml, signalwire-swaig, flask, requests, ipython, httpie, black

AI Tools: Claude Code, Gemini CLI (with MCP server support)

Tunneling Options

ngrok (Default)

Set NGROK_TOKEN in your .env file. The tunnel starts automatically on container launch.

# Optional: Use a custom domain
NGROK_ARGS="--url yourdomain.ngrok.io"

Access the ngrok session: tmux attach -t ngrok

Cloudflare Tunnel (Alternative)

  1. Create a tunnel in Cloudflare Zero Trust Dashboard
  2. Run setup and select "Setup Cloudflare Tunnel"
  3. Enter your tunnel token

The tunnel runs in a tmux session and auto-starts on container launch.

Access the cloudflared session: tmux attach -t cloudflared

Environment Variables

Variable Required Description
SIGNALWIRE_SPACE_NAME Yes Your SignalWire space (without .signalwire.com)
SIGNALWIRE_PROJECT_ID Yes SignalWire project ID
SIGNALWIRE_TOKEN Yes SignalWire API token
NGROK_TOKEN Yes* ngrok auth token (*or use Cloudflare Tunnel)
NGROK_ARGS No Additional ngrok arguments (e.g., --url yourdomain.ngrok.io)
FREESWITCH_PAT No FreeSWITCH package access token
WORKDIR Yes Host directory to mount as /workdir
VISUAL No Preferred editor (vim/emacs/nano/micro/ne)
ANTHROPIC_API_KEY No Claude API key (alternative to OAuth)
GEMINI_API_KEY No Gemini API key (alternative to OAuth)
GITHUB_TOKEN No GitHub personal access token
SLACK_BOT_TOKEN No Slack bot token (for MCP server)
BRAVE_API_KEY No Brave Search API key (for MCP server)

AI Coding Assistants

Claude Code

Claude Code is pre-installed. Authenticate via:

  • OAuth: claude (browser-based login)
  • API Key: Set ANTHROPIC_API_KEY in setup

MCP servers can be added via the setup menu for enhanced capabilities (filesystem access, GitHub, memory, etc.).

Gemini CLI

Gemini CLI is pre-installed. Authenticate via:

  • OAuth: gemini (browser-based login)
  • API Key: Set GEMINI_API_KEY in setup

Example: Creating a SignalWire Agent

# Enter the container
make enter

# Exit swsh to get to bash
exit

# Create a new agent project
newagent mybot
cd /workdir/mybot

# Edit the agent logic
vim agents/main_agent.py

# Run it
up

# Your agent is now available at the ngrok URL
urls

Webhook Development

WireStarter includes a webhook catcher for debugging callbacks:

# Start the webhook catcher
webhook

# Your webhook URL is:
# https://your-tunnel-url/webhook
# https://your-tunnel-url/webhook/xml (returns XML/LaML)

All incoming requests are pretty-printed to the console with headers, body, and query parameters.

Troubleshooting

Container exits immediately

  • Check that .env exists and has valid credentials
  • Run make debug to see startup errors

ngrok not working

  • Verify NGROK_TOKEN is set in .env
  • Check ngrok status: curl http://127.0.0.1:4040/api/tunnels
  • Attach to session: tmux attach -t ngrok

Cloudflare Tunnel not working

  • Check the tunnel session: tmux attach -t cloudflared
  • Verify token file exists: ls -la /workdir/.cloudflared/token
  • Re-run setup to reconfigure

SignalWire credentials fail

  • Run sw_test to validate credentials
  • Ensure space name doesn't include .signalwire.com

Venv not activating

  • Only works in /workdir/* directories
  • Run venv init to create one

PostgreSQL not starting

  • Check if data exists: ls /workdir/postgres/PG_VERSION
  • Run setup → "Setup PostgreSQL" to initialize

Platform-Specific Installation

Windows

  1. Install Docker Desktop and GitHub Desktop
  2. Clone repository via GitHub Desktop
  3. Open in Command Prompt: Repository > Open in Command Prompt
  4. Run windows-start.bat

Linux Quick Start

chmod +x Start-WireStarter.sh
./Start-WireStarter.sh

macOS / Linux

git clone https://github.com/signalwire/WireStarter.git
cd WireStarter
cp env.example .env
# Edit .env with your credentials
make up
make enter

Contributing

Issues and pull requests welcome at github.com/signalwire/WireStarter.

License

MIT License - See LICENSE file for details.

About

This is a docker file to setup the signalwire SDKs and build a dev / test env for new developers.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 6