Discord Bot Deployment Guide (2025)

Dockerize your bot and deploy to Railway/Render/Fly.io with reliability and logs

← Back to Blog

Dockerfile (Node 18+)

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
ENV NODE_ENV=production
CMD ["node", "server.js"]

Railway/Render/Fly.io Basics

  • Use persistent services (not serverless request handlers)
  • Set DISCORD_TOKEN and other secrets in dashboard
  • Enable health checks and review logs for restarts/backoffs

Why Not Vercel/Netlify?

Serverless platforms excel at stateless HTTP but terminate idle processes. Discord bots require a long-lived WebSocket connection to the Gateway, which serverless does not provide. Use a persistent runtime instead.

Zero-Downtime Restarts

Use a process manager (e.g., pm2) or platform restarts with backoff. Handle shard/resume events in Discord.js for resilience.

Security and Secrets

Never bake tokens into images. Store secrets in platform secret managers and rotate regularly. Scope bot permissions minimally when generating invites.

Serverless Suitability (Vercel/Netlify)

Classic gateway bots require a long‑lived WebSocket to Discord. Serverless functions do not sustain such connections; they are request/response and short‑lived. However, you can still implement Interactions‑only bots by handling slash commands via an HTTP Interactions Endpoint URL. Recent community templates demonstrate acknowledging within 3 seconds (deferring) and completing within 15 minutes—consistent with Discord interaction rules.

  • Works well: Slash commands, buttons/selects/modals via HTTP interactions.
  • Not suitable: Presence events, message create streams, rich gateway‑driven features.
  • Alternative: Hybrid—run gateway shards on VPS/Cloud; route interactions to serverless APIs for bursty compute.

Serverless Checklist

  • Set Interactions Endpoint URL to your /api route.
  • Always reply or defer within 3s; finish within 15 minutes.
  • Store secrets in platform env vars; never in code.
  • Add simple rate limiting and idempotency to prevent duplicate executions on retries.