EQVPS

Draai een Telegram-bot 24/7 op een VPS: aiogram, systemd, polling vs webhook

4 jul 2026 · 5 min lezen · EQVPS Team

Je schreef een Telegram-bot met aiogram, testte hem lokaal, en hij werkt. Nu moet hij ergens leven dat niet slaapt wanneer je de laptop sluit. Een kleine VPS is het natuurlijke thuis — maar er is een gat tussen python bot.py in een SSH-sessie en een bot die daadwerkelijk up blijft door crashes, reboots, en je verbinding die wegvalt.

Dit is de productie-versie: een virtualenv, de token gehouden buiten je code, een systemd-service die de bot op eigen kracht doet herrijzen, en een helder antwoord op de vraag die iedereen uiteindelijk stelt — polling of webhook?

Waarom niet gewoon op je laptop draaien

Een bot heeft een gestage uitgaande verbinding naar Telegram nodig. Je laptop slaapt, herstart voor updates, en hopt tussen netwerken — elk daarvan dropt de bot, en gebruikers stuiten op een muur van stilte. Een VPS houdt die verbinding de klok rond. Dat is de hele reden om hem van je machine te halen, en het is dezelfde reden dat een Discord-bot op een server hoort.

Als je gewoon het snelst mogelijke "krijg het online"-pad wilt met een minimale bot, dekt de host-een-Telegram-bot-walkthrough dat. Dit stuk gaat een niveau dieper: aiogram, veilige token-behandeling, en weten wanneer op te schalen.

De bot, in een virtualenv

SSH erin en houd de bot geïsoleerd in zijn eigen venv — installeer geen packages system-wide, het maakt upgrades en cleanup later een puinhoop:

sudo apt update && sudo apt install -y python3-venv
mkdir ~/tgbot && cd ~/tgbot
python3 -m venv venv && source venv/bin/activate
pip install -U aiogram

Een minimale aiogram 3-bot die zijn token uit de environment leest, niet uit een hard-coded string:

# bot.py
import asyncio, logging, os
from aiogram import Bot, Dispatcher
from aiogram.types import Message
from aiogram.filters import CommandStart

logging.basicConfig(level=logging.INFO)
dp = Dispatcher()

@dp.message(CommandStart())
async def start(m: Message):
    await m.answer("Alive and running on a VPS.")

async def main():
    bot = Bot(os.environ["BOT_TOKEN"])
    await dp.start_polling(bot)

if __name__ == "__main__":
    asyncio.run(main())

Houd de token uit je code

Plak nooit de BotFather-token in bot.py — één push naar een publieke repo en hij is gelekt. Zet hem in plaats daarvan in een root-leesbaar env-bestand:

sudo tee /etc/tgbot.env >/dev/null <<'EOF'
BOT_TOKEN=123456:your-token-from-botfather
EOF
sudo chmod 600 /etc/tgbot.env

Een gelekte token is één /revoke in BotFather verwijderd van gefixt zijn — maar een gelekt iets anders op een gedeelde machine is erger. Een dedicated VPS voor de bot is eerlijk gezegd een veiliger thuis voor de token dan je dagelijkse laptop: als hij lekt, roteer je één token, niet je hele setup.

Het deel dat het in leven houdt: systemd

Dit is wat een bot die draait scheidt van een bot die blijft draaien. Maak de service:

# /etc/systemd/system/tgbot.service
[Unit]
Description=Telegram bot (aiogram)
After=network-online.target
Wants=network-online.target

[Service]
User=botuser
WorkingDirectory=/home/botuser/tgbot
EnvironmentFile=/etc/tgbot.env
ExecStart=/home/botuser/tgbot/venv/bin/python bot.py
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Draai het als een non-root-gebruiker (botuser hierboven), niet root — als de bot ooit gecompromitteerd is, wil je hem ingedamd. Dan:

sudo systemctl daemon-reload
sudo systemctl enable --now tgbot

Restart=always met RestartSec=3 betekent dat een crash — een slechte update van Telegram, een onbehandelde exception, een OOM — de bot in drie seconden terugbrengt in plaats van hem dood te laten tot je het merkt. Bekijk het live:

journalctl -u tgbot -f

Dat is je hele logging-setup. Geen log-bestanden om te roteren, geen extra tooling — journald heeft het al.

Updaten zonder downtime-drama

Wanneer je de code verandert of aiogram bumpt:

cd ~/tgbot && source venv/bin/activate
pip install -U aiogram          # if upgrading the library
sudo systemctl restart tgbot
journalctl -u tgbot -n 30 --no-pager   # confirm it came back clean

De herstart blipt de bot een seconde of twee. Voor een polling-bot is dat onzichtbaar voor gebruikers — Telegram queuet updates en levert ze zodra de bot opnieuw verbindt.

Polling vs webhook — de eerlijke versie

Dit is de beslissing die mensen overdenken. Hier is de gewone versie:

Polling (start_polling, wat de code hierboven gebruikt) heeft de bot Telegram vragen "iets nieuws?" op een langlevende verbinding. Het heeft niets nodig behalve uitgaand internet — geen domein, geen TLS, geen open inkomende poorten. Het draait prima achter NAT. Voor de overweldigende meerderheid van bots is dit correct en zou je hier moeten stoppen.

Webhook heeft Telegram updates naar jou pushen, wat betekent dat je een publiek HTTPS-endpoint moet blootstellen. Dat vereist een domein en een bereikbare inkomende poort — dus ofwel een dedicated publiek IP of een reverse proxy ervoor. Meer setup, meer dingen die breken. De opbrengst is lagere latency en minder overhead op grote schaal — duizenden gelijktijdige gebruikers, zware update-volume.

De praktische regel: begin met polling op een NAT-plan. Ga alleen over naar een webhook wanneer je polling daadwerkelijk bent ontgroeid — en als je dat doet, is dat wanneer een dedicated IP zijn plaats verdient, omdat je dat inkomende HTTPS-endpoint nodig hebt.

Wat het kost om te draaien

Een polling-bot is licht. Het idlet op Telegram's long-poll en reageert op berichten, dus de box wacht meestal:

Aanmelden is e-mail-only en je betaalt in USDC of USDT op Base of Ethereum — geen kaart, geen ID. Een kaart werkt ook, maar de on-ramp heeft een minimum van ~$27, dus voor een $3-plan is het soepeler om één keer een klein saldo op te waarderen en renewals eruit te laten trekken. Het is CPU-only, één datacenter in Duitsland — een non-issue voor een bot, goed om te weten als je een GPU of een specifieke regio nodig had.

De eerlijke conclusie

Een Telegram-bot is een van de goedkoopste dingen die je kunt zelf-hosten: een $3-box, een systemd-unit, en polling geeft je een bot die online is door crashes en reboots zonder dat je hem babysit. Grijp naar een webhook en een groter plan alleen wanneer schaal het daadwerkelijk forceert — niet omdat een tutorial je vertelde dat webhooks "beter" zijn. Krijg de kleine box, houd de token in een env-bestand, laat systemd de uptime afhandelen, en — voor alles — draai de nieuwe-VPS beveiligingschecklist zodat de box zelf op slot zit.


Klaar om de jouwe te hosten? Een Telegram-bot gebruikt nauwelijks resources — het Nano-plan ($3/mnd) draait hem 24/7 zonder gedoe.

FAQ

Polling of webhook — welke moet ik gebruiken?

Begin met polling. Het werkt vanaf elke box met uitgaand internet — geen domein, geen open poorten, geen TLS — en het is ruim voldoende voor de meeste bots. Schakel alleen over naar een webhook wanneer je op schaal draait (duizenden gebruikers) of de laagst mogelijke latency nodig hebt; een webhook heeft een publiek HTTPS-endpoint nodig, wat een domein en een bereikbare inkomende poort betekent (een dedicated IP, of een reverse proxy), dus het zijn meer bewegende delen. Voor 95% van de bots is polling op een kleine VPS het juiste antwoord.

Heb ik een dedicated IP of een domein nodig voor een Telegram-bot?

Niet voor polling — de bot maakt alleen uitgaande calls naar Telegram, dus een NAT-plan met port-forwarded SSH is genoeg. Je hebt een publiek HTTPS-endpoint nodig (domein + inkomende poort, d.w.z. een dedicated IP of reverse proxy) alleen als je overschakelt naar webhook-modus. De meeste bots hebben het nooit nodig.

Welke grootte VPS heeft een aiogram-bot nodig?

De kleinste. Een polling-bot wacht meestal op Telegram's long-poll, dus 1 vCPU / 1 GB (een $3 Nano) handelt de meeste bots comfortabel af. Schaal alleen op wanneer de bot zelf het zware werk doet — een database, media-verwerking, of een lokaal model — wat je richting 2 GB ($5) of meer duwt.

Hoe houd ik de bot draaiend nadat ik uitlog?

Draai hem als een systemd-service met Restart=always. Gestart in je terminal sterft hij wanneer SSH sluit; onder systemd overleeft hij logout, herstart bij crash, en komt terug na een reboot. Dat is de lijn tussen een demo en iets waar je op kunt vertrouwen.

← Terug naar blogBekijk plannen & prijzen →

Reacties

Nog geen reacties. Wees de eerste.

Laat een reactie achter

Reacties worden gemodereerd voordat ze verschijnen.