Buyukweb
Discord Bot Hosting: Node.js + PM2 ile VDS'te 7/24 Çalıştırma Rehberi

Discord Bot Hosting: Node.js + PM2 ile VDS'te 7/24 Çalıştırma Rehberi

Discord bot'unu Node.js + PM2 ile Türkiye lokasyonlu VDS sunucuda 7/24 çalıştırma. discord.js, slash commands, deploy ve auto-restart kurulumu.

Discord Bot Hosting: Node.js + PM2 ile VDS'te 7/24 Çalıştırma Rehberi

Discord bot'lar, sunucu yönetimi, oyun istatistik takibi, müzik çalma, moderasyon, role yönetimi ve müşteri desteği gibi sayısız senaryoda kullanılır. Bot kodunuzu lokal bilgisayarınızda çalıştırırsanız bilgisayar kapanınca bot da çevrimdışı olur. Profesyonel bir bot 7/24 ayakta kalmalıdır — bu bir VDS sunucu işidir.

Büyükweb Türkiye VDS sunucularında discord.js + Node.js + PM2 ile bot deploy etme süreci pratik. Bu rehberde sıfırdan adım adım kurulumu, slash command yapılandırmayı, otomatik restart, log management ve monitoring anlatıyoruz.

VDS Gereksinimleri

Bot Aktivite RAM vCPU Disk
Küçük (1-3 sunucu, basit komutlar) 1 GB 1 vCPU 20 GB
Orta (5-50 sunucu, müzik, log) 2-4 GB 2 vCPU 30 GB
Büyük (1000+ sunucu, voice channels) 8-16 GB 4-6 vCPU 100 GB
Public bot (1M+ kullanıcı) 16+ GB 8+ vCPU Dedicated

Discord Developer Portal Hazırlık

Bot Application Oluştur

  1. https://discord.com/developers/applications adresine gir
  2. New Application → bot adı
  3. Sol menü → BotReset Token → tokeni kopyala (güvenli sakla)
  4. Privileged Gateway Intents (gerekiyorsa):
    • Server Members Intent
    • Message Content Intent
    • Presence Intent

OAuth2 Invite URL

OAuth2 → URL Generator:

  • Scopes: bot + applications.commands
  • Permissions: gerekli yetkiler (örn. Send Messages, Manage Roles)

URL kopyala, Discord sunucusuna ekle.

Adım 1: VDS'e Bağlan ve Hazırla

# SSH ile bağlan
ssh user@vds.example.com

# Sistem güncelle
sudo apt update && sudo apt upgrade -y

# Build essentials (bazı npm paketleri için)
sudo apt install -y build-essential git curl

Adım 2: Node.js LTS Kurulum

NodeSource resmi repo (en güncel LTS):

# Node.js 20.x LTS
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# Doğrula
node -v   # v20.x.x
npm -v    # 10.x.x

Adım 3: Bot için Sistem Kullanıcısı

# Bot için ayrı kullanıcı (root değil — güvenlik)
sudo adduser discordbot
sudo usermod -aG sudo discordbot   # opsiyonel
sudo su - discordbot

Adım 4: Bot Klasör Yapısı

mkdir -p ~/bots/my-bot
cd ~/bots/my-bot

# Git ile repo clone (varsa)
git clone https://github.com/YOUR_USER/my-discord-bot.git .

# Veya sıfırdan başlat
npm init -y

Adım 5: discord.js Kurulum

npm install discord.js dotenv

.env

# ~/bots/my-bot/.env
DISCORD_TOKEN=BOTTOKEN_BURAYA
CLIENT_ID=APPLICATION_ID
GUILD_ID=TEST_GUILD_ID

İzin:

chmod 600 .env

Adım 6: Basit Bot Skeleton

index.js

require('dotenv').config();
const { Client, Events, GatewayIntentBits, Collection } = require('discord.js');
const fs = require('node:fs');
const path = require('node:path');

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

// Komutları yükle
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
if (fs.existsSync(commandsPath)) {
  for (const file of fs.readdirSync(commandsPath).filter(f => f.endsWith('.js'))) {
    const command = require(path.join(commandsPath, file));
    if ('data' in command && 'execute' in command) {
      client.commands.set(command.data.name, command);
    }
  }
}

// Olaylar
client.once(Events.ClientReady, c => {
  console.log(\`Bot logged in as \${c.user.tag}\`);
});

client.on(Events.InteractionCreate, async interaction => {
  if (!interaction.isChatInputCommand()) return;
  const command = client.commands.get(interaction.commandName);
  if (!command) return;
  try {
    await command.execute(interaction);
  } catch (error) {
    console.error(error);
    if (interaction.replied || interaction.deferred) {
      await interaction.followUp({ content: 'Hata oluştu!', ephemeral: true });
    } else {
      await interaction.reply({ content: 'Hata oluştu!', ephemeral: true });
    }
  }
});

// Bağlan
client.login(process.env.DISCORD_TOKEN);

// Graceful shutdown
process.on('SIGINT', () => {
  console.log('SIGINT received — shutting down');
  client.destroy();
  process.exit(0);
});

commands/ping.js

const { SlashCommandBuilder } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Bot gecikmesini gösterir'),
  async execute(interaction) {
    const sent = await interaction.reply({ content: 'Pinging...', fetchReply: true });
    const latency = sent.createdTimestamp - interaction.createdTimestamp;
    await interaction.editReply(\`Pong! Latency: \${latency}ms\`);
  },
};

commands/hello.js

const { SlashCommandBuilder } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('hello')
    .setDescription('Selamlama mesajı'),
  async execute(interaction) {
    await interaction.reply(\`Selam \${interaction.user}!\`);
  },
};

Adım 7: Slash Command Deploy

deploy-commands.js

require('dotenv').config();
const { REST, Routes } = require('discord.js');
const fs = require('node:fs');
const path = require('node:path');

const commands = [];
const commandsPath = path.join(__dirname, 'commands');
for (const file of fs.readdirSync(commandsPath).filter(f => f.endsWith('.js'))) {
  const command = require(path.join(commandsPath, file));
  commands.push(command.data.toJSON());
}

const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);

(async () => {
  try {
    console.log(\`Deploying \${commands.length} commands...\`);
    // Test sunucu için (anlık)
    await rest.put(
      Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID),
      { body: commands }
    );
    // Production: tüm sunucular (1 saate kadar yansır)
    // await rest.put(Routes.applicationCommands(process.env.CLIENT_ID), { body: commands });
    console.log('Commands deployed!');
  } catch (error) {
    console.error(error);
  }
})();

Çalıştır

node deploy-commands.js

Test sunucunda /ping ve /hello komutları görünür.

Adım 8: Bot'u Çalıştır (Manual Test)

node index.js

Output:

Bot logged in as MyBot#1234

Ctrl+C ile durdurun. Şimdi PM2 ile production-ready yapacağız.

Adım 9: PM2 Kurulum

sudo npm install -g pm2

# Versiyon
pm2 -v

Adım 10: PM2 ile Bot'u Başlat

cd ~/bots/my-bot
pm2 start index.js --name my-bot --time

# Listele
pm2 list

# Logs
pm2 logs my-bot

ecosystem.config.js (Daha İyi Yöntem)

// ~/bots/my-bot/ecosystem.config.js
module.exports = {
  apps: [{
    name: 'my-bot',
    script: 'index.js',
    instances: 1,
    autorestart: true,
    watch: false,            // Dev'da true, prod'da false
    max_memory_restart: '500M',
    error_file: './logs/error.log',
    out_file: './logs/out.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss',
    env: {
      NODE_ENV: 'production',
    },
    env_dev: {
      NODE_ENV: 'development',
    },
  }],
};
mkdir -p logs
pm2 start ecosystem.config.js

PM2 Status

pm2 monit       # Real-time monitoring
pm2 status      # Listele
pm2 restart my-bot
pm2 stop my-bot
pm2 delete my-bot

Adım 11: Boot'ta Otomatik Başlatma

pm2 startup
# Çıktıdaki sudo komutunu çalıştır

pm2 save

VDS reboot olduğunda PM2 otomatik bot'u başlatır.

Adım 12: Log Management

PM2 Log Rotation

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true

7 gün saklı, sıkıştırılmış log dosyaları.

Log Görüntüleme

pm2 logs my-bot --lines 100
pm2 logs my-bot --raw         # JSON formatlı
pm2 flush                     # Tüm logları temizle

Adım 13: Monitoring + Uptime

PM2 Plus (Web Dashboard)

pm2.io sitesinden ücretsiz hesap aç → pm2 link <key> <secret> → web dashboard'dan tüm bot'larınızı izle.

Uptime Robot

External monitoring:

Bot HTTP endpoint için Express ekle:

// healthz.js
const express = require('express');
const app = express();
app.get('/healthz', (req, res) => res.json({ status: 'ok', uptime: process.uptime() }));
app.listen(3000);

Uptime Robot http://YOUR_VDS_IP:3000/healthz kontrol eder.

Adım 14: Güvenlik Best Practice

Token Asla Commit Edilmemeli

# .gitignore
.env
node_modules/
logs/

Kullanıcı Yetki Sınırı

Bot kendi kullanıcısı ile çalışsın (sudo değil); root erişim almamış olun.

Rate Limiting

Discord API rate limit'lerine duyarlı olun:

const { LimiterMemory } = require('rate-limiter-flexible');
const limiter = new LimiterMemory({
  points: 10,        // 10 istek
  duration: 60,      // 60 sn'de
});

client.on(Events.MessageCreate, async msg => {
  try {
    await limiter.consume(msg.author.id);
    // Komut işle
  } catch {
    // Limit aşıldı — kullanıcıyı geçici sustur
  }
});

Input Sanitization

User input'u doğrudan SQL/shell'e geçirmeyin:

// KÖTÜ
db.query(\`SELECT * FROM users WHERE id = '\${userId}'\`);

// İYİ
db.query('SELECT * FROM users WHERE id = ?', [userId]);

Adım 15: Veritabanı Entegrasyonu

SQLite (Tek Dosya, Basit)

npm install better-sqlite3
const Database = require('better-sqlite3');
const db = new Database('./bot.db');
db.exec('CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, points INTEGER)');

PostgreSQL (Production)

npm install pg
const { Pool } = require('pg');
const pool = new Pool({
  user: process.env.DB_USER,
  host: process.env.DB_HOST,
  database: process.env.DB_NAME,
  password: process.env.DB_PASSWORD,
  port: 5432,
});

VDS'te PostgreSQL kurulumu için: PostgreSQL Kurulumu.

Adım 16: Deployment Otomasyon (CI/CD)

Git Auto-Deploy

# VDS'te
cd ~/bots/my-bot
git pull origin main
npm ci --production
pm2 restart my-bot

deploy.sh

#!/bin/bash
set -e
cd ~/bots/my-bot
git pull origin main
npm ci --production
node deploy-commands.js
pm2 restart my-bot --update-env
echo "Deploy complete"

chmod +x deploy.sh./deploy.sh ile tek komutta deploy.

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy Bot

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: SSH to VDS
        uses: appleboy/ssh-action@v1
        with:
          host: \${{ secrets.VDS_HOST }}
          username: \${{ secrets.VDS_USER }}
          key: \${{ secrets.SSH_KEY }}
          script: |
            cd ~/bots/my-bot
            ./deploy.sh

GitHub'a push → VDS otomatik deploy.

Yaygın Sorunlar

Sorun Çözüm
"Invalid token" .env'i tekrar kontrol; token reset
"Missing intents" Developer portal'da Privileged Intents aç
Bot 1 dk sonra düşüyor OOM — PM2 max_memory_restart
Slash commands görünmüyor deploy-commands.js çalıştırıldı mı?
Voice channel sessiz FFmpeg + opus libs kurulu mu?
Database connection lost Connection pool kullan
Heavy CPU Event listener sızıntısı; process.memoryUsage() izle

Performans

Bot Sharding (1000+ Guild)

npm install discord.js shard-manager
// shard.js
const { ShardingManager } = require('discord.js');
const manager = new ShardingManager('./index.js', {
  token: process.env.DISCORD_TOKEN,
  totalShards: 'auto',
});
manager.spawn();

PM2 ile shard.js çalıştırın; her shard ayrı process.

Sıkça Sorulan Sorular

Discord bot için hangi VDS paketi yeterli?

Küçük bot için Başlangıç paketi (1-2 GB RAM). Müzik bot, voice channel desteği gerekirse Performans paketi.

Bot 7/24 çalışmadığında ne olur?

Discord bot listede "offline" görünür; komutlar çalışmaz. PM2 + boot'ta otomatik başlatma ile bunu önlüyoruz.

Free hosting (Heroku, Replit) bot için yeter mi?

Heroku free tier kapatıldı (2022). Replit free 1 saat sonra uyutuluyor. VDS profesyonel bot için tek doğru yol.

Bot kodumun gizliliği için?

VDS sizin; kimse ona erişemez. Token'ı .env'de tutun, .gitignore'a ekleyin.

Ne kadar bot eş zamanlı çalıştırabilirim?

VDS RAM/CPU sınırı içinde. 1 GB RAM'de 5-10 küçük bot rahat. PM2 her birini ayrı process'te yönetir.

Discord bot Türkçe karakterlerle ilgili sorun var mı?

Yok — discord.js UTF-8 destekli. Linux locale'i tr_TR.UTF-8 ayarlı olsun.

Veritabanı backup nasıl?

SQLite: dosyayı kopyala. PostgreSQL: pg_dump cron + Restic ile B2 backup.

İlgili Rehberler

Production Best Practices

Discord bot'u Büyükweb VDS üzerinde production'a aldığınızda dikkat edeceğiniz kritik konular:

1. Rate Limit Yönetimi

Discord API'sinin global rate limit (50 req/sec) ve route-bazlı rate limit sınırları vardır. discord.js v14 otomatik rate limit handler ile gelir, ancak özel HTTP istekleri yapıyorsanız:

// Rate limit'e takılırsa retry-after header'ını oku
client.rest.on('rateLimited', (info) => {
  console.warn('Rate limited:', info.timeToReset, 'ms', info.route);
});

2. Sharding (10K+ guild için)

Discord 2.500 guild'i geçen bot'lar için sharding zorunlu kılar. discord.js ShardingManager ile:

const { ShardingManager } = require('discord.js');
const manager = new ShardingManager('./bot.js', { token: process.env.TOKEN, totalShards: 'auto' });
manager.on('shardCreate', shard => console.log(`Shard ${shard.id} launched`));
manager.spawn();

Büyükweb VDS'te shard başına 2 vCore + 2 GB RAM ayrımı önerilir; 10 shard için E5-V4 VDS Pro paketi yeterli.

3. Database Bağlantı Havuzu

PostgreSQL veya MySQL kullanıyorsanız, her komuta yeni bağlantı açmak yerine pool kullanın:

const { Pool } = require('pg');
const pool = new Pool({ max: 20, idleTimeoutMillis: 30000 });

4. PM2 Cluster ve Auto-Restart

ecosystem.config.js içinde exec_mode: 'fork' kullanın (Discord WebSocket cluster'da sorun çıkarabilir):

module.exports = { apps: [{
  name: 'discord-bot',
  script: './bot.js',
  exec_mode: 'fork',
  instances: 1,
  max_memory_restart: '1G',
  autorestart: true,
  watch: false,
}]};

5. Log Rotasyonu

PM2 logrotate modülünü kurun:

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7

Sıkça Sorulan Sorular

Discord bot için kaç GB RAM yeterli?

Tek shard, az kullanıcılı bot için 1-2 GB yeterli. 10K+ guild bot'u için shard başına 2 GB önerilir. Büyükweb VDS sunucu paketleri içinde 4 GB+ RAM seçenekleri uygundur.

Bot trafiği hosting'i etkiler mi?

Discord bot'u WebSocket bağlantısı kullanır; bant genişliği tüketimi düşüktür (saatte ~50-100 MB). Büyükweb VDS bant genişlik kotası içinde rahatlıkla çalışır.

Bot'u Türkiye'de host etmenin avantajı nedir?

Discord global CDN kullansa da, bot komutlarına yanıt veren database/API arka planındaysa Türkiye lokasyonu kullanıcı deneyimini iyileştirir. Büyükweb Bursa Tier 3 lokasyonu Türk kullanıcılara 10-20 ms ek hız sunar.

24/7 uptime için ne gerekir?

Büyükweb VDS paketleri %99.8 SLA sunar. PM2 ile auto-restart + monitoring (Zabbix/Prometheus) kombinasyonu ile aylık downtime 30 dakikanın altında tutulur.

İlgili Büyükweb Hizmetleri

Discord bot ve Node.js uygulama hosting için Türkiye lokasyonlu Büyükweb hizmetleri:

Sorularınız için 0850 302 60 70 numaralı destek hattımıza veya iletişim sayfamıza yazabilirsiniz.

Sunucu Yönetimi İlgili Hizmetlerimiz

Bu yazıda anlatılan teknik konuyu profesyonel altyapıyla deneyimleyin

Etiketler:

#discord bot#discord.js#nodejs#pm2#vds bot hosting#slash commands#bot hosting#process manager

Bu yazıyı paylaş