From 2d772351c151ed984719555f52bbc5924585ea98 Mon Sep 17 00:00:00 2001 From: Brian Olson Date: Wed, 31 Dec 2025 20:44:58 -0500 Subject: [PATCH 1/4] docs: add system requirements to README Add detailed system requirements including: - Minimum specs for building (2 cores, 2GB RAM) - Runtime-only specs for pre-built images (1 core, 512MB) - Recommended production specs (2+ cores, 2GB RAM) - Note about memory requirements for Docker build Fixes #132 --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 68afa4d..880b30d 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,41 @@ Tabby Web serves the [Tabby Terminal](https://github.com/Eugeny/tabby) as a web # Requirements -* Python 3.7+ +## Software Requirements + +* Python 3.10+ (3.12 recommended) +* Node.js 18+ (for frontend build) * A database server supported by Django (MariaDB, Postgres, SQLite, etc.) * Storage for distribution files - local, S3, GCS or others supported by `fsspec` +* Docker and Docker Compose (for containerized deployment) + +## System Requirements + +### Minimum (Build & Run) + +| Resource | Requirement | +|----------|-------------| +| CPU | 2 cores | +| RAM | 2GB (4GB recommended for building) | +| Disk | 5GB | + +> **Note:** Building the Docker image requires significant memory for the frontend compilation step. If you're running on a memory-constrained system (like Oracle Cloud Free Tier), consider using a pre-built image or building on a machine with more RAM. + +### Runtime Only (Pre-built Image) + +| Resource | Requirement | +|----------|-------------| +| CPU | 1 core | +| RAM | 512MB | +| Disk | 1GB + app distributions | + +### Recommended (Production) + +| Resource | Requirement | +|----------|-------------| +| CPU | 2+ cores | +| RAM | 2GB | +| Disk | 10GB | # Quickstart (using `docker-compose`) From 9544e363c9eb32fe1c87dbeb0f384d2f3de6832e Mon Sep 17 00:00:00 2001 From: Brian Olson Date: Wed, 31 Dec 2025 20:46:53 -0500 Subject: [PATCH 2/4] feat: add Azure AD single-tenant authentication support Add support for AzureADTenantOAuth2 backend which allows restricting authentication to a specific Azure AD tenant (organization). Configuration: - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY: Azure app client ID - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET: Azure app client secret - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID: Azure AD Directory ID This enables organizations to restrict Tabby Web access to only users from their Azure AD tenant, preventing personal Microsoft accounts or users from other organizations from logging in. Fixes #120 --- README.md | 15 ++++++++++++++- backend/tabby/settings.py | 5 +++++ docker-compose.yml | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 68afa4d..8c629b6 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,20 @@ For SSH and Telnet, once logged in, enter your connection gateway address and au * `DATABASE_URL` (required). * `APP_DIST_STORAGE`: a `file://`, `s3://`, or `gcs://` URL to store app distros in. -* `SOCIAL_AUTH_*_KEY` & `SOCIAL_AUTH_*_SECRET`: social login credentials, supported providers are `GITHUB`, `GITLAB`, `MICROSOFT_GRAPH` and `GOOGLE_OAUTH2`. + +### OAuth Providers + +Configure one or more OAuth providers for authentication: + +| Provider | Variables | +|----------|-----------| +| GitHub | `SOCIAL_AUTH_GITHUB_KEY`, `SOCIAL_AUTH_GITHUB_SECRET` | +| GitLab | `SOCIAL_AUTH_GITLAB_KEY`, `SOCIAL_AUTH_GITLAB_SECRET` | +| Google | `SOCIAL_AUTH_GOOGLE_OAUTH2_KEY`, `SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET` | +| Microsoft (multi-tenant) | `SOCIAL_AUTH_MICROSOFT_GRAPH_KEY`, `SOCIAL_AUTH_MICROSOFT_GRAPH_SECRET` | +| Azure AD (single-tenant) | `SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY`, `SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET`, `SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID` | + +**Azure AD Single-Tenant:** Use this instead of Microsoft Graph if you want to restrict login to users from a specific Azure AD tenant (organization). Set `TENANT_ID` to your Azure AD Directory (tenant) ID. ## Adding Tabby app versions diff --git a/backend/tabby/settings.py b/backend/tabby/settings.py index 0714461..22b3b50 100644 --- a/backend/tabby/settings.py +++ b/backend/tabby/settings.py @@ -138,6 +138,7 @@ AUTHENTICATION_BACKENDS = ( "social_core.backends.github.GithubOAuth2", "social_core.backends.gitlab.GitLabOAuth2", "social_core.backends.azuread.AzureADOAuth2", + "social_core.backends.azuread_tenant.AzureADTenantOAuth2", # Single-tenant Azure AD "social_core.backends.microsoft.MicrosoftOAuth2", "social_core.backends.google.GoogleOAuth2", "django.contrib.auth.backends.ModelBackend", @@ -180,6 +181,10 @@ for key in [ "SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET", "SOCIAL_AUTH_MICROSOFT_GRAPH_KEY", "SOCIAL_AUTH_MICROSOFT_GRAPH_SECRET", + # Azure AD single-tenant (use instead of multi-tenant for org-only access) + "SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY", + "SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET", + "SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID", "CONNECTION_GATEWAY_AUTH_CA", "CONNECTION_GATEWAY_AUTH_CERTIFICATE", "CONNECTION_GATEWAY_AUTH_KEY", diff --git a/docker-compose.yml b/docker-compose.yml index 6202d8e..cf91cc2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,24 @@ services: - PORT=80 - DEBUG=False - DOCKERIZE_ARGS="-wait tcp://db:3306 -timeout 60s" + # + # OAuth Providers - uncomment and configure: + # - SOCIAL_AUTH_GITHUB_KEY=your_github_client_id + # - SOCIAL_AUTH_GITHUB_SECRET=your_github_client_secret + # - SOCIAL_AUTH_GITLAB_KEY=your_gitlab_client_id + # - SOCIAL_AUTH_GITLAB_SECRET=your_gitlab_client_secret + # - SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=your_google_client_id + # - SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=your_google_client_secret + # + # Microsoft/Azure AD (multi-tenant - allows any Microsoft account): + # - SOCIAL_AUTH_MICROSOFT_GRAPH_KEY=your_microsoft_client_id + # - SOCIAL_AUTH_MICROSOFT_GRAPH_SECRET=your_microsoft_client_secret + # + # Azure AD Single-Tenant (restricts to specific organization): + # - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY=your_azure_client_id + # - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET=your_azure_client_secret + # - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID=your_tenant_id + # # - APP_DIST_STORAGE="file:///app-dist" db: From 15e0469de482b47cd662bf9a50228f973ee5bbe1 Mon Sep 17 00:00:00 2001 From: Brian Olson Date: Wed, 31 Dec 2025 20:48:26 -0500 Subject: [PATCH 3/4] docs: add comprehensive deployment guide Add detailed deployment documentation covering: - Quick start guide - System requirements - Docker Compose production configuration - Reverse proxy setup (Nginx, Traefik, Caddy) - OAuth provider configuration for all supported providers - Connection gateway setup - Troubleshooting common issues Also update README with links to documentation. Fixes #135, #137 --- README.md | 5 + docs/DEPLOYMENT.md | 300 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100644 docs/DEPLOYMENT.md diff --git a/README.md b/README.md index 68afa4d..f7106db 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,11 @@ This is the Tabby terminal, served as a web app. It also provides the config syn Tabby Web serves the [Tabby Terminal](https://github.com/Eugeny/tabby) as a web application while managing multiple config files, authentication, and providing TCP connections via a [separate gateway service](https://github.com/Eugeny/tabby-connection-gateway). +# Documentation + +- **[Deployment Guide](docs/DEPLOYMENT.md)** - Complete guide for production deployment +- **[Connection Gateway](https://github.com/Eugeny/tabby-connection-gateway)** - For SSH/Telnet connections + # Requirements * Python 3.7+ diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md new file mode 100644 index 0000000..73808d4 --- /dev/null +++ b/docs/DEPLOYMENT.md @@ -0,0 +1,300 @@ +# Tabby Web Deployment Guide + +This guide covers deploying Tabby Web in production environments. + +## Table of Contents + +- [Quick Start](#quick-start) +- [Prerequisites](#prerequisites) +- [Docker Compose Deployment](#docker-compose-deployment) +- [Reverse Proxy Configuration](#reverse-proxy-configuration) +- [OAuth Provider Setup](#oauth-provider-setup) +- [Adding Tabby Versions](#adding-tabby-versions) +- [Connection Gateway](#connection-gateway) +- [Troubleshooting](#troubleshooting) + +## Quick Start + +```bash +# Clone the repository +git clone https://github.com/Eugeny/tabby-web.git +cd tabby-web + +# Configure OAuth (at minimum, one provider) +export SOCIAL_AUTH_GITHUB_KEY=your_github_client_id +export SOCIAL_AUTH_GITHUB_SECRET=your_github_client_secret + +# Build and start +export DOCKER_BUILDKIT=1 +docker-compose up -d + +# Add a Tabby version +docker-compose exec tabby /manage.sh add_version 1.0.208 + +# Access at http://localhost:9090 +``` + +## Prerequisites + +### System Requirements + +| Resource | Minimum | Recommended | +|----------|---------|-------------| +| CPU | 2 cores | 2+ cores | +| RAM | 2GB (4GB for building) | 2GB | +| Disk | 5GB | 10GB | + +### Software Requirements + +- Docker 20.10+ with Docker Compose +- Docker BuildKit enabled (`export DOCKER_BUILDKIT=1`) + +### OAuth Credentials + +You need OAuth credentials from at least one provider: +- **GitHub**: Create an OAuth App at https://github.com/settings/developers +- **GitLab**: Create an Application at https://gitlab.com/-/profile/applications +- **Google**: Create OAuth credentials at https://console.cloud.google.com/apis/credentials +- **Microsoft**: Register an app at https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps + +## Docker Compose Deployment + +### 1. Create Environment File + +Create a `.env` file in the project root: + +```env +# Database (included MariaDB uses these defaults) +DATABASE_URL=mysql://root:123@db/tabby + +# OAuth Provider (configure at least one) +SOCIAL_AUTH_GITHUB_KEY=your_client_id +SOCIAL_AUTH_GITHUB_SECRET=your_client_secret + +# Optional: Custom app distribution storage +# APP_DIST_STORAGE=s3://bucket-name/path +``` + +### 2. Configure docker-compose.yml + +For production, update the `docker-compose.yml`: + +```yaml +services: + tabby: + build: . + restart: always + depends_on: + - db + ports: + - "127.0.0.1:9090:80" # Bind to localhost only (use reverse proxy) + environment: + - DATABASE_URL=mysql://root:${DB_PASSWORD}@db/tabby + - DEBUG=False + - SOCIAL_AUTH_GITHUB_KEY=${SOCIAL_AUTH_GITHUB_KEY} + - SOCIAL_AUTH_GITHUB_SECRET=${SOCIAL_AUTH_GITHUB_SECRET} + volumes: + - app-dist:/app/app-dist # Persist app distributions + + db: + image: mariadb:10.7.1 + restart: always + environment: + MARIADB_DATABASE: tabby + MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} + volumes: + - db-data:/var/lib/mysql # Persist database + +volumes: + app-dist: + db-data: +``` + +### 3. Build and Start + +```bash +export DOCKER_BUILDKIT=1 +docker-compose up -d --build +``` + +### 4. Verify Deployment + +```bash +# Check container status +docker-compose ps + +# Check logs +docker-compose logs -f tabby + +# Test the application +curl http://localhost:9090/api/1/auth/providers +``` + +## Reverse Proxy Configuration + +### Nginx + +```nginx +server { + listen 443 ssl http2; + server_name tabby.example.com; + + ssl_certificate /path/to/cert.pem; + ssl_certificate_key /path/to/key.pem; + + location / { + proxy_pass http://127.0.0.1:9090; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # WebSocket support (for terminal) + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} +``` + +### Traefik + +```yaml +http: + routers: + tabby: + rule: Host(`tabby.example.com`) + entryPoints: + - websecure + service: tabby + tls: + certResolver: letsencrypt + + services: + tabby: + loadBalancer: + servers: + - url: http://tabby:80 +``` + +### Caddy + +```caddyfile +tabby.example.com { + reverse_proxy localhost:9090 +} +``` + +## OAuth Provider Setup + +### GitHub + +1. Go to https://github.com/settings/developers +2. Click "New OAuth App" +3. Set Authorization callback URL to: `https://tabby.example.com/complete/github/` +4. Copy Client ID and Client Secret + +```env +SOCIAL_AUTH_GITHUB_KEY=your_client_id +SOCIAL_AUTH_GITHUB_SECRET=your_client_secret +``` + +### Google + +1. Go to https://console.cloud.google.com/apis/credentials +2. Create OAuth 2.0 Client ID +3. Add authorized redirect URI: `https://tabby.example.com/complete/google-oauth2/` + +```env +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=your_client_id +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=your_client_secret +``` + +### Azure AD (Single Tenant) + +For organization-only access: + +1. Go to https://portal.azure.com +2. Register a new application +3. Add redirect URI: `https://tabby.example.com/complete/azuread-tenant-oauth2/` +4. Create a client secret +5. Note your Tenant ID from the Overview page + +```env +SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY=your_client_id +SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET=your_client_secret +SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID=your_tenant_id +``` + +## Adding Tabby Versions + +After deployment, add Tabby app versions: + +```bash +# Add a specific version +docker-compose exec tabby /manage.sh add_version 1.0.208 + +# Check available versions at: +# https://www.npmjs.com/package/tabby-web-container +``` + +## Connection Gateway + +For SSH and Telnet connections, you need the [tabby-connection-gateway](https://github.com/Eugeny/tabby-connection-gateway). + +### Option 1: Use Hosted Gateway + +After logging in, the default gateway is already configured. No additional setup needed. + +### Option 2: Self-Hosted Gateway + +1. Deploy the gateway: https://github.com/Eugeny/tabby-connection-gateway +2. In Tabby Web settings, enter your gateway address and auth token + +## Troubleshooting + +### Build Fails with Memory Error + +The frontend build requires significant memory. Solutions: +- Use a machine with at least 4GB RAM for building +- Use a pre-built Docker image (when available) +- Increase Docker memory limit + +### "No authentication providers configured" + +No OAuth providers are set. Configure at least one: +```bash +docker-compose exec tabby printenv | grep SOCIAL_AUTH +``` + +### Database Connection Errors + +```bash +# Check database is running +docker-compose ps db + +# Check database logs +docker-compose logs db + +# Test connection +docker-compose exec tabby python -c "import django; django.setup(); from django.db import connection; connection.ensure_connection()" +``` + +### OAuth Callback Errors + +Verify your callback URLs match exactly: +- GitHub: `https://YOUR_DOMAIN/complete/github/` +- Google: `https://YOUR_DOMAIN/complete/google-oauth2/` +- Azure AD: `https://YOUR_DOMAIN/complete/azuread-tenant-oauth2/` + +### Container Starts but Page is Blank + +Check for JavaScript errors in browser console. Common causes: +- Mixed content (HTTP/HTTPS mismatch) +- CORS issues +- Missing app distribution + +```bash +# Check if app distribution exists +docker-compose exec tabby ls -la /app/app-dist/ +``` From cc4d030b732e1d0f3b3b086a775bb4de512cef2f Mon Sep 17 00:00:00 2001 From: Brian Olson Date: Wed, 31 Dec 2025 20:49:53 -0500 Subject: [PATCH 4/4] docs: document pre-built Docker image and add prebuilt compose file Add docker-compose.prebuilt.yml that uses the pre-built GHCR image, making deployment much easier for users who don't need to customize the build. Update README to prominently feature the pre-built image option as the recommended approach, reducing the barrier to entry. Pre-built images are available at: ghcr.io/eugeny/tabby-web:latest Fixes #115 --- README.md | 22 +++++++++++++++++--- docker-compose.prebuilt.yml | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 docker-compose.prebuilt.yml diff --git a/README.md b/README.md index 68afa4d..e2358e2 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,29 @@ You'll need: * OAuth credentials from GitHub, GitLab, Google or Microsoft for authentication. * For SSH and Telnet: a [`tabby-connection-gateway`](https://github.com/Eugeny/tabby-connection-gateway) to forward traffic. -* Docker BuildKit: `export DOCKER_BUILDKIT=1` + +## Option 1: Pre-built Image (Recommended) + +Use the pre-built image from GitHub Container Registry - no build required: ```bash - docker-compose up -e SOCIAL_AUTH_GITHUB_KEY=xxx -e SOCIAL_AUTH_GITHUB_SECRET=yyy +docker-compose -f docker-compose.prebuilt.yml up -d ``` -will start Tabby Web on port 9090 with MariaDB as a storage backend. +The image is available at `ghcr.io/eugeny/tabby-web:latest`. + +## Option 2: Build from Source + +If you need to customize the build: + +```bash +export DOCKER_BUILDKIT=1 +docker-compose up -d +``` + +--- + +Both options will start Tabby Web on port 9090 with MariaDB as a storage backend. For SSH and Telnet, once logged in, enter your connection gateway address and auth token in the settings. diff --git a/docker-compose.prebuilt.yml b/docker-compose.prebuilt.yml new file mode 100644 index 0000000..e802d31 --- /dev/null +++ b/docker-compose.prebuilt.yml @@ -0,0 +1,40 @@ +# Use this file for quick deployment with pre-built images (no build required) +# Usage: docker-compose -f docker-compose.prebuilt.yml up -d + +services: + tabby: + image: ghcr.io/eugeny/tabby-web:latest + restart: always + depends_on: + - db + ports: + - 9090:80 + environment: + - DATABASE_URL=mysql://root:123@db/tabby + - PORT=80 + - DEBUG=False + - DOCKERIZE_ARGS="-wait tcp://db:3306 -timeout 60s" + # + # OAuth Providers - uncomment and configure at least one: + # - SOCIAL_AUTH_GITHUB_KEY=your_github_client_id + # - SOCIAL_AUTH_GITHUB_SECRET=your_github_client_secret + # - SOCIAL_AUTH_GITLAB_KEY=your_gitlab_client_id + # - SOCIAL_AUTH_GITLAB_SECRET=your_gitlab_client_secret + # - SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=your_google_client_id + # - SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=your_google_client_secret + # - SOCIAL_AUTH_MICROSOFT_GRAPH_KEY=your_microsoft_client_id + # - SOCIAL_AUTH_MICROSOFT_GRAPH_SECRET=your_microsoft_client_secret + + db: + image: mariadb:10.7.1 + restart: always + environment: + MARIADB_DATABASE: tabby + MARIADB_USER: user + MARIADB_PASSWORD: 123 + MYSQL_ROOT_PASSWORD: 123 + volumes: + - db-data:/var/lib/mysql + +volumes: + db-data: