← Blog

Como hospedar um bot do Telegram que fica sempre no ar

Railyard

14 de setembro de 2026 · 8 min de leitura

Siga isso no seu próprio servidor. Comece grátis, sem cartão

Um bot do Telegram que só responde enquanto o seu notebook está ligado ainda não é um bot, é um script. A diferença entre os dois é a mesma de qualquer outro serviço sempre ativo: um processo que continua rodando, reinicia se travar, e que fica perguntando ao Telegram se há atualizações ou tem algum endereço público pra onde o Telegram possa mandá-las. Este guia constrói um bot real com python-telegram-bot, passa pela única decisão que realmente importa na hora de hospedá-lo (long polling ou webhook) e cobre o Dockerfile, a política de restart e o caminho de deploy pra mantê-lo no ar.

O que você vai precisar

  • Python 3.10 ou mais recente instalado localmente (o python-telegram-bot 22.x exige isso).
  • Uma conta no Telegram e o @BotFather pra criar o bot e conseguir um token.
  • Docker instalado localmente, pra buildar e testar a imagem.
  • Um servidor pra rodar o container, ou uma conta no Railyard pro atalho da última seção.

Passo 1: criar o bot e conseguir um token

Abra uma conversa com o @BotFather no Telegram, envie /newbot, dê um nome ao bot e escolha um username terminado em bot. O BotFather responde com um token parecido com 123456789:AAFkj2-examplenotrealtoken. Esse token é a credencial completa pra controlar o bot; ele vai numa variável de ambiente, nunca commitado num repositório.

Passo 2: escrever o bot

O python-telegram-bot 22.8 é a versão atual no PyPI. Instale assim:

python -m venv venv
source venv/bin/activate
pip install "python-telegram-bot==22.8"

bot.py:

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)
logger = logging.getLogger(__name__)


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.message.reply_text("Hi. Send me anything and I'll echo it back.")


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


def main() -> None:
    token = os.environ["TELEGRAM_BOT_TOKEN"]
    application = Application.builder().token(token).build()

    application.add_handler(CommandHandler("start", start))
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))

    application.run_polling(allowed_updates=Update.ALL_TYPES)


if __name__ == "__main__":
    main()

Teste localmente:

TELEGRAM_BOT_TOKEN=your-token-here python bot.py

Mande uma mensagem pro bot no Telegram; tanto /start quanto qualquer texto comum devem receber uma resposta em um ou dois segundos.

Passo 3: long polling ou webhook, e por que isso importa pra hospedagem

O application.run_polling() acima é long polling: seu bot pergunta repetidamente aos servidores do Telegram “tem algo novo pra mim?” numa conexão HTTP que o Telegram mantém aberta e responde no instante em que surge uma atualização, e então o bot já pergunta de novo. Nada no seu bot precisa ser acessível pela internet; ele só faz requisições de saída pro Telegram, o mesmo formato da conexão com o gateway do Discord em como hospedar um bot do Discord 24/7. É por isso que long polling é o padrão certo pra “sempre no ar”: basta uma única coisa, um processo que continua rodando e continua perguntando, sem nada pra expor, sem domínio e sem certificado.

A alternativa, um webhook, inverte a direção: você registra uma URL HTTPS pública no Telegram (application.run_webhook(...), escutando numa porta, mais uma chamada pra configurar a URL do webhook do lado do Telegram), e o Telegram empurra cada atualização pra essa URL como um POST HTTP no instante em que ela acontece, em vez do seu bot perguntar. O trade-off, dito sem rodeios: um webhook elimina o ir-e-vir constante do polling e pode ter uma latência um pouco menor, mas não é de fato mais simples de hospedar, é um conjunto diferente de exigências. Ele precisa de um domínio real com certificado TLS válido (o Telegram exige HTTPS pra webhooks; certificado autoassinado só funciona com passos extras que a maioria dos bots pula) e, o ponto crítico, ainda precisa de um processo sempre rodando pra receber as atualizações: um webhook é acionado por HTTP, não é do tipo “recebe a requisição e desliga”, porque se não houver nada escutando na URL registrada no momento em que o Telegram tenta entregar uma atualização, essa atualização simplesmente se perde. “Baseado em HTTP” não quer dizer “funciona numa plataforma que escala a zero” aqui, já que o bot ainda precisa estar de pé no instante exato, e imprevisível, em que o Telegram envia o POST.

Pra quem vai hospedar o próprio bot sem já ter domínio e certificado configurados, long polling é a opção mais simples e igualmente “sempre no ar”, e é em torno dela que este guia é construído. Troque pra webhook mais tarde se o volume de requisições realmente justificar; as funções de handler (start, echo) não mudam de um jeito ou de outro, só a main() muda.

Passo 4: escrever o Dockerfile

FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd --create-home appuser
USER appuser
CMD ["python", "bot.py"]

requirements.txt:

python-telegram-bot==22.8

Assim como no Dockerfile do bot do Discord, não há EXPOSE aqui: long polling só faz conexões de saída, então não há nada que precise aceitar uma conexão de entrada. A imagem roda como um appuser criado, sem ser root, o equivalente em Python à história do usuário node numa imagem Node.

Passo 5: política de restart e logging

docker build -t my-telegram-bot .
docker run -d --name my-telegram-bot --restart unless-stopped \
  -e TELEGRAM_BOT_TOKEN=your-token-here \
  my-telegram-bot

--restart unless-stopped reinicia o container depois de uma falha ou de um reboot do host, sem ninguém precisar entrar via SSH. A chamada logging.basicConfig do Passo 2 manda tudo pra stdout, que o Docker já captura:

docker logs -f my-telegram-bot

Você deve ver as linhas INFO que o próprio python-telegram-bot emite na inicialização (confirmando que ele se conectou à API do Telegram) e uma pra cada /start ou mensagem ecoada.

O atalho: fazer isso com o Railyard

Aponte o Railyard pro mesmo repositório. Um Dockerfile que builda uma imagem autossuficiente (não um que espera um diretório de código montado via bind mount, caso que a detecção de build do Railyard pula automaticamente) builda e roda direto; veja métodos de build. Assim como no bot do Discord, essa é uma aplicação só de worker, sem processo web, que o Railyard roda do mesmo jeito que qualquer outra aplicação, só que sem porta associada; veja workers e tarefas agendadas.

Adicione TELEGRAM_BOT_TOKEN na aba Variables da aplicação; ela é criptografada e aplicada no próximo deploy, substituindo a flag -e do Passo 5. Veja variáveis e secrets. Deixe Sleep when idle (em Settings → General) desligado pra esse processo: uma conversa quieta pode parecer ociosa pra CPU por longos períodos enquanto o bot está no meio de um long poll, esperando a resposta dos servidores do Telegram, e essa espera é justamente o que não pode ser interrompido.

A política de restart do Passo 5 não é uma configuração separada pra fazer, é como o container de qualquer aplicação roda no Railyard por padrão, o mesmo comportamento de “continua a menos que alguém pare explicitamente”. Os logs estão na aba Logs da página da aplicação, ou via railyard logs my-bot --follow pela CLI.

Se você preferir usar o modelo de webhook do Passo 3 em vez de long polling, o HTTPS automático do Railyard (toda aplicação recebe um certificado imediatamente; um domínio personalizado exige um registro de DNS e uma verificação de propriedade; veja domínios e HTTPS) resolve a parte que normalmente torna o webhook a opção mais complicada de auto-hospedar; a aplicação precisaria então de um pequeno processo web ao lado da lógica do bot pra receber os POSTs do Telegram, o que é uma mudança real de arquitetura em relação ao formato só-worker deste guia, não apenas uma opção pra marcar.

Solução de problemas

O bot não responde, mas o container está rodando. Confira primeiro o docker logs em busca de um erro de autorização; um token inválido falha em Application.builder().token(token).build() ou logo depois que o run_polling() começa, e esse erro é quase sempre a primeira coisa no log.

“Conflict: terminated by other getUpdates request.” O Telegram permite só uma conexão de long polling por token de bot ao mesmo tempo. Isso significa que dois processos estão rodando com o mesmo token simultaneamente, geralmente um teste local deixado rodando enquanto o mesmo bot também está em deploy; pare um deles.

O container reinicia em loop. Confira as primeiras linhas do docker logs logo depois de um restart, não o final. Uma variável de ambiente TELEGRAM_BOT_TOKEN ausente (um KeyError em os.environ["TELEGRAM_BOT_TOKEN"]) é a causa mais comum de uma falha imediata num bot recém implantado.

Mensagens enviadas enquanto o bot estava offline nunca chegam. O Telegram realmente enfileira atualizações pra um bot que fica brevemente inacessível e as entrega quando o polling volta, por um tempo limitado, mas um bot que fica fora do ar por um período longo ainda vai perder o que ficar fora dessa janela; essa é uma razão pra tratar “sempre no ar” como o objetivo de fato, e não “geralmente no ar”, e não como uma rede de segurança pra confiar.

Perguntas frequentes

Long polling ou webhook: qual eu devo usar de fato? Long polling, pra maioria dos bots mantidos por uma pessoa ou uma equipe pequena sem domínio e certificado já configurados. Não precisa de nada exposto pra internet. Troque pra webhook só quando o volume de requisições ou a latência justificarem de verdade o domínio, o certificado e a porta de entrada extras.

O python-telegram-bot ou o node-telegram-bot-api importa pra hospedagem? Não, pra nada deste guia. A versão principal atual do node-telegram-bot-api (2.x) é um redesenho da API do zero em relação a versões antigas, mas o formato de hospedagem é idêntico nos dois casos: um processo sempre ativo, um Dockerfile sem porta exposta no caso de long polling, e uma política de restart. O código em Python e em Node é diferente; o que o processo precisa pra continuar vivo não é.

Posso rodar o bot de graça? A biblioteca é grátis; um processo sempre ativo precisa de compute sempre ativo, e um free tier serverless geralmente não é feito pra isso, já que a maioria escala a zero entre requisições. Um VPS pequeno por alguns dólares por mês é o piso realista pra um uptime de verdade contínuo.

O que acontece se duas instâncias do bot rodarem ao mesmo tempo com o mesmo token? A API de long polling do Telegram rejeita explicitamente uma segunda conexão getUpdates concorrente pro mesmo token, com o erro “Conflict” da seção de solução de problemas acima; só uma instância pode manter a conexão de polling por vez, por design, o que também significa que você não consegue escalar horizontalmente um bot de long polling do jeito que escalaria uma aplicação web.

Eu preciso do modo webhook pra rodar muitos bots ou um bot com muitos usuários? Não necessariamente só pelo número de usuários; long polling escala com a quantidade de mensagens que chegam, não com quantos usuários seguem o bot. O modo webhook se torna mais atraente num volume de mensagens genuinamente alto, onde o próprio ir-e-vir do polling passa a ter um overhead relevante, o que é uma barra mais alta do que a maioria dos bots alcança.

Ficar no ar, pra um bot do Telegram, se resume às mesmas duas coisas que pra qualquer outro serviço continuamente em execução: um processo que não para por conta própria, e um que volta quando algo o derruba mesmo assim. Todo o resto, incluindo se você escolhe polling ou webhook, é um detalhe em cima disso.

Por que escolhem o Railyard para isso

  • Sua própria conta de cloud. Faça deploy no DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, ou em qualquer servidor Linux via SSH, cobrado direto pelo seu provedor, sem markup.
  • Um preço fixo por equipe. O Free é grátis para sempre: um servidor mais um servidor de banco de dados, três apps, sem cartão. O Pro custa US$19 por mês para até cinco servidores e apps ilimitados. O Team custa US$49 por mês com servidores ilimitados. Sem cobrança por app, por deploy, por assento ou por gigabyte.
  • Templates de um clique. Faça deploy de apps open source, como bancos de dados, analytics e ferramentas de dev, no seu próprio servidor em um clique.
  • Bancos de dados gerenciados. Postgres, MySQL e Redis com backups programados, verificados por restauração, e recuperação point-in-time.
  • Push-to-deploy. Faça deploy a partir do GitHub, GitLab ou da CLI, com HTTPS automático e releases sem downtime.

Pule a configuração do servidor

Faça o deploy do Dockerfile do seu bot do Telegram no Railyard como um processo worker, já com política de restart e logs configurados.

Plano grátis, sem cartão, e 14 dias de Pro para cada equipe nova. Um preço fixo por equipe.