Skip to content

Self-Hosting with Docker Compose

  • Docker and Docker Compose v2
  • An Auth0 tenant (for user authentication)
  • Node.js 18+ (for the web frontend)
Terminal window
git clone https://github.com/gregorycarter/bridge-town-core.git
cd bridge-town-core
cp .env.example .env
# Edit .env with your Auth0 credentials
docker compose up -d

This starts:

ServicePortDescription
web3000Next.js frontend
mcp_server8000FastAPI MCP server
postgres5434PostgreSQL 16 with RLS
redis6380Rate limiting + Celery broker
gitea3001Git server
celery_workerAsync task execution
celery_beatScheduled tasks

Key variables for the MCP server (mcp_server service):

VariableDescription
DATABASE_URLPostgreSQL connection string
REDIS_URLRedis URL for rate limiting
GITEA_URLInternal Gitea URL
AUTH0_DOMAINAuth0 tenant domain (e.g. your-tenant.us.auth0.com)
AUTH0_AUDIENCEAuth0 JWT audience — must be a URL (e.g. https://api.example.com). Used as the JWT audience claim value for /authorize and /token requests. In standard deployments this also serves as the OAuth metadata and relay-callback base URL.
OAUTH_PUBLIC_BASE_URL(Optional) Public HTTPS base URL for OAuth metadata (RFC 9728/8414) and the localhost relay-callback endpoint. Set this only when your reverse proxy exposes the API at a different URL than AUTH0_AUDIENCE (e.g. https://api.example.com behind a proxy while AUTH0_AUDIENCE is an internal value). Defaults to AUTH0_AUDIENCE when not set.
RATE_LIMIT_FAIL_OPENtrue for dev (skip rate limiting if Redis is down)

For external testing without a public deployment:

Terminal window
./scripts/start-funnel.sh

This starts Docker Compose with Funnel-specific overrides and configures Tailscale path-based routing:

  • / → web (port 3000)
  • /mcp → mcp_server (port 8000)

See docker-compose.funnel.yml for the environment overrides.

Terminal window
docker compose exec mcp_server pytest tests/ -x