aiogram으로 Telegram 봇을 쓰고, 로컬에서 테스트했고, 됩니다. 이제 노트북을 닫아도 잠들지 않는 어딘가에 살아야 합니다. 작은 VPS가 자연스러운 보금자리 — 하지만 SSH 세션의 python bot.py와 크래시, 재부팅, 연결 끊김을 통해 실제로 떠 있는 봇 사이에는 간극이 있습니다.
이것이 프로덕션 버전입니다: virtualenv, 코드 밖에 둔 토큰, 봇을 스스로 되살리는 systemd 서비스, 그리고 누구나 결국 묻는 질문 — polling이냐 webhook이냐? — 에 대한 또렷한 답.
왜 그냥 노트북에서 돌리면 안 되나
봇에는 Telegram으로의 안정적인 아웃바운드 연결이 필요합니다. 노트북은 잠들고, 업데이트로 재부팅하고, 네트워크 사이를 넘나듭니다 — 그 하나하나가 봇을 떨구고, 사용자는 침묵의 벽에 부딪힙니다. VPS는 그 연결을 밤낮없이 유지합니다. 그것이 기기에서 옮기는 전체 이유이고, Discord 봇도 서버에 속하는 것과 같은 이유입니다.
최소한의 봇으로 가능한 한 빠른 "온라인으로" 경로만 원하면, Telegram 봇 호스팅 안내가 그것을 다룹니다. 이 글은 한 단계 깊이 갑니다: aiogram, 안전한 토큰 다루기, 그리고 언제 스케일할지 아는 것.
봇, virtualenv 안에서
SSH로 들어가 봇을 자체 venv 안에 격리하세요 — 패키지를 시스템 전체에 설치하지 마세요, 나중에 업그레이드와 정리가 엉망이 됩니다:
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
토큰을 하드코딩된 문자열이 아니라 환경에서 읽는 최소한의 aiogram 3 봇:
# 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())
토큰을 코드 밖에 두기
BotFather 토큰을 결코 bot.py에 붙여 넣지 마세요 — 공개 리포로 한 번 푸시하면 샙니다. 대신 root가 읽을 수 있는 env 파일에 두세요:
sudo tee /etc/tgbot.env >/dev/null <<'EOF'
BOT_TOKEN=123456:your-token-from-botfather
EOF
sudo chmod 600 /etc/tgbot.env
새어 나간 토큰은 BotFather의 /revoke 하나로 고칠 수 있습니다 — 하지만 공유 기기에서 새어 나간 다른 무엇이든은 더 나쁩니다. 봇 전용 VPS는 솔직히 일상 노트북보다 토큰에게 안전한 보금자리입니다: 새면 토큰 하나를 돌리는 것이지 설정 전체가 아닙니다.
살려 두는 부분: systemd
이것이 도는 봇과 계속 도는 봇을 가릅니다. 서비스를 만드세요:
# /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
비-root 사용자(위의 botuser)로 돌리세요, root가 아니라 — 봇이 침해되어도 상자 안에 가두고 싶으니까요. 그다음:
sudo systemctl daemon-reload
sudo systemctl enable --now tgbot
Restart=always와 RestartSec=3은 크래시 — Telegram의 나쁜 업데이트, 처리되지 않은 예외, OOM — 가 봇을 당신이 알아챌 때까지 죽여 두는 대신 3초 만에 되돌린다는 뜻입니다. 라이브로 보기:
journalctl -u tgbot -f
그것이 당신의 로깅 설정 전부입니다. 돌릴 로그 파일도, 추가 도구도 없음 — journald가 이미 갖고 있습니다.
다운타임 드라마 없이 업데이트하기
코드를 바꾸거나 aiogram을 올릴 때:
cd ~/tgbot && source venv/bin/activate
pip install -U aiogram # 라이브러리를 업그레이드한다면
sudo systemctl restart tgbot
journalctl -u tgbot -n 30 --no-pager # 깨끗이 돌아왔는지 확인
재시작은 봇을 1~2초 깜빡입니다. polling 봇에는 그것이 사용자에게 보이지 않습니다 — Telegram이 업데이트를 큐에 넣고 봇이 재연결하면 전달합니다.
polling 대 webhook — 솔직한 버전
이것이 사람들이 과하게 고민하는 결정입니다. 담백한 버전은 이렇습니다:
polling(start_polling, 위 코드가 쓰는 것)은 장수명 연결에서 봇이 Telegram에 "새 거 있어?"를 묻게 합니다. 아웃바운드 인터넷 말고는 아무것도 필요 없습니다 — 도메인도, TLS도, 열린 인바운드 포트도. NAT 뒤에서 잘 됩니다. 봇의 압도적 다수에게 이것이 옳고, 여기서 멈춰야 합니다.
webhook은 Telegram이 업데이트를 당신에게 밀므로 공개 HTTPS 엔드포인트를 노출해야 합니다. 그것은 도메인과 닿을 수 있는 인바운드 포트가 필요하고 — 즉 전용 공개 IP나 앞단의 리버스 프록시. 설정이 늘고, 깨질 것이 늘어납니다. 보상은 대규모에서의 낮은 지연과 적은 오버헤드 — 수천 동시 사용자, 무거운 업데이트 양.
실용적 규칙: NAT 요금제의 polling으로 시작. webhook으로 옮기는 것은 실제로 polling을 넘어 자랐을 때뿐 — 그리고 그렇다면, 그때야말로 전용 IP가 제자리를 법니다, 그 인바운드 HTTPS 엔드포인트가 필요하니까요.
돌리는 데 드는 비용
polling 봇은 가볍습니다. Telegram의 롱폴에서 유휴 상태로 메시지에 반응하므로 박스는 대체로 기다립니다:
- $3 Nano(2 vCPU / 1 GB) — 대부분의 봇에, 꽤 수다스러운 것도 괜찮음.
- $5 Micro(2 vCPU / 2 GB) — 봇이 데이터베이스(SQLite/Postgres)를 쥐거나, 미디어를 다루거나, 많은 사용자를 서빙할 때.
- 그 이상은 봇 자신이 진짜 일을 할 때뿐 — 이미지 처리, 로컬 모델, 무거운 메시지별 로직.
가입은 이메일만이고 Base나 Ethereum의 USDC나 USDT로 결제합니다 — 카드도 신분증도 없이. 카드도 되지만 온램프에 ~$27 최소액이 있으니, $3 요금제에는 작은 잔액을 한 번 채우고 갱신이 거기서 빠지게 하는 편이 매끄럽습니다. CPU 전용, 독일과 핀란드 두 곳(사용 가능 여부는 주문할 때 표시됩니다) — 봇에는 문제없음, GPU나 특정 지역이 필요했다면 알아둘 가치.
솔직한 결론
Telegram 봇은 자체 호스팅할 수 있는 가장 싼 것 중 하나입니다: $3 박스, systemd 유닛, 그리고 polling이 당신이 지켜보지 않아도 크래시와 재부팅을 통해 온라인인 봇을 줍니다. webhook과 더 큰 요금제로 손을 뻗는 것은 규모가 실제로 강제할 때뿐 — 튜토리얼이 webhook이 "낫다"고 해서가 아니라. 작은 박스를 얻고, 토큰을 env 파일에 두고, systemd에 가동 시간을 맡기고, 그리고 — 무엇보다 먼저 — 새 VPS 보안 체크리스트를 돌려 박스 자체를 잠그세요.
당신 것을 호스팅할 준비가 됐나요? Telegram 봇은 리소스를 거의 안 씁니다 — Nano 요금제(월 $3)가 군더더기 없이 24시간 내내 돌립니다.
댓글
아직 댓글이 없습니다. 첫 번째가 되세요.