How to Host a Discord Bot on a VPS: Node.js & Python

Your Discord bot works perfectly on your laptop.
Then you close the terminal.
Or your laptop goes to sleep.
Or you reboot.
Suddenly, your bot disappears from Discord.
That is where a VPS (Virtual Private Server) becomes useful.
Instead of running your Discord bot from your personal computer, you can deploy it to a remote Linux server where it can continue running independently of your laptop. A process manager such as PM2 or a Linux service manager such as systemd can also restart the application when it fails.
This guide explains how to host a Discord bot on a VPS using Node.js or Python, including:
- Deploying your bot to a Linux VPS
- Installing Node.js or Python dependencies
- Securing Discord credentials with environment variables
- Running a Node.js bot with PM2
- Running a Python bot with systemd
- Configuring automatic restarts
- Starting your bot after a VPS reboot
- Monitoring logs
- Testing that your bot remains online when your laptop is offline
The core idea is simple:
Your laptop can sleep. Your Discord bot doesn’t have to.
What You Need to Host a Discord Bot on a VPS
Before starting, you’ll need:
- A Discord application and bot
- Your bot’s source code
- A Linux VPS
- SSH access to the VPS
- Node.js for a JavaScript or TypeScript bot, or Python for a Python bot
- Your Discord bot token
- A process or service manager such as PM2 or systemd
Discord bots are applications that interact with Discord through the Discord API. Depending on the architecture, an application can communicate through Discord’s persistent Gateway WebSocket, HTTP API, or HTTP-based interactions. Discord notes that most bots use one or both depending on their use case.
This distinction matters because not every Discord application needs a permanently connected Gateway process. A bot listening for real-time server events generally needs a Gateway connection, while an application designed around HTTP interactions can receive requests through a public endpoint instead.
Why Host a Discord Bot on a VPS?
Running your bot locally is perfectly reasonable during development.
For a production deployment, however, your personal computer becomes an unnecessary dependency.
Running locally
Your laptop
↓
Discord Bot
↓
DiscordIf your computer shuts down or the bot process stops, the bot goes offline.
Running on a VPS
Your laptop
↓
SSH
↓
VPS
↓
Discord Bot
↓
DiscordYour laptop is now the development and management device rather than the machine responsible for keeping the bot running.
A VPS provides a persistent server environment where you control the operating system, application runtime and processes.

Step 1: Create Your Discord Bot
If you haven’t created your bot yet, start in the Discord Developer Portal.
Discord’s current setup process involves creating an application, adding a bot user, configuring the required permissions and intents, and installing the application into a server using the appropriate OAuth2 configuration.
Your bot will have a token that your application uses to authenticate with Discord.
Important: Protect Your Bot Token
Your Discord bot token is a credential.
Never hardcode it into publicly accessible source code or commit it to GitHub.
Instead, provide it to the application through an environment variable.
For example:
DISCORD_TOKEN=your_token_hereWe’ll configure this properly later in the guide.
If a token is accidentally exposed, treat it as compromised and rotate it through the Discord Developer Portal.
Step 2: Choose a VPS
A Discord bot doesn’t automatically require a large server.
The appropriate VPS size depends on what your application actually does.
A simple command bot and a bot that processes images, runs AI workloads, connects to a database or handles significant background jobs can have very different resource requirements.
Instead of choosing a VPS based only on the fact that you’re hosting a Discord bot, consider:
- CPU requirements
- RAM usage
- Storage requirements
- Database requirements
- Network traffic
- Number and complexity of background tasks
For many small projects, the VPS can also host other supporting services alongside the bot, provided the combined workload fits within the available resources.
Step 3: Connect to Your VPS
Once your VPS is deployed, connect through SSH.
On Linux or macOS:
ssh username@your_server_ipOn Windows, you can use PowerShell or Windows Terminal with the built-in SSH client.
After connecting, update the system packages.
On a Debian or Ubuntu-based server:
sudo apt update && sudo apt upgrade -yThe exact package-management commands can differ depending on your Linux distribution.
Step 4: Deploy a Node.js Discord Bot
If your Discord bot uses Node.js, first check whether Node.js and npm are installed:
node --version
npm --versionMove into your project directory:
cd ~/discord-botInstall your dependencies.
If your project contains a package-lock.json generated for your project, npm ci is appropriate for a clean deployment. npm documents npm ci specifically for automated and deployment environments; it requires an existing lockfile and performs a clean dependency installation without modifying the package lock.
npm ciIf your project doesn’t have a compatible lockfile, use:
npm installThen test the application:
node index.jsReplace index.js with your actual entry file.
If the bot connects successfully, you should see it become available in Discord.
Stop the process with:
Ctrl + CWe’ll use PM2 to run it persistently in the next section.
Step 5: Deploy a Python Discord Bot
For Python, check the installed version:
python3 --versionCreate your project directory if necessary:
mkdir -p ~/discord-bot
cd ~/discord-botCreate a Python virtual environment:
python3 -m venv venvActivate it:
source venv/bin/activateInstall your dependencies:
pip install -r requirements.txtThen test the bot:
python3 bot.pyReplace bot.py with your application’s actual entry point.
If the bot connects successfully, stop the process with:
Ctrl + CThe virtual environment keeps your bot’s Python packages isolated from system-level Python packages.
Step 6: Configure Environment Variables Securely
Your Discord token should not be embedded directly in your source code.
Avoid:
const token = "YOUR_DISCORD_TOKEN";Instead, read the value from the environment.
Node.js
const token = process.env.DISCORD_TOKEN;You can provide the variable to the process with:
export DISCORD_TOKEN="your_token_here"However, remember that shell exports are tied to that shell environment. For a production process manager, configure the environment through your process or service configuration.
Python
Python can read the same environment variable using the standard library:
import os
token = os.getenv("DISCORD_TOKEN")If your application uses a .env file during development, you can use python-dotenv:
from dotenv import load_dotenv
import os
load_dotenv()
token = os.getenv("DISCORD_TOKEN")A .env file should not be committed to your public repository.
Add it to .gitignore:
.envKeep Secrets Out of Your Repository
The principle is:
Application code
↓
Environment variable
↓
Secret valueThis keeps credentials separate from your source code.
Also avoid printing tokens to application logs.
Step 7: Keep Your Node.js Discord Bot Running with PM2
Running:
node index.jsis useful for testing, but it ties the process to your current session.
For a persistent Node.js deployment, PM2 provides process management, including background execution, monitoring and automatic restarts.
Install PM2:
npm install pm2 -gThen start your bot:
pm2 start index.js --name discord-botCheck the process:
pm2 statusView logs:
pm2 logs discord-botRestart the bot:
pm2 restart discord-botStop it:
pm2 stop discord-botPM2 automatically manages the application as a background process and can restart it when the application exits unexpectedly.
Step 8: Configure PM2 to Start the Bot After a VPS Reboot
Starting your bot with PM2 isn’t enough if you want it to return automatically after a server reboot.
PM2 provides a startup hook for this purpose.
First generate the startup configuration:
pm2 startupPM2 will print a command that must be executed with the required privileges. Copy and run the command it provides.
PM2’s documentation specifically notes that pm2 startup generates the startup configuration, while pm2 save stores the process list that the startup hook will restore after a reboot.
Now start your bot if you haven’t already:
pm2 start index.js --name discord-botThen save the active process list:
pm2 saveYou can verify the saved process list with:
pm2 statusThe important workflow is:
pm2 startup
↓
Run the command PM2 provides
↓
pm2 start discord-bot
↓
pm2 save
↓
Reboot
↓
PM2 restores the saved processPM2 stores the saved process list so it can resurrect those processes after a machine restart.

Step 9: Run a Python Discord Bot with systemd
For Python on Linux, systemd provides a native way to manage a long-running service.
Before creating the service, make sure the bot will run as a non-root user.
Security warning
Do not run your Discord bot as root unless you have a specific reason and understand the security implications.
A dedicated unprivileged user such as botuser is preferable.
For example:
sudo adduser botuserYou can then place the application under that user’s home directory:
/home/botuser/discord-botMake sure the user has ownership of the application files.
Now create the systemd unit:
sudo nano /etc/systemd/system/discord-bot.serviceUse a configuration similar to:
[Unit]
Description=Discord Bot
After=network.target
[Service]
User=botuser
WorkingDirectory=/home/botuser/discord-bot
ExecStart=/home/botuser/discord-bot/venv/bin/python bot.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetWhat these settings do
User=botuser
Runs the bot with the permissions of the specified unprivileged account rather than root.
WorkingDirectory=
Sets the application’s working directory.
ExecStart=
Uses the Python interpreter inside the virtual environment.
Restart=on-failure
Tells systemd to restart the service when it exits unsuccessfully or is terminated abnormally.
RestartSec=5
Waits five seconds before attempting the restart.
After=network.target
Places the service after the network target in systemd’s startup ordering.
WantedBy=multi-user.target
Allows the service to be enabled for normal multi-user system startup.
systemd documents Restart=on-failure as a recommended choice for long-running services where automatic recovery is desirable.
Step 10: Enable and Start the Python Service
After saving the service file, reload systemd:
sudo systemctl daemon-reloadEnable the service so it starts during boot:
sudo systemctl enable discord-botStart it:
sudo systemctl start discord-botCheck its status:
sudo systemctl status discord-botView its logs:
journalctl -u discord-botFor live logs:
journalctl -u discord-bot -fYou can restart the service with:
sudo systemctl restart discord-botAnd stop it with:
sudo systemctl stop discord-botPM2 vs systemd: Which Should You Use?
You don’t need both for the same bot.
| Requirement | PM2 | systemd |
|---|---|---|
| Node.js applications | Excellent | Yes |
| Python applications | Supported | Excellent |
| Automatic restart | Yes | Yes |
| Start after reboot | Yes | Yes |
| Process logs | Yes | Yes |
| Environment configuration | Yes | Yes |
| Application-focused management | Strong | Moderate |
| Linux-native service manager | No | Yes |
PM2 can also run Python scripts, but its primary positioning is as a production process manager for Node.js applications.
Simple recommendation
Node.js Discord bot → PM2 is a convenient choice.
Python Discord bot → systemd is a natural Linux-native choice.
The important part isn’t which tool you select. It’s that your bot isn’t dependent on an open SSH session.
Step 11: Configure PM2 Environment Variables
For a Node.js bot, PM2 can manage environment variables through an ecosystem configuration file.
Create one:
nano ecosystem.config.jsExample:
module.exports = {
apps: [{
name: "discord-bot",
script: "./index.js",
env: {
NODE_ENV: "production"
}
}]
};Then start it:
pm2 start ecosystem.config.jsPM2 supports environment variables in ecosystem files and separate environments such as env_production.
For example:
module.exports = {
apps: [{
name: "discord-bot",
script: "./index.js",
env_production: {
NODE_ENV: "production"
}
}]
};You can then launch the production environment with:
pm2 start ecosystem.config.js --env productionIf environment variables are changed through the shell and you restart an existing PM2 process, PM2 documents using --update-env to update the application’s environment.
Security note: Avoid placing the actual Discord token directly into a configuration file that could be committed to version control. Use your server’s environment or another appropriate secret-management approach.
Step 12: Test the “Laptop Sleeps, Bot Stays Online” Setup
Now test the reason you moved the bot to a VPS in the first place.
Once your bot is running:
- Confirm that the bot is online in Discord.
- Disconnect your SSH session.
- Close your terminal.
- Put your laptop to sleep.
- Check Discord from another device or after reconnecting later.
The bot process is running on the VPS, not on your laptop.
Therefore, closing your laptop or disconnecting SSH does not itself terminate the bot process.
This is the practical difference between local development and server deployment.
Laptop
↓
SSH management
↓
VPS
↓
Bot process
↓
DiscordYour laptop is now the administration interface rather than the bot’s runtime environment.
Step 13: Test Automatic Recovery
Don’t assume that your restart configuration works.
Test it.
PM2
Restart the application:
pm2 restart discord-botThen check:
pm2 statusReview the logs:
pm2 logs discord-botsystemd
Restart the service:
sudo systemctl restart discord-botThen:
sudo systemctl status discord-botReview the logs:
journalctl -u discord-bot -fYou should also test the behavior after a VPS reboot.
sudo rebootReconnect after the server comes back and verify that your bot has started automatically.
A production deployment isn’t finished simply because the application starts once. You should verify that the recovery path works too.
Discord Gateway Intents: Why Your Bot Can Be Online but Not Responding
A bot can appear online while still failing to receive certain events.
One possible reason is Gateway intents.
Discord uses intents to determine which categories of Gateway events your application receives. Some intents are standard, while others are privileged and must be enabled in the application’s settings.
For example, MESSAGE_CONTENT, GUILD_MEMBERS and GUILD_PRESENCES involve privileged access.
If your application needs one of these intents, make sure:
- The required intent is enabled in the Discord Developer Portal.
- Your bot code requests the required intent.
- Your application’s verification/approval requirements are satisfied where applicable.
Discord states that privileged intents must be enabled in the application’s settings and that verified applications may need approval for them.
This leads to an important troubleshooting distinction:
Bot online ≠ Bot correctly configured.
If your bot connects successfully but doesn’t react to expected events, check:
- Gateway intents
- Discord permissions
- Server permissions
- Event handlers
- Bot token
- Application logs
- API responses
Slash Commands and HTTP Interactions
Modern Discord applications commonly use application commands, including slash commands.
For example:
/ping
/help
/statsDiscord interactions can be received over the Gateway or through HTTP.
If your application already maintains a Gateway connection, interactions can arrive through that connection.
Alternatively, Discord supports HTTP-based interactions through an Interactions Endpoint URL. This model does not require a persistent Gateway connection for receiving those interactions.
HTTP-based interactions require your endpoint to handle Discord’s validation requirements, including request-signature validation and the initial PING handshake.
This is why the hosting architecture should match what your Discord application actually needs.
Common Problems When Hosting a Discord Bot on a VPS
1. The Bot Goes Offline When You Close SSH
Cause
You started it directly:
node index.jsor:
python3 bot.pyand the process was tied to your session.
Solution
Use PM2, systemd or another appropriate service/process manager.
2. The Bot Starts but Immediately Crashes
Check the application logs.
PM2
pm2 logs discord-botsystemd
journalctl -u discord-botCommon causes include:
- Missing dependencies
- Invalid environment variables
- Invalid bot token
- Incorrect working directory
- Incorrect Python virtual environment
- Application exceptions
- Incorrect file permissions
3. The Bot Works Locally but Not on the VPS
Compare the runtime environments.
For Node.js:
node --versionFor Python:
python3 --versionThen verify your dependencies:
npm cior:
pip install -r requirements.txtAlso check whether all environment variables available locally have been configured on the VPS.
4. The Bot Is Online but Doesn’t Respond
Check:
- Gateway intents
- Bot permissions
- Server permissions
- Slash-command registration
- Event handlers
- Bot token
- Application logs
If you’re using Gateway-based functionality, verify that the required intents are both configured in Discord and requested by the application.
5. The Bot Keeps Restarting
Automatic restart is useful, but it doesn’t fix an application that continuously crashes.
Check your logs first.
For PM2:
pm2 logs discord-botFor systemd:
journalctl -u discord-bot -n 100Look for the original application error rather than simply restarting the process repeatedly.
Discord Bot VPS Security Checklist
Before considering your deployment complete, review these basics.
Keep credentials private
Never publish your Discord bot token.
Run the application as a non-root user
Your Discord bot generally doesn’t need root privileges.
Keep your operating system updated
Apply security updates regularly.
Use a firewall
Only expose services and ports that your application actually requires.
Don’t expose databases unnecessarily
If your bot uses PostgreSQL, MySQL or another database, don’t expose the database publicly unless your architecture requires it.
Protect your source repository
Make sure .env files and other credential-containing files aren’t committed.
Monitor application logs
Logs provide visibility when your bot crashes or behaves unexpectedly.
Back up important data
Keep your source code in version control and establish an appropriate backup strategy for persistent application data.
How Much VPS RAM and CPU Does a Discord Bot Need?
There isn’t one universal resource requirement for Discord bots.
A lightweight bot that handles a few commands can have a very different workload from one that:
- Processes images
- Uses AI APIs
- Performs media processing
- Runs database queries
- Handles large event volumes
- Performs scheduled jobs
- Integrates with multiple external APIs
- Runs additional applications on the same VPS
The better approach is to start with resources appropriate to your workload and monitor actual CPU, RAM, storage and network usage.
If your workload grows, you can scale the VPS accordingly.
Why a VPS Is a Natural Fit for Discord Bots
The concept is straightforward.
Your Discord bot is software that needs an environment in which to execute.
Your laptop can provide that environment.
But your laptop is also:
- A development machine
- Subject to sleep and shutdown
- Dependent on your local network
- Used for other work
- Not necessarily available 24/7
A VPS separates the bot from those dependencies.
You
↓
Laptop
↓
SSH
↓
VPS
↓
Discord Bot
↓
DiscordYour laptop becomes the tool you use to deploy and manage the bot.
The VPS becomes the environment where the bot actually runs.
The Bottom Line
How do you host a Discord bot on a VPS?
The process is:
- Create your Discord application and bot.
- Deploy a Linux VPS.
- Upload your Node.js or Python project.
- Install the required dependencies.
- Store your Discord token securely as an environment variable.
- Test the application.
- Use PM2 for Node.js or systemd for Python.
- Configure automatic restart.
- Configure startup after a VPS reboot.
- Monitor logs and test recovery.
The result is a bot that doesn’t depend on your laptop remaining powered on or connected to the internet.
Your laptop can sleep. Your Discord bot can keep working.
Ready to Move Your Discord Bot Off Your Laptop?
If your bot is ready for a persistent deployment environment, a VPS gives you control over the operating system, runtime and application process.
Deploy your bot, manage your environment and keep your application running independently of your local machine.
Build locally. Deploy remotely. Keep your bot online.
Frequently Asked Questions
Can I host a Discord bot on a VPS?
Yes. A VPS can run the application code behind a Discord bot independently of your personal computer. Node.js and Python are both commonly used runtimes for Discord applications.
Can a Discord bot run 24/7 on a VPS?
A VPS provides a persistent server environment, so a bot can continue running after you disconnect from SSH or shut down your local computer. Actual availability depends on the server, application, network and service architecture.
What is the best VPS for a Discord bot?
There isn’t one universal best VPS for every Discord bot. Choose resources according to the bot’s CPU, RAM, storage, database and network requirements.
Can I host a Node.js Discord bot on a VPS?
Yes. Deploy the Node.js project to the VPS, install its dependencies and use a process manager such as PM2 to manage the application.
Can I host a Python Discord bot on a VPS?
Yes. A Python Discord bot can run on a Linux VPS using Python and a service manager such as systemd.
How do I keep my Discord bot running after I close SSH?
Run the bot under a process or service manager rather than directly inside your SSH session. PM2 is an option for Node.js applications, while systemd is a native Linux service manager suitable for Python and other applications.
How do I automatically restart a Discord bot?
PM2 can automatically restart managed applications when they exit unexpectedly. systemd supports restart policies such as Restart=on-failure for long-running services.
Should I use PM2 or systemd?
For a Node.js bot, PM2 provides a convenient application-focused process-management workflow. For Python on Linux, systemd provides native service management. Both can be configured for automatic restart and startup after reboot.
Do I need a VPS for every Discord bot?
No. A VPS isn’t mandatory for every bot. Running locally may be perfectly appropriate during development. A VPS becomes useful when you want the application to run independently of your personal computer or need a persistent server environment.
Does a Discord bot need a persistent Gateway connection?
Not necessarily. Discord applications can receive events and interactions through the Gateway, while HTTP-based interactions can be delivered to a configured public endpoint. The architecture depends on what your application needs to receive and process.
Technical References
The article’s technical guidance is based primarily on first-party documentation:
- Discord Developer Documentation — Bots, Gateway connections, intents, and interactions
- Discord Developer Documentation — Bots & Companion AppsDiscord Gateway Documentation — Gateway WebSocket, events, and intents
- Discord Gateway DocumentationDiscord Interactions Documentation — Slash commands, buttons, modals, and HTTP interactions
- Discord Interactions Documentationnpm Documentation —
npm ci, lockfiles, and deployment-oriented installs - npm ci DocumentationPM2 Documentation — Process management and keeping Node.js applications running
- PM2 Runtime DocumentationPM2 Startup Hook — Starting applications automatically after server reboot
- PM2 Startup Hook DocumentationPM2 Environment Variables — Managing environment variables for applications
- PM2 Environment Variables DocumentationUbuntu/systemd Documentation — Service units, restart behavior, and service configuration
- Ubuntu systemd.service Documentation