Find us on social media
DeployCI/CDZero downtime5 min read
Update your bot with zero downtime
Deploy strategies with git pull + PM2 reload, blue-green with systemd and CI/CD with GitHub Actions.
Why zero downtime?
Every time you restart your bot, users see it disconnect briefly. With the right techniques you can minimize or eliminate that dead time.
Method 1: PM2 Reload (graceful)
PM2 reload starts a new instance before killing the old one:
bash
#!/bin/bash
# deploy.sh
cd /opt/bots/my-bot
git pull origin main
npm install --production
pm2 reload my-bot
echo "Deploy complete: $(date)"For this to work correctly, handle graceful shutdown:
javascript
process.on('SIGINT', async () => {
console.log('Closing connections...');
await client.destroy();
process.exit(0);
});Method 2: Blue-Green with systemd
Keep two instances and alternate between them:
bash
# Structure
/opt/bots/my-bot-blue/ # Active version
/opt/bots/my-bot-green/ # New versionDeploy script:
bash
#!/bin/bash
ACTIVE=$(systemctl is-active discord-bot-blue && echo 'blue' || echo 'green')
NEW=$([ "$ACTIVE" = 'blue' ] && echo 'green' || echo 'blue')
cd /opt/bots/my-bot-$NEW
git pull origin main
npm install --production
# Start the new version
sudo systemctl start discord-bot-$NEW
sleep 5
# Verify it started correctly
if systemctl is-active --quiet discord-bot-$NEW; then
sudo systemctl stop discord-bot-$ACTIVE
echo "Switched to $NEW"
else
sudo systemctl stop discord-bot-$NEW
echo "Deploy failed, $ACTIVE still active"
exit 1
fiMethod 3: CI/CD with GitHub Actions
Automate deployment on every push to main:
yaml
# .github/workflows/deploy.yml
name: Deploy Bot
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.VPS_HOST }}
username: deploy
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /opt/bots/my-bot
git pull origin main
npm install --production
pm2 reload my-botConfigure secrets in your GitHub repository:
VPS_HOST: Your Baires Host VPS IPSSH_PRIVATE_KEY: SSH private key for the deploy user
Graceful shutdown in discord.js
javascript
const shutdown = async () => {
console.log('Shutdown initiated...');
// Save pending state to DB
await saveState();
// Disconnect the bot
client.destroy();
process.exit(0);
};
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);Recommendations
- Use
pm2 reloadinstead ofpm2 restartfor zero downtime - Implement graceful shutdown to avoid data loss
- Test deployments in a staging environment before production
- Set up deploy success/failure notifications in Discord
Was this guide helpful?