Hosting a Node.js Discord Bot: Complete Setup Guide
discord.js makes building bots easy; deploying one that survives reboots, restarts and updates is a different skill. This is the full path from local project to a production bot on a server.
A Discord bot is just a long-running Node process - which means everything that keeps Node apps healthy in production applies here: dependency hygiene, environment variables, a process manager, logs and monitoring. This walkthrough takes a discord.js project from your machine to a server running reliably under professional bot hosting.
Project structure that scales
Keep it boring and predictable: a commands/ folder with one file per command, an events/ folder with handlers for ready, interactionCreate and message events, a config.js that reads environment variables, and a single entry point that loads them all. Bots grow from 3 commands to 40 faster than expected, and a folder-per-command structure means adding features never touches the core.
Intents and the developer portal
Before deploying, register your application, grab the token, and configure intents. Message Content is privileged: without it your bot sees empty message content for messages from other users. Enable only what you need, because over-requesting intents delays approval and raises security questions. Also create a bot user, copy its ID, and invite it with the precise OAuth scopes (bot, applications.commands) and permissions your features require.
Server setup
- Install Node.js LTS from your distribution or a version manager, and pin the version in
package.json. - Create a dedicated system user for the bot; never run it as root.
- Copy the project with
git cloneor SFTP and runnpm cifor reproducible installs. - Put secrets in
.envor PM2 environment config, and add.envto.gitignore. - Open outbound-only networking: a bot needs no inbound ports unless you expose an API.
Run it under PM2
Start with pm2 start index.js --name mybot --max-memory-restart 300M. The memory restart option handles the slow leaks that long-running Node processes accumulate. Then pm2 save and pm2 startup to persist the process list across reboots. Use pm2 logs mybot for day-to-day debugging and set up log rotation, because unrotated logs are the fastest way to fill a small disk.
Logging that helps at 3 AM
Replace console.log with a structured logger (pino or winston) that writes JSON lines with timestamps and levels. Log gateway reconnects, command errors and unhandled promise rejections - the three things that explain most "bot stopped responding" incidents. Send errors to Discord or an email channel so you are not discovering them from users.
Optional: HTTP endpoints for health checks
A tiny Express or Fastify server on localhost that returns bot status and latency lets an external monitor confirm the gateway is healthy, not just that the process exists. Point an uptime service at it through a reverse proxy if you want the monitor to reach it, or keep it internal and run the check from a cron job that posts to Discord.
Updating safely
Test locally, commit, pull on the server, run your tests, then pm2 reload mybot for a graceful restart. Keep a rollback one command away: pm2 save before risky changes so you can return to the previous state quickly. For larger bots, add a staging instance and switch commands on gradually.
Set up once and your bot behaves like a proper service: restarts itself, survives reboots, logs its failures, and tells you when something breaks.
Ready to launch on NextyHost?
Node-ready VPS with root access, SSH keys and PM2 support out of the box.

