노트북 덮개를 닫기 전까지 봇은 모든 메시지에 응답합니다. 하지만 덮개를 닫으면 사용자에게 아무 응답도 가지 않습니다. 한 달에 몇 달러인 소형 VPS로 해결할 수 있습니다. Telegram 봇에 가장 적합한 VPS는 업데이트를 받는 방식에 따라 달라집니다. 봇이 Telegram에 요청하거나, Telegram이 봇으로 보내는 방식 중 하나입니다.
이 선택에 따라 필요한 포트와 인증서, 공인 IPv4 연결의 필요 여부가 결정됩니다.
요약
- VPS 하나에서 봇 하나를 실행한다면 롱 폴링을 사용하세요. 도메인, 인증서, 개방된 수신 포트가 필요하지 않습니다.
- 웹훅에는 443, 80, 88 또는 8443 포트의 HTTPS와 공인 IPv4 주소가 필요합니다. Telegram은 IPv6로 웹훅을 전달하지 않습니다.
- 512 MB of RAM is a workable start for one bot with no local database.
- systemd로 봇을 계속 실행하세요. 이미 컨테이너로 배포한다면 Docker 재시작 정책을 사용하세요.
- 표시 가격만 보지 말고 IPv4와 RAM 여유를 기준으로 업체를 선택하세요.
폴링과 웹훅: 서버 요구 사항을 결정하는 선택
Telegram 봇은 두 가지 방법 중 하나로 업데이트를 받습니다. 롱 폴링에서는 봇이 getUpdates를 호출하고 Telegram은 업데이트가 도착하거나 시간이 초과될 때까지 요청을 유지합니다. 따라서 모든 연결은 서버에서 시작됩니다. 웹훅에서는 setWebhook으로 URL을 한 번 등록하면 Telegram이 각 업데이트를 HTTPS POST로 전송합니다.
| 요구사항 | 롱 폴링(getUpdates) |
웹훅(setWebhook) |
|---|---|---|
| 수신 포트 | 없음. 발신 요청만 사용 | 443, 80, 88 또는 8443의 HTTPS |
| 공인 IPv4 | 불필요 | 필요. 웹훅은 IPv6 미지원 |
| 도메인 및 인증서 | 불필요 | 인증서 필요. 일반적으로 도메인을 사용하지만 자체 서명 인증서는 IP를 CN으로 사용 가능 |
| 프로세스 | 계속 실행 | HTTPS 요청에 계속 응답 |
웹훅 열은 Telegram 웹훅 요구 사항을 따릅니다.
봇이 어떤 방식을 사용하는지 확인하려면 Bot API를 조회하세요.
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getWebhookInfo"
응답에 "url":""가 있으면 웹훅이 설정되지 않은 상태이므로 롱 폴링을 사용할 수 있습니다. grammY의 bot.start()는 기본적으로 롱 폴링을 사용합니다. python-telegram-bot은 run_polling() 또는 run_webhook()을 사용합니다.
전용 VPS에서 봇 하나를 실행한다면 저는 폴링을 선택하겠습니다. 이는 grammY의 기본 권장 사항이기도 합니다. 서버에 이미 리버스 프록시(HTTPS 요청을 봇으로 전달하는 웹 서버)가 있거나, 여러 봇이 HTTPS 엔드포인트 하나를 공유하거나, 서버리스 플랫폼을 사용한다면 웹훅이 더 적합합니다. 이 경우 Caddy가 인증서를 발급받고 갱신하므로 cron 작업이 필요하지 않습니다.
짧은 장애는 메시지를 지연시키지만 유실시키지는 않습니다. Bot API 업데이트 규칙에 따르면 어느 방식이든 Telegram은 봇이 수신할 때까지 최대 24시간 업데이트를 보관하며, 포기하기 전에 실패한 웹훅 요청을 재시도합니다.
웹훅이 포트를 직접 독점한다면 해당 포트를 Telegram이 공개한 송신 주소 범위로 제한하세요. 다른 사이트도 서비스하는 리버스 프록시가 443 포트를 공유한다면 웹훅 경로만 제한하거나 Telegram의 비밀 토큰을 활용해 다른 HTTPS 트래픽 전체가 차단되지 않게 하세요. 웹훅 가이드는 두 송신 주소 범위를 제시하며 변경될 수 있다고 경고합니다. 호스트 방화벽으로 UFW를 사용한다면 다음과 같이 설정합니다.
sudo ufw allow 22/tcp # keep SSH open before you enable the firewall
sudo ufw allow proto tcp from 149.154.160.0/20 to any port 443
sudo ufw allow proto tcp from 91.108.4.0/22 to any port 443
sudo ufw allow 80/tcp # if your HTTPS setup uses HTTP validation or redirects HTTP to HTTPS
sudo ufw enable
웹훅이 80, 88 또는 8443에서 수신한다면 443을 변경하세요. 이 규칙은 호스트에서 직접 실행되는 봇을 보호합니다. Docker 방화벽 문서에서는 게시한 포트가 UFW를 우회한다고 설명하므로, -p 443:443으로 시작한 웹훅 컨테이너는 누구에게나 열려 있습니다. 또한 setWebhook에 secret_token을 설정하세요. Telegram은 모든 요청의 X-Telegram-Bot-Api-Secret-Token 헤더로 이 값을 보내며, 핸들러는 이 값이 없는 요청을 거부해야 합니다.
봇을 계속 실행하기: systemd 또는 Docker
Telegram 봇을 연중무휴 실행하려면 충돌과 재부팅 후 다시 시작해야 합니다. VPS에서는 systemd가 이를 처리하며, 봇을 이미지로 배포한다면 Docker를 사용할 수 있습니다.
systemd 유닛은 초기화 시스템에 프로그램 시작 및 재시작 방법을 알려주는 짧은 설정 파일입니다. /etc/systemd/system/telegram-bot.service를 만드세요.
[Unit]
Description=Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
User=bot
WorkingDirectory=/opt/bot
EnvironmentFile=/opt/bot/.env
ExecStart=/opt/bot/venv/bin/python bot.py
# Node: ExecStart=/usr/bin/node bot.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
토큰은 프로젝트 폴더의 .env 파일에 BOT_TOKEN=... 형식으로 저장하고 os.environ["BOT_TOKEN"](Node에서는 process.env.BOT_TOKEN)으로 읽어 코드 밖에 보관하세요. 그런 다음 프로젝트를 지정 위치로 복사하고 시작합니다.
sudo mkdir -p /opt/bot
sudo cp -r ~/your-bot/. /opt/bot/ # your project, after git clone or scp from your machine; include .env and requirements.txt
sudo apt install -y python3-venv # Debian/Ubuntu
sudo useradd --system --no-create-home bot
sudo chown -R bot:bot /opt/bot
sudo -u bot python3 -m venv /opt/bot/venv
sudo -u bot /opt/bot/venv/bin/pip install -r /opt/bot/requirements.txt
# Node: skip the venv and pip commands above, then run:
cd /opt/bot && sudo -u bot npm ci
sudo chmod 600 /opt/bot/.env
sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot
systemctl status telegram-bot # look for: Active: active (running)
sudo journalctl -u telegram-bot -f # follow the bot's logs
systemd.service 매뉴얼에 따르면 Restart=always는 정상 종료나 충돌 모두에서 봇을 재시작하며, on-failure는 정상 종료를 제외합니다. RestartSec=5는 재시도 간격을 두고, WantedBy=multi-user.target과 enable은 부팅 시 봇을 시작합니다. 계속 재시작한다면 sudo journalctl -u telegram-bot -n 50으로 트레이스백을 확인하세요. 먼저 BOT_TOKEN이 누락되지 않았는지 확인하세요.
Docker에서는 플래그 하나로 동일하게 설정합니다.
docker run -d --name telegram-bot --restart unless-stopped --env-file .env your-bot-image
docker logs -f telegram-bot
Compose에서는 restart: unless-stopped를 사용합니다. Docker 재시작 정책 문서에 따르면 컨테이너 종료 또는 데몬 재시작 시에는 다시 실행되지만 직접 중지한 후에는 그렇지 않습니다. Docker 자체가 부팅 시 시작된다면 재부팅에도 적용됩니다. Debian과 Ubuntu에서는 이것이 기본값입니다. 다른 환경에서는 sudo systemctl enable docker.service를 실행하세요.
제 기준은 소형 서버의 스크립트 하나라면 systemd를 써서 추가 데몬의 메모리 사용을 피하는 것입니다. 이미 이미지를 만들거나 다른 컨테이너를 실행한다면 Docker를 사용하고 데몬이 RAM 일부를 차지한다는 점을 감안하세요.
두 도구 모두 봇 중단을 알려주지는 않습니다. 별도 서버의 Uptime Kuma 푸시 모니터가 그 역할을 할 수 있습니다. 봇이 일정 간격으로 모니터 URL을 호출하고, 호출이 멈추면 Uptime Kuma가 Telegram으로 알립니다.
무료 호스팅과 홈 서버의 한계
Render는 15분 동안 수신 트래픽이 없으면 무료 웹 서비스를 정지하며, Render 무료 요금제 문서에 따르면 재가동에는 약 1분이 걸립니다. 폴링 봇은 수신 트래픽이 없어 중지됩니다. 웹훅 봇은 Telegram POST로 깨어나지만 한동안 조용했던 뒤에는 콜드 스타트가 발생합니다. 따라서 Telegram 봇에 무료 호스팅이 적합한지는 사용하는 방식에 달려 있습니다.
grammY 가이드는 서버리스 플랫폼을 웹훅에 적합한 환경으로 제시하는 반면, 롱 폴링에는 상시 가동되는 컴퓨터가 필요합니다. Fly.io는 사용량에 따라 과금하며 카드 등록을 요구합니다.
Raspberry Pi나 오래된 PC도 기기, 전원, 연결이 유지되는 동안 폴링 봇을 실행할 수 있습니다. 집에서 웹훅을 사용하려면 공인 주소와 포트 포워딩도 필요합니다. 취미용 봇에는 두 무료 방식 모두 충분할 수 있습니다.
VPS는 고정 월 요금으로 두 방식 모두 지원합니다.
Telegram 봇용 VPS 업체 5곳 비교
표는 2026년 10월 기준 세전 광고 월 요금으로 Telegram 봇 호스팅용 유료 입문 요금제 5개를 비교합니다. 해당하는 경우 프로모션 가격을 명시했습니다.
| 업체 | 입문 요금제 사양 | 월 요금 | 공인 IPv4 | 청구 |
|---|---|---|---|---|
| Cloudzy | 1 vCPU(AMD EPYC), 512 MB DDR5, 20 GB NVMe, 전송량 1 TB | 프로모션 $2.48(정가 $4.95) | IPv6와 함께 포함 | 시간별 또는 월별 |
| DigitalOcean | 1 vCPU, 512 MiB, 10 GiB SSD, 전송량 500 GiB | $4부터 | 포함 | 초별(월 요금 상한) |
| Vultr | 1 vCPU, 512 MB, 10 GB SSD, 전송량 512 GB | IPv6 전용 $2.50부터, IPv4 포함 $3.50부터 | $3.50 요금제에만 포함 | 시간별 또는 월별 |
| Hetzner(독일/핀란드) | 2 vCPU, 4 GB, 40 GB SSD, 전송량 20 TB | €5.49부터, 부가세 별도 | 추가 €0.50/월부터, 부가세 별도(IPv6 무료) | 시간별, 월 요금이 상한 |
| Linode (Akamai) | 1 vCPU, 1 GB, 저장 공간 25 GB, 전송량 1 TB | $5부터 | 포함 | 시간별 또는 월별 |
Vultr의 IPv6 전용 요금제에는 IPv4가 없으며, Hetzner의 가격에도 IPv4 주소는 제외되어 있습니다. IPv4가 없으면 어느 쪽도 웹훅을 받을 수 없습니다.
api.telegram.org에 IPv6 주소가 있으므로 폴링 봇은 IPv6 전용으로 실행할 수 있습니다. 하지만 패키지 레지스트리, Git 호스트, 호출하는 모든 API를 비롯한 다른 접속 대상도 IPv6 주소가 있어야 합니다. 선택 전에 각 호스트를 확인하세요.
dig +short AAAA api.telegram.org
dig +short AAAA github.com
dig +short AAAA pypi.org # repeat for every host your bot or its installs reach
빈 결과는 해당 호스트에 IPv6 주소가 없다는 뜻입니다.
Telegram 봇에 512 MB면 충분할까요?
로컬 데이터베이스가 없는 봇 하나라면 저는 512 MB로 시작하겠습니다. python-telegram-bot 문서에는 메모리 요구 사항이 없습니다. 운영체제, 사용하는 경우 Docker 데몬, 로컬 데이터베이스 등 같은 서버에 무엇이 있는지에 따라 달라집니다. 직접 측정하세요.
free -m # "available" is your headroom; the Swap row shows swap use
ps -o rss,cmd -p "$(systemctl show -p MainPID --value telegram-bot)" # bot's resident memory, in KB
docker stats --no-stream # per-container memory, if the bot runs in Docker
journalctl -k | grep -i "out of memory" # kernel OOM kills
메모리 부족(OOM) 종료는 커널이 RAM을 확보하려고 프로세스를 끝내는 것입니다. systemd가 봇을 다시 시작하므로 로그 한 줄만 증거로 남을 수 있습니다. OOM 종료가 발생하거나 스왑이 꾸준히 사용되거나, 로컬 데이터베이스나 두 번째 봇을 추가하기 전에는 1 GB로 올리세요.
어떤 요금제를 선택할까
봇 하나라면 공인 IPv4가 포함된 512 MB 요금제를 고르겠습니다. 그다음 가격, 여유 자원, 사용자 위치에 따라 업체를 선택하면 됩니다.
- 현재 최저 월 요금: Cloudzy는 50% 프로모션 중 $2.48이며 IPv4와 IPv6가 포함됩니다.
- 현재 IPv4 포함 최저가: Cloudzy는 프로모션 중 $2.48이며 전용 IPv4와 IPv6가 포함됩니다.
- 1 GB of headroom for Docker or a small database: Linode, from $5 a month.
- 여러 봇이나 데이터베이스를 사용하며 유럽 사용자가 있는 경우: 요금제 재고가 있을 때 이 표에서 유로당 자원이 가장 많은 Hetzner(2026년 10월에는 이용 불가로 표시됨). 웹훅에는 IPv4 비용을 더하세요.
- 512 MB에서 더 많은 디스크와 전송량: Cloudzy. 512 MB 요금제 중 저장 공간(다른 요금제의 10 GB 대비 20 GB NVMe)과 전송량(약 500 GB 대비 1 TB)이 가장 많고 IPv4와 IPv6도 포함됩니다. 현재 프로모션 가격으로는 비교 대상인 다른 입문 요금제보다 저렴합니다.
현재 프로모션 가격에서 Cloudzy는 이 비교의 최저 월 요금과 다른 512 MB 요금제보다 많은 저장 공간 및 전송량을 함께 제공합니다. Cloudzy의 512 MB 요금제는 시간별 과금과 14일 환불 보장을 제공하므로 결정하기 전에 며칠간 봇을 실행해 볼 수 있습니다. 사용자에게 가장 가까운 위치를 고르고 Cloudzy Linux VPS를 배포한 뒤 위의 systemd 유닛을 적용하세요.
자주 묻는 질문
Telegram 봇을 실행할 수 있는 가장 저렴한 VPS는 무엇인가요?
2026년 10월 기준 Cloudzy의 512 MB 요금제가 5곳 중 가장 저렴합니다. 50% 프로모션 중 월 $2.48이며 전용 IPv4와 IPv6가 포함됩니다. 정가는 월 $4.95입니다. Vultr의 IPv6 전용 옵션은 조금 더 높은 $2.50부터 시작합니다.
Telegram 웹훅에 HTTPS가 필요한 이유는 무엇인가요?
RAM 512 MB로 Telegram 봇을 실행할 수 있나요?
로컬 데이터베이스가 없는 봇 하나라면 대체로 가능합니다. 커널 로그에서 메모리 부족 종료를 확인하고, 발생하거나 데이터베이스를 추가할 때 1 GB로 올리세요.
재부팅 후 Telegram 봇을 계속 실행하려면 어떻게 하나요?
sudo systemctl enable --now telegram-bot으로 systemd 서비스를 활성화하거나 --restart unless-stopped로 컨테이너를 실행하고 docker.service를 활성화해 부팅 시 Docker가 시작되게 하세요.
Telegram은 IP 주소별로 봇의 요청 속도를 제한하나요?
Telegram의 봇 제한 FAQ는 봇별, 채팅별 제한을 설명합니다. 서버 이전을 제한 우회 방법으로 생각해서는 안 됩니다. 제한을 넘으면 API는 retry_after 값과 함께 HTTP 429를 반환합니다. 해당 초만큼 기다린 뒤 재시도하세요.
Telegram 봇의 서버 리전은 어디로 골라야 하나요?
사용자와 봇이 호출하는 서비스에 가장 가까운 위치를 고른 뒤, 각 후보에서 curl -o /dev/null -s -w '%{time_connect}\n' https://api.telegram.org으로 연결 시간을 측정하세요.
토론
댓글
토론에 참여하려면 로그인하세요.