Skip to content

Configuration

poiromaniax edited this page Sep 11, 2025 · 2 revisions

This page covers all environment variable configuration needed for your TableSlayer self-hosted deployment. Proper configuration is critical for all features to work correctly.

Environment File Setup

Create Production Environment File

Create the production environment file:

# Navigate to deployment directory
cd apps/web/deployment

# Create production environment file
cp .env.example .env.production

# Edit the production file
nano .env.production

Complete Environment Configuration

Copy this template into your .env.production file and replace all placeholder values:

# =================================================================
# DATABASE CONFIGURATION
# =================================================================
# Get these from: turso db show YOUR_DATABASE_NAME
# and: turso db tokens create YOUR_DATABASE_NAME

TURSO_API_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
TURSO_APP_DB_AUTH_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
TURSO_APP_DB_URL=libsql://your-database-name.aws-eu-west-1.turso.io

# Leave these empty for single database setup
TURSO_GS_PARENT_DB_URL=
TURSO_GS_PARENT_DB_AUTH_TOKEN=

# =================================================================
# EMAIL CONFIGURATION
# =================================================================
# Get from: resend.com → API Keys

RESEND_TOKEN=re_123456789_abcdefghijklmnopqrstuvwxyz
DEV_EMAIL=admin@yourdomain.com

# =================================================================
# CLOUDFLARE R2 STORAGE CONFIGURATION  
# =================================================================
# Get these from: Cloudflare Dashboard → R2 → Manage R2 API tokens

CLOUDFLARE_ACCOUNT_ID=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
CLOUDFLARE_R2_ACCESS_KEY=your_r2_access_key_id
CLOUDFLARE_R2_SECRET_KEY=your_r2_secret_access_key
CLOUDFLARE_R2_BUCKET_NAME=your-tableslayer-files

# Your custom R2 domain (setup in R2 bucket settings)
CLOUDFLARE_R2_PUBLIC_URL=https://files.yourdomain.com
PUBLIC_CLOUDFLARE_R2_URL=https://files.yourdomain.com

# =================================================================
# APPLICATION CONFIGURATION
# =================================================================

# Your primary domain
BASE_URL=https://yourdomain.com

# File upload size limit
BODY_SIZE_LIMIT=20M

# =================================================================
# GOOGLE OAUTH CONFIGURATION
# =================================================================
# Get from: Google Cloud Console → APIs & Services → Credentials

GOOGLE_CLIENT_ID=123456789012-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-AbCdEfGhIjKlMnOpQrStUvWxYz

# =================================================================
# PARTYKIT REAL-TIME CONFIGURATION
# =================================================================
# Get from: partykit deploy output

PUBLIC_PARTYKIT_HOST=your-project-name.your-username.partykit.dev

# =================================================================
# OPTIONAL: STRIPE PAYMENT CONFIGURATION
# =================================================================
# Leave dummy values if not using payments

STRIPE_API_KEY=sk_test_dummy_key_for_build_purposes_only
STRIPE_WEBHOOK_KEY=whsec_dummy_webhook_key
STRIPE_PRICE_ID_LIFETIME=price_dummy_lifetime_id
STRIPE_PRICE_ID_MONTHLY=price_dummy_monthly_id  
STRIPE_PRICE_ID_YEARLY=price_dummy_yearly_id

# =================================================================
# OPTIONAL: MONITORING AND ANALYTICS
# =================================================================

# Sentry error tracking (optional)
SENTRY_DSN=
SENTRY_AUTH_TOKEN=

# =================================================================
# NODE.JS CONFIGURATION
# =================================================================

# Production environment
NODE_ENV=production

# Memory optimization (already set in Docker)
NODE_OPTIONS=--max-old-space-size=4096

Configuration Details

Database Configuration

Required Values:

TURSO_API_TOKEN=         # From: turso auth login
TURSO_APP_DB_AUTH_TOKEN= # From: turso db tokens create YOUR_DB  
TURSO_APP_DB_URL=        # From: turso db show YOUR_DB

How to Get These:

# Get API token (login token)
turso auth login
turso auth token

# Get database URL and create auth token
turso db show tableslayer-production
turso db tokens create tableslayer-production

R2 Storage Configuration

Required Values:

CLOUDFLARE_ACCOUNT_ID=      # From R2 dashboard sidebar
CLOUDFLARE_R2_ACCESS_KEY=   # From API tokens
CLOUDFLARE_R2_SECRET_KEY=   # From API tokens  
CLOUDFLARE_R2_BUCKET_NAME=  # Your bucket name
CLOUDFLARE_R2_PUBLIC_URL=   # Your custom domain

Finding Account ID:

  1. Go to Cloudflare Dashboard
  2. Select your domain
  3. Look in the right sidebar for "Account ID"

PartyKit Configuration

Required Value:

PUBLIC_PARTYKIT_HOST=your-project.your-username.partykit.dev

How to Get This:

cd apps/web
partykit deploy

# The deploy command outputs the URL
# Example: "Deployed to your-project.your-username.partykit.dev"

Google OAuth Configuration

Required Values:

GOOGLE_CLIENT_ID=     # From Google Cloud Console  
GOOGLE_CLIENT_SECRET= # From Google Cloud Console

Finding These Values:

  1. Go to Google Cloud Console
  2. Navigate to APIs & Services → Credentials
  3. Click on your OAuth 2.0 Client ID
  4. Copy Client ID and Client Secret

Environment Security

File Permissions

Secure your environment file:

# Set restrictive permissions
chmod 600 .env.production

# Verify permissions
ls -la .env.production
# Should show: -rw------- (600)

Backup Configuration

# Create encrypted backup of environment file
gpg -c .env.production
# Creates: .env.production.gpg

# Store backup securely and delete original if needed

Environment Validation

Create a validation script to check configuration:

File: scripts/validate-env.js

#!/usr/bin/env node

const fs = require('fs');
const path = require('path');

const envFile = path.join(__dirname, '../apps/web/deployment/.env.production');

if (!fs.existsSync(envFile)) {
  console.error('❌ .env.production file not found');
  process.exit(1);
}

const envContent = fs.readFileSync(envFile, 'utf8');

const requiredVars = [
  'TURSO_API_TOKEN',
  'TURSO_APP_DB_AUTH_TOKEN', 
  'TURSO_APP_DB_URL',
  'RESEND_TOKEN',
  'CLOUDFLARE_ACCOUNT_ID',
  'CLOUDFLARE_R2_ACCESS_KEY',
  'CLOUDFLARE_R2_SECRET_KEY',
  'CLOUDFLARE_R2_BUCKET_NAME',
  'CLOUDFLARE_R2_PUBLIC_URL',
  'BASE_URL',
  'GOOGLE_CLIENT_ID',
  'GOOGLE_CLIENT_SECRET',
  'PUBLIC_PARTYKIT_HOST'
];

const missingVars = [];
const emptyVars = [];

requiredVars.forEach(varName => {
  const regex = new RegExp(`^${varName}=(.*)$`, 'm');
  const match = envContent.match(regex);
  
  if (!match) {
    missingVars.push(varName);
  } else if (!match[1] || match[1].trim() === '' || match[1].includes('your_') || match[1].includes('yourdomain.com')) {
    emptyVars.push(varName);
  }
});

console.log('🔍 Environment Validation Results');
console.log('================================');

if (missingVars.length === 0 && emptyVars.length === 0) {
  console.log('✅ All required environment variables are configured');
} else {
  if (missingVars.length > 0) {
    console.log('❌ Missing variables:');
    missingVars.forEach(v => console.log(`   - ${v}`));
  }
  
  if (emptyVars.length > 0) {
    console.log('⚠️  Empty or placeholder variables:');
    emptyVars.forEach(v => console.log(`   - ${v}`));
  }
  
  console.log('\n💡 Please update your .env.production file before deployment');
  process.exit(1);
}

Run validation:

node scripts/validate-env.js

Domain-Specific Configuration

Development vs Production

For development, create .env.development:

# Development overrides
BASE_URL=http://localhost:5174
PUBLIC_PARTYKIT_HOST=localhost:1999
CLOUDFLARE_R2_PUBLIC_URL=http://localhost:3000/dev-files

# Keep production values for external services
TURSO_APP_DB_URL=libsql://dev-database.turso.io
# ... other production service configs

Multiple Environment Setup

For staging/production separation:

Staging (.env.staging):

BASE_URL=https://staging.yourdomain.com
TURSO_APP_DB_URL=libsql://tableslayer-staging.turso.io
# ... staging-specific configs

Production (.env.production):

BASE_URL=https://yourdomain.com
TURSO_APP_DB_URL=libsql://tableslayer-production.turso.io
# ... production configs

Common Configuration Issues

Database Connection Fails

Symptoms: Can't connect to Turso database Solutions:

  • Verify database URL format: libsql://name.region.turso.io
  • Check auth token hasn't expired: turso auth token
  • Ensure database exists: turso db list

File Upload Errors

Symptoms: Images won't upload or display Solutions:

  • Check R2 credentials are correct
  • Verify bucket name matches exactly
  • Ensure custom domain DNS is propagated
  • Check CORS policy allows your domain

Google OAuth Fails

Symptoms: "OAuth error" during login Solutions:

  • Verify redirect URIs match exactly (including https://)
  • Check Google+ API is enabled
  • Ensure client ID/secret are correct

Real-time Features Don't Work

Symptoms: Changes don't sync between users Solutions:

  • Verify PartyKit host URL is accessible
  • Check PartyKit deployment succeeded
  • Ensure WebSocket connections aren't blocked

Email Not Sending

Symptoms: No signup/password reset emails Solutions:

  • Check Resend API key is valid
  • Verify domain is verified in Resend
  • Check DEV_EMAIL is set to admin email

Testing Configuration

Connection Tests

Test each service connection:

# Test Turso connection
turso db shell your-database "SELECT 1 as test;"

# Test R2 connection  
curl -I https://files.yourdomain.com

# Test PartyKit connection
curl https://your-project.your-username.partykit.dev

# Test Resend (replace API_KEY)
curl -X POST https://api.resend.com/emails \
  -H "Authorization: Bearer YOUR_RESEND_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"from":"test@yourdomain.com","to":"admin@yourdomain.com","subject":"Test","text":"Test"}'

Application Health Check

After deployment, verify health:

# Check application health endpoint
curl https://yourdomain.com/healthcheck

# Should return: {"status": "healthy"}

Next Steps

Once configuration is complete and validated, proceed to Deployment to build and deploy your TableSlayer instance.


🔒 Security Reminder: Never commit .env.production to version control. Add it to your .gitignore file.