Skip to content

Deployment

umutxyp edited this page Oct 17, 2026 · 1 revision

Deployment

How to run Beatra around the clock on a server. Everything here uses what the repository ships: npm start (or node index.js), environment variables, and the built-in sharding manager.


Production checklist

  1. Node.js 22.12 or newer on the server.
  2. The bot folder (with git clone, so updates are a git pull away).
  3. DISCORD_TOKEN in .env, or as an environment variable on your host.
  4. Write access to the bot folder: the bot writes data/ and bin/.
  5. Outgoing internet access to Discord, the music sites, LRCLIB for lyrics, the npm registry when packages are installed, and (on start) GitHub for yt-dlp.
  6. YouTube access if your host is a VPS or data center: set up cookies or a proxy first (YouTube Access). Without it, YouTube songs fall back to SoundCloud.
  7. Something that keeps the process running and restarts it if the machine reboots: your hosting panel, or the service or process manager you already use on your server.

Note: The bot needs no open ports. It only makes outgoing connections. Its internal audio relay listens on 127.0.0.1 (this machine only) on a random port.


Starting and stopping

Action How
Start npm start, node . or node index.js from the bot folder (on Windows also start.bat)
Stop Ctrl + C, or a normal stop signal (SIGINT / SIGTERM) from your host

On a stop signal the bot shuts down cleanly: every shard saves its queues, leaves its voice channels and disconnects. The manager waits up to 10 seconds for this, then ends the shards and exits. Queues are restored on the next start (see Features).

Tip: If your process manager or panel lets you choose a start command, use node index.js with the bot folder as the working directory. The startup check then runs on every start, and npm is only called when packages need installing.


Hosting panels

On panels such as Pterodactyl or Railway you can set the settings as environment variables instead of writing a .env file:

Variable Value
DISCORD_TOKEN your token (required)
anything from Configuration as needed

When DISCORD_TOKEN is already in the environment, the bot does not create a .env file. Use npm start or node index.js as the start command.

Note: The bot keeps its files in the bot folder: bin/ (yt-dlp) and data/ (server languages and saved queues). If your host wipes that folder on restart, yt-dlp is simply downloaded again, but server languages and saved queues are lost. DATA_DIR can point data/ to a folder that is kept.


Sharding

The bot always runs under discord.js' ShardingManager: index.js runs the startup check, registers slash commands, then starts the shards. Each shard is a separate Discord connection with its own share of servers.

Setting Default When to change it
TOTAL_SHARDS auto Leave it on auto to use Discord's recommended count. Set a number only if you know you need a fixed count.
SHARD_MODE process process runs each shard as a child process (isolated). worker runs each shard as a worker thread.
SHARD_RESPAWN true Restart crashed shards automatically.
SHARD_SPAWN_DELAY 5500 Milliseconds between starting two shards.
SHARD_SPAWN_TIMEOUT 60000 Milliseconds a shard may take to log in and become ready.
SHARD_LIST auto Start only some shard ids in this process, for example 0,1.

What to expect in the console:

14:02:51 INFO  [manager] Launching shard 0
14:02:55 OK    [shard 0] [bot] Logged in as Beatra#1234 · 42 servers on this shard
14:02:55 OK    [manager] 1 shard(s) running

Some tips:

  • Every log line from a shard carries [shard N], so you can tell them apart.
  • YTDLP_CONCURRENCY (default 4) is per shard. More shards means more yt-dlp processes can run at once on the machine.
  • Each server's data file is written only by the shard that owns that server, so shards never write the same file.

Updating in production

git pull
npm start

The startup check sees the changed package.json / package-lock.json and installs the new packages itself. Slash commands are re-registered automatically only when they changed.

yt-dlp is checked for a new version at startup, at most once a day. If the bot runs for a long time without restarting, restart it now and then to keep yt-dlp (and therefore YouTube) working.

Upgrading from v16? Follow Installation > Updating from v16.


Logs

Log lines start with the time (UTC), the level, the shard and the part of the bot that wrote them:

14:03:27 OK    [shard 0] [music] Restored 2 music session(s)
14:05:10 INFO  [shard 0] [music] Playing "Song name" from youtube: found in 3.4s, audio after 4.6s
Want Do
More detail DEBUG=true (adds DisTube and ffmpeg debug output)
No colors (for log files) Set NO_COLOR=1. Colors are already off when the output is not a terminal.
Keep logs Let your process manager or panel capture the console output. Log warnings and errors go to stderr; everything else, including the startup checklist, goes to stdout.

Backups

Everything worth keeping is small:

Back up Why
.env Your token and settings
cookies.txt (if used) YouTube access
data/guilds/ Languages chosen with /language

data/sessions/, data/relay/, bin/ and node_modules/ are rebuilt or recreated automatically.


Registering slash commands

At every start the bot registers its slash commands, but only if they changed since the last successful registration (it remembers a fingerprint in data/commands.hash).

Situation What happens
GUILD_ID empty Commands are registered globally, for every server
GUILD_ID set Commands are registered only in that server (the bot must be in it)
You want to force it npm run deploy

Note: npm run deploy does not run the startup check, so it needs CLIENT_ID in .env as well as DISCORD_TOKEN. Otherwise it stops with "DISCORD_TOKEN and CLIENT_ID must be set in .env".


Next: Troubleshooting · Configuration

Clone this wiki locally