Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
World desk12 min

How to Run a Python Telegram Bot on a Linux VPS

A practical, security-first guide to deploying a Python Telegram bot on a Linux VPS, from BotFather and SSH hardening to polling, systemd supervision, webhook migration, and troubleshooting.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The dependable way to run a Python Telegram bot on a Linux VPS is to create the bot with Telegram’s @BotFather, place the code in a Python virtual environment, read the token from a protected environment file, and run the process under systemd. Start with long polling because it needs no public HTTPS endpoint. Use a webhook only when you already have a public domain, TLS, and a reverse-proxy or web-server setup.

This guide takes you from an empty VPS to a bot that survives SSH disconnects, process failures, and reboots, then explains the security and migration details that commonly break deployments.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the deployment actually does

A Telegram bot is a program that sends HTTPS requests to the Telegram Bot API and waits for JSON responses. Your VPS supplies the always-on computer that runs the Python process; Telegram supplies the messaging network and update delivery.

With long polling, your VPS repeatedly asks Telegram for new updates through the getUpdates mechanism. With a webhook, Telegram makes HTTPS requests to an endpoint that you expose. Both methods deliver the same kinds of updates, but they have different network and security requirements.

#1 Best Overall
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
  • [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
  • [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
  • [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
  • [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.

The finished polling architecture looks like this:

  • Telegram stores the bot account and its token.
  • The VPS runs Linux, Python, your bot code, and its installed dependencies.
  • A non-root service account owns the application.
  • systemd starts the bot, restarts it after a failure, and starts it after a reboot.
  • The token lives in an environment file that is not committed to Git.

Only one update-delivery method should be active for a bot at a time. A process using polling cannot retrieve updates while an outgoing webhook is configured for that same bot.

Choose the update method before you deploy

Aspect Long polling Webhook
Network direction The VPS makes outbound requests to Telegram for updates. Telegram sends updates to a public URL on the VPS or to a reverse proxy.
Setup burden Lowest; no inbound TLS endpoint is required. Higher; you need a public endpoint, HTTPS, routing, and secret-token validation.
Best fit Small to medium bots, prototypes, and straightforward VPS services. Deployments that already operate HTTPS infrastructure or specifically need push delivery.
Important constraint Do not leave an outgoing webhook configured at the same time. Do not run long polling at the same time for the same bot.

For a first VPS deployment, polling removes an entire class of certificate, firewall, reverse-proxy, and DNS problems. You can migrate to a webhook later, but the migration must deliberately switch off the previous transport.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create the bot and protect its token

  1. Open Telegram and start a chat with @BotFather.
  2. Use the bot-creation command and follow the prompts for a display name and username.
  3. Copy the token that BotFather returns and store it in a password manager or another private location.
  4. Do not paste the token into a public repository, issue, screenshot, shell transcript, or chat. Anyone who obtains it can operate the bot through the API.

The Bot API is JSON over HTTPS. Your Python library uses the token to authenticate every request, so the token should be treated like a production password. If it is exposed, revoke or rotate it through BotFather immediately and restart the service with the replacement value.

Provision a Linux VPS safely

Use a publicly reachable Linux VPS with enough memory and CPU for your bot and any database or auxiliary service it needs. The exact size depends on your workload; the deployment pattern is the same for a small command bot and a larger application.

Log in with an SSH key

Create an SSH key pair on your workstation and add the public key to the VPS during provisioning. The Python Telegram Bot hosting guidance recommends SSH public-key authentication rather than relying on a password. After confirming key-based access, disable password authentication if your provider’s recovery process allows it.

Create a non-root deployment account

Use the provider’s console or an initial administrative login to create a dedicated account, then grant it only the administrative privileges needed for maintenance. The bot itself should run as a separate, least-privileged service account. This limits the damage if a dependency or handler is compromised.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo adduser --disabled-password --gecos "" telegrambot
sudo mkdir -p /opt/telegram-bot
sudo chown telegrambot:telegrambot /opt/telegram-bot

On distributions that use a separate administrator group, add your maintenance user to that group and use sudo for system changes. Do not run the bot as root simply because the initial SSH user is root.

Update the operating system

Apply the current security updates before installing the application. On Debian- or Ubuntu-family systems:

Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
  • 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
  • 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
  • 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
  • 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.
sudo apt update
sudo apt full-upgrade

Reboot if the package manager installs a kernel or other component that requires it, then reconnect over SSH using the key.

Create an isolated Python application

Keeping the bot in a virtual environment prevents its packages from colliding with the operating system’s Python packages or with another application on the same VPS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Switch to the service account or keep ownership aligned with it while creating the files.
  2. Create the application directory and virtual environment.
  3. Activate the environment for interactive installation.
  4. Install a current python-telegram-bot release, then record the exact installed version in a requirements file so later upgrades are deliberate.
sudo -u telegrambot -H bash
cd /opt/telegram-bot
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install python-telegram-bot
python -m pip freeze > requirements.txt

The final requirements.txt should contain the exact version selected for production. Review release notes and test upgrades before changing that line. When you deploy from a repository, install with python -m pip install -r requirements.txt inside the virtual environment rather than resolving unpinned dependencies on every restart.

Keep secrets outside the repository

Create a root-owned directory for service configuration and give the service account read access to the specific file:

sudo install -d -m 750 -o root -g telegrambot /etc/telegram-bot
sudo install -m 640 -o root -g telegrambot /dev/null /etc/telegram-bot/bot.env
sudoedit /etc/telegram-bot/bot.env

Put only the token and other private settings in that file:

TELEGRAM_BOT_TOKEN=put_the_value_from_botfather_here

Use a Git ignore rule for local copies such as .env, and never commit /etc/telegram-bot/bot.env. The systemd unit below reads the protected file directly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Write a minimal bot

Create /opt/telegram-bot/bot.py. This example has a /start command and a text handler, and reads the token from the process environment rather than embedding it in source code.

import logging
import os

from telegram import Update
from telegram.ext import (
    Application,
    CommandHandler,
    ContextTypes,
    MessageHandler,
    filters,
)

logging.basicConfig(
    format="%(asctime)s %(name)s %(levelname)s %(message)s",
    level=logging.INFO,
)

TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    if update.effective_message:
        await update.effective_message.reply_text(
            "Hello. Send me a message and I will repeat it."
        )

async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    if update.effective_message and update.effective_message.text:
        await update.effective_message.reply_text(update.effective_message.text)

def main() -> None:
    application = Application.builder().token(TOKEN).build()
    application.add_handler(CommandHandler("start", start))
    application.add_handler(
        MessageHandler(filters.TEXT & ~filters.COMMAND, echo)
    )
    application.run_polling()

if __name__ == "__main__":
    main()

The handlers are asynchronous, while run_polling() manages the updater and event loop for you. This is the simplest first deployment because it does not require you to expose an HTTP listener to the Internet.

Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord
  • [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
  • [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
  • [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
  • [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
  • [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by

Test polling before adding a supervisor

Run the bot manually once. This separates application errors from service-manager errors.

cd /opt/telegram-bot
source .venv/bin/activate
export TELEGRAM_BOT_TOKEN='the_private_token_for_this_bot'
python bot.py

Open the bot in Telegram, send /start, and then send ordinary text. The process should stay attached to the terminal while it receives updates. Stop it with Ctrl-C after confirming both handlers work.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

On the VPS, an exported shell variable is suitable for a quick test but not for production. The systemd unit will supply the protected environment file consistently on every start.

Run the bot with systemd

systemd is a suitable supervisor on most modern Linux VPS distributions. It starts the process after networking is available, restarts it after an unexpected exit, and provides logs through the journal.

Create the service unit

Create /etc/systemd/system/telegram-bot.service as root:

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

[Service]
Type=simple
User=telegrambot
Group=telegrambot
WorkingDirectory=/opt/telegram-bot
EnvironmentFile=/etc/telegram-bot/bot.env
ExecStart=/opt/telegram-bot/.venv/bin/python /opt/telegram-bot/bot.py
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Using the virtual environment’s absolute Python path is important: systemd does not load your interactive shell’s activation scripts. The working directory ensures relative paths behave predictably, and Restart=on-failure handles crashes without creating a rapid restart loop.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Load, start, and enable it

sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot.service
sudo systemctl status telegram-bot.service

The status should show active (running). Confirm that the bot responds in Telegram, then verify it survives a reboot during a maintenance window:

sudo reboot

After reconnecting, check the service again. Because it is enabled, systemd should start it automatically.

Rank #4
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
  • Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
  • All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
  • Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
  • Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.

Read the logs

sudo journalctl -u telegram-bot.service -n 100 --no-pager
sudo journalctl -u telegram-bot.service -f

The first command prints recent entries; the second follows new entries while you reproduce a problem. Do not log the token or private user data from handlers. Journal retention and rotation should follow your distribution’s normal policy.

Polling details and common conflicts

Long polling is not the same as a busy loop that hammers the API. The library manages the repeated getUpdates requests and waits for responses. Keep a single polling process for the bot; two simultaneous pollers can compete for updates and produce conflicts.

If polling reports a conflict or receives no updates after a webhook deployment, inspect the bot’s configured update method. Telegram’s FAQ states that long polling cannot retrieve updates while an outgoing webhook is set. Remove the webhook before starting polling, and decide whether pending updates should be retained or deliberately discarded during the changeover.

Do not start a second copy from an SSH shell after systemd is already running. Check first:

sudo systemctl status telegram-bot.service
pgrep -af '/opt/telegram-bot/.venv/bin/python'
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When a webhook is the better choice

A webhook is appropriate when you already operate a public HTTPS service, need Telegram to push updates to your infrastructure, or want to integrate the bot into an existing reverse-proxy layout. It is not a shortcut around TLS: Telegram must be able to reach your endpoint, and the endpoint must use HTTPS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You need all of the following:

  • A public IP address or DNS name that resolves to the VPS.
  • An HTTPS certificate that clients can validate.
  • Firewall and reverse-proxy rules that route the webhook path to the Python application.
  • The webhook extra dependency for the version of python-telegram-bot you selected.
  • A secret token that the library checks in the X-Telegram-Bot-Api-Secret-Token request header.

Install the library’s optional webhook dependency in the same virtual environment, keep the resulting version pinned, and test the complete HTTPS path before switching production traffic.

Use a hard-to-guess path and the secret header

Choose a webhook path that is not an obvious /telegram or /bot endpoint. Treat the path as an additional filter, not as authentication. Configure a random secret token and pass the same value to the library’s webhook runner. The current updater documentation says requests with a missing or incorrect X-Telegram-Bot-Api-Secret-Token header receive HTTP 403. Keep the secret in the environment file, not in source code or a proxy configuration committed to Git.

Adapt the application for webhook mode

The handlers can remain unchanged. Replace the polling startup with the library’s webhook runner and provide the listen address, port, URL path, public webhook URL, and secret token expected by your chosen deployment. If TLS terminates at a reverse proxy, bind the Python listener to the private interface or loopback address and let the proxy handle the public certificate and forwarding.

The exact runner arguments depend on the library release, so verify them against the installed version’s updater documentation before deploying. This is one reason to record and review the package version rather than silently upgrading it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Switch safely between polling and webhook

  1. Stop the current systemd service so the old updater is no longer making requests.
  2. Change Telegram’s update configuration: remove the outgoing webhook before polling, or set the webhook before starting the webhook service.
  3. Decide whether to preserve pending updates. Telegram’s API supports an explicit drop-pending-updates choice; use it only when losing queued messages is acceptable.
  4. Start exactly one transport and inspect its logs.
  5. Send a test message and confirm that it arrives once.

During migration, avoid leaving an old VPS, a local development process, and the new service active simultaneously. Duplicate consumers make it difficult to tell whether a missing message is a code problem or an update-delivery conflict.

Security and reliability checklist

  • Token handling: keep the BotFather token in an environment file or secret store, restrict file permissions, and rotate it immediately if exposed.
  • Account isolation: use SSH keys, a non-root maintenance user, and a separate least-privileged service account.
  • Dependency control: pin the installed library and its transitive dependencies, review upgrades, and confirm the installed version before using version-specific APIs.
  • Transport choice: operate one update method at a time and document whether pending updates are retained during a migration.
  • Webhook protection: require HTTPS, use a hard-to-guess path, and validate the X-Telegram-Bot-Api-Secret-Token header.
  • Process supervision: use a restart policy, enable the service at boot, and inspect the journal after every deployment.
  • Minimal permissions: keep application files writable only where the bot needs to write, and avoid giving the service account shell or administrative privileges.

Troubleshooting by symptom

The service exits immediately

Run sudo journalctl -u telegram-bot.service -n 100. A missing TELEGRAM_BOT_TOKEN usually means the environment file path, ownership, or syntax is wrong. A module-import error means the unit is using a different Python interpreter than the one where you installed the package; compare ExecStart with the virtual environment path.

The bot works in a shell but not under systemd

Interactive shells provide a current directory, activated virtual environment, and exported variables that systemd does not. Use absolute paths in ExecStart, set WorkingDirectory, and place required variables in EnvironmentFile. Restart the unit after editing the file.

Telegram messages never reach the bot

Confirm that the service is running, that the token belongs to the intended bot, and that no webhook remains configured while polling. Check the journal for API errors and make sure only one polling process exists.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Webhook requests return 403

A 403 from the updater indicates that the secret header is absent or does not match the configured secret token. Check the reverse proxy’s header forwarding, the environment value consumed by the Python process, and the exact header name: X-Telegram-Bot-Api-Secret-Token.

The webhook is unreachable

Verify DNS, the public firewall, the certificate chain, and reverse-proxy routing from outside the VPS. Telegram must be able to establish a valid HTTPS connection to the public URL; a listener bound only to an inaccessible private address cannot receive updates directly.

The bot stopped after a reboot

Check that the unit is enabled, not merely started once, with systemctl is-enabled telegram-bot.service. Then inspect the boot-time journal for a bad environment path, a missing virtual environment, or a dependency that was removed during an OS update.

Routine maintenance

After the first successful deployment, treat the VPS as a small production service. Keep the operating system patched, review dependency releases before upgrading, and test the bot after each change. When updating, stop or restart through systemd rather than launching an extra copy from SSH. Check the status and recent journal entries, then send a real Telegram message to verify the complete path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If the token ever appears in a log, repository, or public support request, rotate it through BotFather, update the protected environment file, restrict its permissions again, and restart the service. For webhook deployments, review certificate renewal and reverse-proxy configuration as part of the same maintenance schedule.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.