diff --git a/README.md b/README.md index 6dbf8bf..1cb7f57 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,48 @@ 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 -## Runtime Requirements +## Software Requirements -* Python 3.7+ +* 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 | ## Docker Build Requirements @@ -43,13 +78,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: 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: 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/ +```