Skip to content

Discord Bot Deployment

This guide covers deploying the Lantern Discord bot to production using Railway.

Purpose

The Discord bot is a 24/7 feature request submission system for the Lantern community. It:

  • Accepts /feature and /bug slash commands from Discord users
  • Automatically creates GitHub issues in our private repository
  • Detects duplicates using keyword matching
  • Provides real-time status updates via /mystatus
  • Connects to Firestore to track submission metadata

Why Railway?

  • Simple Node.js deployment with automatic scaling
  • Cost-effective for 24/7 uptime (~$5/month)
  • Built-in logging and monitoring
  • Auto-deploys from GitHub on push (no manual steps)
  • Perfect for long-running background services
  • Reliable restart policies ensure bot stays online

Alternative considered: AWS Lambda, Heroku, DigitalOcean. Railway wins on simplicity + cost for a stateless Node process.

Quick Start

The Discord bot is deployed on Railway and automatically starts when the service runs. Configuration is handled via environment variables.

Deployment Architecture

  • Platform: Railway (Starter plan)
  • Runtime: Node.js 22+
  • Build: Railpack (automatic detection)
  • Entry point: discord-bot/bot.js
  • Package manager: npm with workspaces support
  • Uptime: 24/7 (managed by Railway restart policy)
  • Scaling: Single replica during pilot (auto-scale on Pro plan)

Prerequisites

  1. Railway account with a project created
  2. GitHub repository connected to Railway (for automatic deploys)
  3. Environment variables configured in Railway dashboard

Configuration

Environment Variables (Railway Dashboard)

Set these in your Railway service settings under Variables:

DISCORD_TOKEN=<your-discord-bot-token>
DISCORD_GUILD_ID=<your-server-id>
GITHUB_TOKEN=<your-github-token>
GITHUB_REPO=cattreedev/lantern_app
FIREBASE_SERVICE_ACCOUNT_KEY=<your-firebase-json-as-string>

Firebase Configuration (IMPORTANT):

  • FIREBASE_SERVICE_ACCOUNT_KEY should be the entire service account JSON as a single string
  • Example format: {"type":"service_account","project_id":"lantern-app-dev",...}
  • The bot will parse this automatically in discord-bot/bot.js

Discord Bot Setup

  1. Create Discord Application at discord.com/developers/applications
  2. Enable OAuth2 and get token under "Bot" section
  3. Configure permissions:
    • Send Messages
    • Embed Links
    • Read Message History
    • Use Slash Commands
  4. Add bot to your server using the OAuth2 URL generator

GitHub Token

Generate a Personal Access Token at github.com/settings/tokens with:

  • repo (Full control of private repositories)
  • workflow (Update GitHub Action workflows)

Railway Deployment Process

Initial Setup

  1. Connect your GitHub repository to Railway
  2. Railway auto-detects the Node.js project via package.json
  3. Railpack builds the project automatically

Build Steps

The build process follows this sequence:

  1. Install phase: npm ci installs root dependencies, then postinstall hook installs discord-bot dependencies

    json
    "postinstall": "npm ci --prefix discord-bot"
  2. Build phase: Quick validation (no actual build needed)

    json
    "build": "echo 'Build step complete'"
  3. Deploy phase: Starts the bot

    json
    "start": "node discord-bot/bot.js"

Troubleshooting Build Failures

Problem: Build stuck in "building" state
Solution: Check Railway settings:

  • Go to SettingsBuild section
  • Ensure Custom Build Command field is empty (should use package.json instead)
  • Clear the Build Cache if you changed package.json
  • Click Redeploy

Problem: "Cannot find package 'discord.js'"
Solution:

  • Ensure postinstall script runs: npm ci --prefix discord-bot
  • Clear build cache and redeploy
  • Verify discord-bot/package-lock.json is committed to git

Problem: Discord bot crashes on start
Solution:

  • Check Railway logs for error messages
  • Verify all required environment variables are set
  • Test locally: cd discord-bot && npm install && npm start

Monitoring & Logs

View Logs in Railway

  1. Go to your project dashboard
  2. Select the service
  3. Click Deployments → Select active deployment → Logs

Common Log Messages

📋 /feature command received from username
📋 /bug command received from username
✅ Feature request submitted (Issue #123)
❌ Error creating GitHub issue: ...

Environment Detection

The bot automatically uses:

  • Dev environment: When VITE_APP_ENV=development or on dev.ourlantern.app
  • Production environment: When VITE_APP_ENV=production or on ourlantern.app

This determines which Firestore database and GitHub repository it connects to.

Local Testing

Before deploying, test locally:

bash
cd discord-bot
npm install
cp .env.example .env.local
# Edit .env.local with your tokens
npm start

See Discord Bot README for full local setup.

Railway Engineering Considerations

Resource Allocation

Current configuration (pilot phase):

  • CPU: 2 vCPU (Railway Starter plan limit)
  • Memory: 1 GB (Railway Starter plan limit)
  • Replicas: 1 (single instance)

These are sufficient for feature request processing. Upgrade to Pro plan for multi-region replicas if needed.

Uptime & Reliability

Restart Policy:

  • Set to "On Failure" (default) — restarts bot if it crashes
  • Max restart retries: 10 (prevent infinite restart loops)
  • Average restart time: 30–60 seconds

Monitoring uptime:

  • Check Railway dashboard → Deployments → active deployment
  • Set up Discord status channel to post bot health checks
  • Consider adding healthcheck endpoint to bot (future enhancement)

Performance Considerations

Discord Bot Behavior:

  • Event-driven (reacts to slash commands, doesn't poll)
  • Low baseline resource usage (~50MB RAM, <5% CPU at rest)
  • Spikes during GitHub API calls (Issue creation) or Firebase writes (typically <1 second)
  • Handles ~100 concurrent Discord connections per shard (bot uses 1 shard during pilot)

Scaling strategy:

  • 0–50 submissions/day: Current setup is fine
  • 50–500 submissions/day: Monitor CPU/memory; may need upgrade
  • 500+/day: Consider Cloud Functions for async processing + Firestore for queuing

Networking & DNS

Railway automatically handles:

  • Public IP management (internal to Railway network)
  • Discord API connectivity (outbound to gateway.discord.gg)
  • GitHub API connectivity (outbound to api.github.com)
  • Firebase connectivity (outbound to firestore.googleapis.com)

No special networking config needed during pilot.

Cost Optimization

Railway Starter Plan breakdown:

  • Base: $5/month (equivalent to ~230 hours/month overage)
  • Included: 500 hours/month free
  • Actual usage: ~730 hours/month (24/7 uptime) → ~230 overage hours → ~$5/month

Future optimizations:

  • If you need multi-region or higher resource limits → upgrade to Pro ($20/month)
  • If submission volume becomes very high → migrate bot processing to Firebase Cloud Functions + Pub/Sub (pay-per-use model)
  • Consider "Serverless" option if bot can tolerate cold starts (~5–10 seconds)

Logs & Debugging

Log retention:

  • Railway keeps logs for 24 hours free tier; 30 days with paid backup
  • Logs auto-rotate and are searchable in dashboard

Debugging checklist:

  • Check recent deployments for failed builds
  • Review last 50 log lines in active deployment
  • Verify all environment variables are set
  • Test Discord bot locally to reproduce issues

See Troubleshooting section above for common issues.

Disaster Recovery

If bot goes offline:

  1. Check Railway dashboard for crash/restart logs
  2. Verify environment variables still exist (Railway doesn't delete on crash)
  3. Click Redeploy to force restart
  4. If still failing, check local test: cd discord-bot && npm start

If GitHub token expires:

  • Generate new token at github.com/settings/tokens
  • Update GITHUB_TOKEN in Railway Variables
  • Restart bot (auto-deploy or manual redeploy)

Data recovery:

  • All submissions are stored in Firestore (persistent)
  • Bot can be restarted without data loss
  • GitHub issues are permanent (even if bot crashes after creation)

See Also

Built with VitePress