EQVPS

How to host a Telegram bot on a VPS (and keep it running)

Jun 15, 2026 · 3 min read · EQVPS Team

A Telegram bot that only runs while your laptop is open isn't really running — it's demoing. To have it actually online, answering at 3am, surviving your reboots and its own crashes, it needs to live on a server. Here's the whole path, start to finish, with the commands.

Good news first: a bot is a tiny workload. It mostly sits idle waiting for messages, so the cheapest box runs it fine — no dedicated IP, no domain, nothing fancy.

1. Get a token from BotFather

In Telegram, message @BotFather, send /newbot, pick a name and username. It hands you a token that looks like 12345:AAH.... Treat it like a password — anyone with it controls your bot.

2. A minimal bot

SSH into the server, set up Python and the library:

sudo apt update && sudo apt install -y python3-venv
mkdir ~/mybot && cd ~/mybot
python3 -m venv venv && source venv/bin/activate
pip install python-telegram-bot

A bot that replies — ~/mybot/bot.py:

import os
from telegram.ext import ApplicationBuilder, CommandHandler

async def start(update, ctx):
    await update.message.reply_text("Alive and on a server. 🟢")

app = ApplicationBuilder().token(os.environ["BOT_TOKEN"]).build()
app.add_handler(CommandHandler("start", start))
app.run_polling()

Note it reads the token from an environment variable — not hardcoded. That matters in the next step.

3. The part that actually keeps it running: systemd

If you just run python bot.py, it dies the moment you close SSH. A systemd service is what makes it survive logout, crashes, and reboots. Create /etc/systemd/system/mybot.service:

[Unit]
Description=Telegram bot
After=network-online.target

[Service]
WorkingDirectory=/home/youruser/mybot
Environment=BOT_TOKEN=12345:AAH...your-token
ExecStart=/home/youruser/mybot/venv/bin/python bot.py
Restart=always
RestartSec=5
User=youruser

[Install]
WantedBy=multi-user.target

Then:

sudo systemctl daemon-reload
sudo systemctl enable --now mybot
sudo systemctl status mybot      # should say active (running)
journalctl -u mybot -f           # live logs

Restart=always is the line doing the real work — crash, and it's back in 5 seconds. enable means it comes up after a reboot. That's the whole difference between "I ran a bot once" and "my bot is up."

4. Why no domain or open ports

The bot uses long polling — it reaches out to Telegram for updates, so nothing needs to reach in. No public URL, no inbound firewall rule, no dedicated IP. This is exactly why a NAT VPS (outgoing address not your own, SSH on a port) is a fine and cheap home for a bot. Webhooks exist for very high volume, but you almost certainly don't need them to start.

Honest caveats

  • Token hygiene: here it's inline in the unit file for clarity — fine on a locked-down box, but for anything shared, load it from a root-only EnvironmentFile instead, and never commit it to git. Leaked? Revoke in BotFather, issue a new one.
  • Heavy bots: if your bot does the work itself (image generation, a local model), it's no longer tiny — size up accordingly.

That's it. Lock the box down first with the security checklist, drop the service in, and your bot stays online whether or not you do. On a crypto-paid VPS you can have it running a minute after you decide to.

FAQ

What VPS do I need for a Telegram bot?

The smallest one. A Telegram bot is mostly idle, waiting on updates, so 1 GB RAM and 2 cores is plenty for most bots — even fairly busy ones. You only need more if the bot does heavy work itself (image processing, a local model, a big database).

How do I keep a Telegram bot running after I close SSH?

Run it as a systemd service. Unlike launching it in your terminal, systemd keeps it alive after you log out, restarts it if it crashes, and starts it again after a reboot. That's the difference between a toy and something that stays up.

Why does my bot stop when I disconnect?

Because you started it in your SSH session, so it dies when that session ends. Wrap it in a systemd service (or tmux for a quick test) and it runs independently of your login.

Do I need a domain or webhook for a Telegram bot?

No. Long polling (getUpdates) needs no public URL, no domain, no inbound port — the bot reaches out to Telegram. That's why a NAT VPS with no dedicated IP is perfectly fine for a bot. Webhooks are an optional optimization for high volume.

Is it safe to put my bot token on a VPS?

Yes, if you treat it like a password: keep it in an environment variable or a file readable only by the bot's user, never commit it to git, and lock the server down with SSH keys. If a token leaks, revoke it in BotFather and issue a new one.

Comments

No comments yet. Be the first.

Leave a comment

Comments are moderated before they appear.