NodeJSPublished on December 15, 20259 min read

How to host a Discord bot (discord.js) on OuiPanel

This guide shows how to host a Discord bot written with discord.js (JavaScript, Node.js) on a OuiHeberg Node.js server, managed in OuiPanel. The bot runs continuously on the server, even when your computer is off. You need a bot created on the Discord Developer Portal, its token and the bot's files (index.js, package.json…).


Create the bot on Discord

Already have your bot and its token? Skip to the next section.

Create the application

  1. Go to the Discord Developer Portal and log in with your Discord account.

  2. Click New Application.

  3. Name your application, for example "My Bot", accept the terms, then click Create.

Create an application window of the Discord Developer Portal with the Name field

Create the bot

In the left menu, click Bot. Recent applications already have their bot. If the Add Bot button shows up, click it and confirm with Yes, do it! in the window.

Get the token

  1. In the Bot section, click Reset Token.

  2. Confirm, then copy the token shown.

The token works like a password. Anyone who gets it can control your bot. Never share it and never put it in public code (GitHub, etc.).

Enable the intents

Still in the Bot section, scroll down to Privileged Gateway Intents and enable the intents you need.

IntentUse
PRESENCE INTENTOptional
SERVER MEMBERS INTENTOptional
MESSAGE CONTENT INTENTRequired to read message content

Privileged Gateway Intents section of the Discord Developer Portal with its three toggles

Without MESSAGE CONTENT INTENT, your bot cannot read message content, and a command like !ping gets no answer.

Invite the bot to your Discord server

  1. In the left menu, click OAuth2 › URL Generator.

  2. Under Scopes, tick bot and applications.commands.

  3. Under Bot Permissions, tick the permissions you need, or Administrator for all of them.

  4. Copy the URL generated at the bottom of the page, open it and invite the bot to your Discord server.

Generated URL field of the OAuth2 page with the bot invite link


Prepare the bot files

File structure

Your bot should have this structure.

MyBot/
├── index.js         ← Main file (or bot.js, main.js...)
├── package.json     ← npm dependencies
├── .env             ← Bot's token (created on the server)
├── commands/        ← (Optional) Commands folder
└── events/          ← (Optional) Events folder

The package.json file

Create a package.json file with the discord.js and dotenv dependencies.

{
  "name": "my-discord-bot",
  "version": "1.0.0",
  "description": "My Discord bot",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "discord.js": "^14.14.1",
    "dotenv": "^16.3.1"
  }
}

Adjust "main": "index.js" to the name of your main file (bot.js, main.js, etc.).

The main file (index.js)

Create your main file. It loads the token with dotenv.

// Load environment variables from .env
require('dotenv').config();

const { Client, GatewayIntentBits } = require('discord.js');

// Create the Discord client
const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent
    ]
});

// Event: Bot ready
client.once('ready', () => {
    console.log(`Bot connected as ${client.user.tag}`);
});

// Event: Message received
client.on('messageCreate', message => {
    if (message.author.bot) return;
    
    // Use the prefix from .env (optional)
    const prefix = process.env.PREFIX || '!';
    
    if (message.content === `${prefix}ping`) {
        message.reply('Pong!');
    }
});

// Error handling
process.on('unhandledRejection', error => {
    console.error('Unhandled error:', error);
});

client.on('error', error => {
    console.error('Discord error:', error);
});

// Connect with the token from .env
client.login(process.env.DISCORD_TOKEN);

The require('dotenv').config(); line must be the first line of your file.


Upload the files to OuiPanel

The File Manager has no upload button. Files are sent by drag and drop.

  1. Log in to OuiPanel at dash.ouipanel.com and open your Node.js server.

  2. In the side menu, click File Manager.

  3. Delete the default files, if any.

  4. From your computer, drag index.js, package.json and your folders (commands/, events/…) onto the page.

  5. When the "Drop your files here" overlay appears, release them.

Each file sent this way is limited to 100 MB.

Drop your files here overlay shown during a drag and drop in the File Manager

Do not upload your .env file. You will create it directly on the server in the next step.

Over SFTP

For many files, or files over 100 MB, use SFTP. Connect with FileZilla, drag the whole content of your bot folder, then check that everything arrived. The guide How to connect via SFTP with FileZilla explains the connection.


Create the .env file

Never put your token directly in the code. Create a .env file on the server.

  1. In the File Manager, in Root, click Create file.

  2. In the "Create new file" window, type .env in File name, with the leading dot, then click Create file.

  3. Click .env to open it in the editor and paste the content below.

  4. Replace your_token_here with your token, then click Save.

# Discord bot token
DISCORD_TOKEN=your_token_here

# Command prefix (optional)
PREFIX=!

Example with a real token:

DISCORD_TOKEN=MTIzNDU2Nzg5MDEyMzQ1Njc4OQ.ABcdEF.abcdefghijklmnopqrstuvwxyz123456
PREFIX=!
  • No spaces around the =.

  • No quotes around the values.

  • Never share this file.

File Manager at the root of a Node.js server with index.js, package.json and package-lock.json

Here is the final structure on the server.

Server Root/
├── .env              ← Contains DISCORD_TOKEN
├── index.js          ← Your code
├── package.json      ← Dependencies
└── node_modules/     ← (created automatically)

Set the main file and the Node.js version

OuiPanel needs to know which file to run at startup. On a Node.js server, this setting is a server variable.

  1. Open Configuration › Server Settings.

  2. In the Server Launch card, check the System version. The list offers Node.js 12, 14 and every version from 16 to 26. Version 24, the LTS release, suits discord.js.

  3. In the Environment Variables card, type your file name in Main file (main file; variable names are shown in French).

  4. Click the tick to the right of the field (Save).

Your main fileValue of Main file
index.jsindex.js
bot.jsbot.js
main.jsmain.js
src/index.jssrc/index.js
app.jsapp.js

The same card offers Additional Node packages and Node packages to uninstall, to add or remove npm packages (names separated by spaces). The Additional arguments field passes options to Node.js.

Settings of a Node.js server with the Nodejs 24 version and the Main file variable

The name must match your file exactly, including upper and lower case.


Start and test the bot

Start the server

In the side menu, click Console, then Start. At startup, the server installs the dependencies from package.json with npm install, then runs your file.

> npm install
added 45 packages in 3s

> node index.js
Bot connected as MyBot#1234

Check on Discord

The console should show this line.

Bot connected as MyBot#1234
  1. Open Discord. Your bot shows as online, with a green dot.

  2. Try the !ping command. The bot answers "Pong!".


Deploy from a Git repository

Your code lives on GitHub, GitLab, Bitbucket or Codeberg? The Deployment page fetches the repository and installs the dependencies for you, instead of uploading files by hand.

  1. In the side menu, click Deployment.

  2. In the Link a repository block, fill in Repository address and Branch.

  3. Under Repository access, choose Public repository, or one of the two private repository options (deploy key or access token).

  4. Tick Deploy on every push to the branch if you want automatic updates, then click Save.

  5. Click Deploy now.

Each deployment restarts the server, which stays stopped while dependencies are installed. If the install fails, the previous version starts again. Files not tracked by Git, such as your .env, stay in place. Before the first deployment, the panel backs up the server.

Git deployment page with Link a repository, Repository address, Branch and Repository access

For a private repository, the deploy key is recommended. The panel generates a key for this server, to add to the repository as read-only.


Run multiple bots with a single plan

A Node.js server runs a single file at startup. To run several bots on the same plan, that file can be a launcher that starts each bot in its own process. If one bot crashes, the others keep running. They all share the plan's memory and CPU.

  1. Upload your bots' files to the server root, for example bot1.js and bot2.js.

  2. Put the dependencies of all the bots in the package.json file at the root.

  3. In the .env file, give each bot's token its own name, such as DISCORD_TOKEN_1 and DISCORD_TOKEN_2. Have each bot read its own token, for example with client.login(process.env.DISCORD_TOKEN_1).

  4. At the root, create a launcher.js file with the content below, then adjust the bots list.

  5. In Configuration › Server Settings, type launcher.js in Fichier principal (main file), then click the tick (Save).

  6. In the Console, click Restart.

// Starts each bot in its own process
const { spawn } = require('child_process');
const readline = require('readline');

// Your bots' files, at the server root
const bots = ['bot1.js', 'bot2.js'];

for (const file of bots) {
  const child = spawn(process.execPath, [file]);

  // Prints each line from the bot in the console, prefixed with its name
  readline.createInterface({ input: child.stdout })
    .on('line', (line) => console.log(`[${file}] ${line}`));
  readline.createInterface({ input: child.stderr })
    .on('line', (line) => console.error(`[${file}] ${line}`));

  child.on('exit', (code) => console.log(`[${file}] stopped (code ${code})`));
}

In the console, each line starts with the name of the bot that wrote it, for example [bot1.js] Bot connected as MyBot#1234. When a bot stops, the launcher shows its exit code.

The launcher does not restart a bot that stops. To start it again, restart the server.


Troubleshooting

The bot does not start

ErrorFix
Cannot find module 'discord.js'Check package.json and restart.
Cannot find module 'dotenv'Add dotenv to package.json.
Error: Cannot find module './index.js'Wrong value in the Main file variable.
ENOENT: no such file or directoryThe file given does not exist.

Token error

ErrorFix
An invalid token was providedCheck the token in .env.
TOKEN_INVALIDRegenerate the token on the Discord Developer Portal.
Used disallowed intentsEnable the intents on the Discord Developer Portal.

The bot does not read messages

CauseFix
MESSAGE CONTENT INTENT disabledEnable it on the Discord Developer Portal.
Wrong intents in the codeAdd GatewayIntentBits.MessageContent.

The .env file is not read

CauseFix
dotenv missingCheck that it is listed in package.json.
require in the wrong placerequire('dotenv').config(); must be the first line.
Wrong file nameThe file must be named exactly .env.

npm install fails

ErrorFix
package.json not foundCheck that the file is at the root.
ERESOLVE unable to resolveUpdate the versions in package.json.

Best practices

Protect the .env file

DoAvoid
Keep .env on the server onlySharing .env
Create .env directly in OuiPanelUploading .env from your computer
Add .env to .gitignoreCommitting .env to GitHub

Recommended .gitignore file in your project:

# Environment variables
.env

# Node modules
node_modules/

Security and performance

  • Never share your token, and regenerate it if it leaks.

  • Create .env directly on the server.

  • Only enable the intents you need.

  • Handle errors with try/catch and add logs for debugging.

Organize a larger bot

For a more organized bot, split commands and events.

MyBot/
├── index.js              ← Entry point
├── package.json
├── .env                  ← Created on the server
├── commands/
│   ├── ping.js
│   ├── help.js
│   └── info.js
├── events/
│   ├── ready.js
│   └── messageCreate.js
└── config.json           ← Non-sensitive configuration

Need help?

Open a ticket from Tickets › Open a Ticket, or from the Contact support tile at the bottom of your server's page in the client area. You can also ask your question on the OuiHeberg Discord.

Was this article helpful?

392 views
Share this article
Node.js
Need Node.js hosting?

Deploy your Node.js applications with our optimized hosting and dedicated support.

View plans →

Related Articles