Environment File Setup
JOIP uses environment variables for configuration. All variables are loaded from a.env file in the project root.
1
Create Environment File
2
Edit Configuration
Open
.env in your editor and configure the required variables below.3
Restart Server
.env require a server restart.Core Configuration
Database Connection
string
required
PostgreSQL connection string in URI format.Examples:
- Local:
postgresql://postgres:password@localhost:5432/joip_dev - Supabase:
postgresql://postgres:[password]@db.[project].supabase.co:5432/postgres - Neon:
postgresql://[user]:[password]@[host].neon.tech/[database]
Session Management
string
required
Secret key for signing session cookies. Must be a strong random string.Generate securely:
Application Settings
string
default:"development"
Application environment mode.Effects:
development: Enables Vite HMR, verbose logging, local authproduction: Serves fromdist/, minified assets, Replit OIDC
number
default:5000
Server port number.
Replit automatically proxies this port. The default is always 5000.
number
Optional override for internal localhost callbacks/proxy calls.Defaults to
PORT when omitted. Only needed for special reverse proxy setups.string
default:"./uploads"
Directory for temporary file uploads.
Deprecated: JOIP now uses Supabase Storage exclusively. This setting is retained for backward compatibility but not actively used.
Reddit Integration
Required for Reddit-based sessions, Gaslighter, and Scroller features.string
required
Reddit application client ID.How to get:
- Go to https://www.reddit.com/prefs/apps
- Click “Create App” or “Create Another App”
- Choose “script” type
- The client ID is shown under the app name
string
required
Reddit application client secret.Found in the same location as the client ID.
AI Services
Caption Generation
Choose one or both providers for AI caption generation:string
OpenRouter API key for AI caption generation (recommended).Features:
- Access to Gemini 2.5 Pro and Flash models
- Automatic fallback between models
- Used for contextual/narrative captions in Manual Editor
- Used for Smart Captions with themed prompts
- Sign up at https://openrouter.ai
- Navigate to Settings → API Keys
- Create a new key
- Manual Editor:
google/gemini-2.5-pro(fallback:gemini-2.5-flash-lite) - Smart Captions:
gemini-2.5-flash-lite
string
OpenAI API key as alternative to OpenRouter.The system will use OpenRouter if available, falling back to OpenAI.
AI Image Services
string
xAI API key for AI Undress feature (primary provider).Get your key:
- Visit https://console.x.ai/
- Generate an API key
- Uses
grok-imagine-image-proby default - Override with
XAI_UNDRESS_MODEL
string
default:"grok-imagine-image-pro"
Optional xAI model override for AI Undress.
string
Freepik API key for AI Undress feature (fallback provider).Get your key:
- Visit https://www.freepik.com/developers/dashboard
- Create an API key
- Uses Seedream 4.5 Edit
- Automatically used when xAI fails or is unavailable
string
default:"xai"
Select primary provider for AI Undress.Options:
xai: Use xAI as primary, Freepik as fallbackfreepik: Use Freepik as primary, xAI as fallback
string
Replicate API token (dormant/legacy provider).
This provider is dormant and kept for backward compatibility. The system uses xAI and Freepik.
Cloud Storage
Required for manual sessions, Media Vault, and file uploads.string
required
string
required
Supabase anonymous (public) key.Found in the same location as the project URL under “Project API keys” → “anon public”.
This key is safe to use in client-side code. It respects Row Level Security (RLS) policies.
string
required
Supabase service role (admin) key.Found under “Project API keys” → “service_role”.
Storage Buckets
The application automatically creates these buckets:- user-media: User uploads and manual session media
- Path structure:
users/{userId}/manual-sessions/{sessionId}/
- Path structure:
- general: Community content and shared media
External Services
Imgchest Integration
string
Imgchest API key for importing existing galleries.Required only for the “Import JOIP” feature to import from Imgchest.
Replit Deployment
These variables are automatically set by Replit. Only configure manually for custom deployments.string
Replit domain for the deployed app.Effects:
- When set: Enables Replit OIDC authentication
- When unset: Uses local development auth strategy
string
Unique Replit project identifier.Used for Replit OIDC configuration.
string
default:"https://identity.util.repl.co"
OIDC issuer URL for Replit authentication.
string
Development domain (auto-populated by Replit).
string
Replit database URL (auto-populated).
Payment Integrations
Telegram Payments
string
Telegram bot token for Telegram Stars payments.Required together with
TELEGRAM_WEBHOOK_SECRET to enable Telegram payment flow.string
Telegram webhook secret for payment verification.
string
default:"OfficialJoipBot"
Telegram bot username.Defaults to “OfficialJoipBot” when unset.
string
Telegram channel ID for membership features.Only needed for channel invite/membership features.
Thirdweb Checkout
string
Thirdweb client ID for crypto/card payments.Required together with webhook secret to enable Thirdweb checkout flow.
string
Thirdweb webhook secret for payment verification.
string
Ethereum wallet address for receiving payments.
Database Tuning
Optional connection pool and performance settings.These are optional. The application uses sensible defaults optimized for most deployments.
Logging Configuration
string
default:"info"
Application logging verbosity.Options:
error: Only errorswarn: Warnings and errorsinfo: General information (recommended)debug: Detailed debugging information
Complete Example
Validation
The application validates environment configuration on startup viaserver/environmentConfig.ts.
Startup checks:
- Required variables are present
- Database connection succeeds
- Connection pool initializes
- Supabase connectivity (if configured)
Diagnostics
Check Storage Status
STORAGE_CONFIG_ERROR: Missing environment variablesSTORAGE_UNREACHABLE: Cannot connect to SupabaseSTORAGE_PREFLIGHT_FAILED: Bucket test upload failed
Check Database Connection
Verify the database is accessible:Test API Keys
Test Reddit API
Test Reddit API
Create a Reddit session and verify media loads. Check server logs for:
Test AI Caption Generation
Test AI Caption Generation
Try generating a caption in Smart Captions. Look for:
Test Supabase Storage
Test Supabase Storage
Upload an image in Media Vault. Verify:
Security Best Practices
1
Secret Management
- Never commit
.envfiles to Git - Use different secrets for dev/staging/production
- Rotate API keys regularly (quarterly recommended)
- Store production secrets in secure vaults (Replit Secrets, AWS Secrets Manager)
2
API Key Security
- Never expose service keys client-side
- Use
SUPABASE_ANON_KEYfor client operations only - Keep
SUPABASE_SERVICE_KEYserver-side only - Monitor API usage for anomalies
3
Database Security
- Use SSL for production database connections
- Implement IP whitelisting where possible
- Use strong passwords (20+ characters)
- Enable connection pooling with max limits
4
Session Security
- Use strong
SESSION_SECRET(32+ bytes) - Enable secure cookies in production (HTTPS only)
- Set appropriate session timeouts
- Implement CSRF protection
Troubleshooting
Storage Errors in Manual Sessions
Storage Errors in Manual Sessions
Symptom: Manual session creation returns 503 with error codesSolutions:
- Verify all three Supabase variables are set
- Check if Supabase project is paused (resume it)
- Test with
/api/storage/status - Review error code:
STORAGE_CONFIG_ERROR: Add missing env varsSTORAGE_UNREACHABLE: Check URL and networkSTORAGE_PREFLIGHT_FAILED: Verify bucket permissions
AI Features Not Working
AI Features Not Working
Symptom: Caption generation fails silentlySolutions:
- Check API keys are valid (not expired)
- Verify sufficient credits/quota on provider
- Check server logs for specific errors
- Test fallback: if OpenRouter fails, try OpenAI
Reddit API Rate Limiting
Reddit API Rate Limiting
Symptom: 429 errors when fetching Reddit contentSolutions:
- Built-in retry logic should handle this automatically
- Reduce concurrent requests
- Check if Reddit credentials are valid
- Wait for rate limit to reset (typically 1 minute)
Database Connection Issues
Database Connection Issues
Symptom: Cannot connect to databaseSolutions:
- Verify
DATABASE_URLformat is correct - Check database is running and accessible
- For cloud databases: verify IP whitelist
- Test connection:
psql "$DATABASE_URL" - Check connection pool settings if hitting limits
Next Steps
Quick Start Guide
Create your first session with AI captions
API Reference
Explore all available API endpoints