서버에서 Telegram 봇: 실행과 자동 시작
VPS에서 Telegram 봇을 호스팅하는 방법: 자체 사용자로 격리, systemd 서비스, 토큰 보관, 로그, 네트워크 장애 대응을 다뤄요.
업데이트 2026년 8월 23일
봇에는 항상 실행되는 프로세스가 필요해요. 바로 여기서 무료 호스팅이 끝나고 VDS가 시작돼요. 봇은 리소스를 거의 쓰지 않아요. VDS-1(1코어, 2GB)만으로도 수천 명의 사용자가 있는 봇을 감당할 수 있어요.
배치
봇이 root로 실행되지 않도록 별도의 사용자와 디렉터리를 만들어요:
useradd -r -m -d /srv/bot -s /usr/sbin/nologin botuser
cd /srv/bot && sudo -u botuser git clone https://github.com/you/bot.git .
sudo -u botuser python3 -m venv venv
sudo -u botuser venv/bin/pip install -r requirements.txt
Node.js라면 venv 대신 npm ci --omit=dev를 사용해요.
토큰은 코드가 아니라 환경 파일에 보관해요:
install -o botuser -g botuser -m 600 /dev/null /srv/bot/.env
echo 'BOT_TOKEN=123456:ABC...' > /srv/bot/.env
토큰이 담긴 파일은 저장소에 올라가면 안 돼요. 첫 커밋 전에 .gitignore에 추가하세요.
서비스
/etc/systemd/system/tgbot.service:
[Unit]
Description=Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
User=botuser
WorkingDirectory=/srv/bot
EnvironmentFile=/srv/bot/.env
ExecStart=/srv/bot/venv/bin/python -u bot.py
Restart=always
RestartSec=10
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now tgbot
journalctl -u tgbot -f
Python의 -u 플래그는 출력 버퍼링을 꺼요. 이게 없으면 로그가 journal에 몇 분 늦게 나타나거나 아예 나타나지 않아요.
롱 폴링 또는 웹훅
롱 폴링이 더 간단해요. 봇이 Telegram에 직접 요청하고, 외부에 아무것도 노출할 필요가 없어요. 대부분의 작업에는 이걸로 충분해요.
웹훅은 더 빠르고 트래픽도 적게 쓰지만, 도메인과 인증서가 필요해요:
location /bot/token {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
Let's Encrypt와 리버스 프록시가 필요해요. Telegram은 자체 서명 인증서를 잘 받아주지 않으니 일반 인증서를 사용하세요.
봇의 복사본 두 개가 동시에 실행되면 절대 안 돼요. Telegram은 업데이트를 한 수신자에게만 전달하기 때문에 봇이 간헐적으로 응답하게 돼요. 수정한 뒤에는 두 번째 실행이 아니라 restart를 하세요.
데이터
설정과 통계에는 SQLite면 충분해요. 봇 옆에 파일 하나만 두면 돼요. 별도의 데이터베이스 서버는 봇에 웹 패널이 있거나 프로세스가 여러 개일 때만 필요해요.
흔한 실수
| 증상 | 원인 |
|---|---|
Conflict: terminated by other getUpdates | 봇의 복사본 두 개가 실행 중임 |
| 밤이 지나면 봇이 조용해짐 | Restart=always가 설정되지 않아 네트워크 끊김에 프로세스가 죽음 |
Unauthorized | 토큰이 폐기되었거나 공백이 섞여 복사됨 |
| 로그가 없음 | 출력 버퍼링, 또는 stdout 대신 파일에 기록함 |
| 수동으로는 작동하지만 서비스로는 죽음 | systemd에 환경 변수가 없음 |
스크린샷, 공개 저장소, 남의 채팅에 노출된 토큰은 유출된 것으로 간주해요. BotFather에서 폐기하고
.env파일을 바꾸세요. 아무도 눈치채지 못할 거라고 기대하면 안 돼요.