24시간 텔레그램 봇 호스팅, DashCloud

로컬 컴퓨터 터미널에서 python main.py를 켜두면 텔레그램 봇은 메시지도 잘 받고 답장도 척척 보내요.
문제는 24시간 켜두려고 무료 클라우드에 올리는 순간이에요. 배포가 끝났다고 해서 안심하고 채팅창에 /start를 쳐보면 딱 15분 만에 봇이 메시지를 씹기 시작하거든요.
터미널을 들여다봐도 에러 로그 하나 없이 조용히 멈춰있고, 아무리 명령어를 쳐도 묵묵부답이죠. 1분이 넘게 지난 뒤에야 뒤늦게 답장이 오거나 타임아웃으로 에러가 터지기 일쑤예요.
무료 호스팅에서 텔레그램 봇이 자꾸 잠드는 진짜 이유와, UptimeRobot 핑 우회책 없이 24시간 깨어있는 백그라운드 배포법을 정리했어요.
1. 15분이 지나면 왜 메시지를 씹을까요?
Render나 Heroku 같은 일반적인 무료 클라우드는 웹사이트를 띄우라고 만든 곳이에요.
웹사이트는 방문자가 브라우저 주소창에 주소를 치고 들어올 때 반응하잖아요. 그래서 플랫폼 모니터링 시스템은 15분 동안 밖에서 들어오는 웹 요청이 없으면 서버를 재워버리는 절전 모드 정책을 써요.
하지만 텔레그램 롱폴링 봇은 작동 방식이 정반대예요. 손님이 내 서버를 찾아오는 게 아니라, 내 봇이 텔레그램 공식 API 서버(api.telegram.org)에 "새 메시지 있나요?" 하고 쉬지 않고 물어보는 구조거든요.
외부에서 내 서버로 들어오는 웹 포트가 전혀 필요 없는 셈이죠.
내 봇은 24시간 내내 눈을 부릅뜨고 일하고 있는데, 무료 웹 호스팅 눈에는 "15분 동안 들어오는 웹 트래픽이 0개니까 빈집이네?" 하고 컨테이너를 강제로 재워버리는 거예요.
2. 핑을 쏘거나 가짜 웹 서버를 붙이면 어떻게 될까요?
이 문제를 겪으면 구글에서 UptimeRobot으로 14분마다 핑 쏘기 같은 우회책을 찾아보게 돼요. 봇 코드 옆에 Flask로 가짜 웹 서버를 하나 띄우고 외부에서 억지로 찔러주는 방식이죠.
당장은 돌아가는 것처럼 보여도 얼마 못 가 두 가지 복병을 만나요.
첫째는 메모리 누수예요. 파이썬의 비동기 이벤트 루프와 Flask의 동기 웹 스레드가 한 프로세스 안에서 엉키면서 메모리가 야금야금 차오르거든요. 며칠 지나면 컨테이너가 소리 없이 뻗어버려요.
둘째는 무료 시간의 한계예요. 14분마다 핑을 쏴서 서버를 억지로 깨워두면, 월 750시간 무료 제공량이 20일 만에 바닥나서 월말에 서비스가 통째로 정지돼요.
그렇다고 웹훅으로 바꾸자니 공인 도메인과 HTTPS 443 포트 SSL 인증서, 방화벽까지 세팅해야 하잖아요. 개인 봇 하나 띄우자고 웹 서버 인프라 전체를 짊어져야 하는 셈이에요.
3. 포트 없는 봇에게는 전용 백그라운드 런타임이 필요해요
디스코드를 돌려보신 분들은 익숙하실 거예요. 디스코드 봇도 텔레그램 봇처럼 외부 포트 없이 웹소켓 게이트웨이로 상시 연결되는 백그라운드 프로그램이거든요.
이런 봇들은 애초에 외부 웹 포트를 열지 않는 상시 백그라운드 워커 환경에 올려야 안전해요.
[일반 무료 웹 호스팅]
- 감시 방식: 외부 인바운드 웹 트래픽 감시
- 결과: 15분 동안 웹 요청 없으면 강제 절전 (봇 사망)
[DashCloud 백그라운드 런타임]
- 감시 방식: 프로세스 생존 여부 및 CPU/메모리 헬스체크
- 결과: 외부 트래픽 0개여도 24시간 365일 무중단 가동
DashCloud는 외부 포트 개방 없이 백그라운드에서 계속 돌아가야 하는 텔레그램 봇, 디스코드 봇, 트레이딩 봇, 크롤러를 위해 만들어졌어요.
웹 트래픽이 0개여도 컨테이너가 잠들지 않고, 15분 유휴 제한이나 절전 모드 자체가 없거든요.
4. 코드도 AI에게 "봇 만들어줘" 한마디면 끝나요
파이썬 문법을 깊게 공부하지 않았어도 전혀 걱정할 필요 없어요. Cursor나 ChatGPT, Claude에게 프롬프트 한 줄만 던져주면 되거든요.
"텔레그램 방에서 메시지를 받으면 친절하게 인사하고, /ping 명령어를 입력하면 즉각 pong으로 답장하는 파이썬 롱폴링 봇 코드랑 requirements.txt 만들어줘."
이렇게 물어보면 AI가 실전에 바로 쓸 수 있는 코드와 라이브러리 목록을 10초 만에 완벽하게 짜줘요. 우리는 그 코드를 받아서 파일 두 개로 나눠 담기만 하면 됩니다.
5. 서버에 올릴 파일은 딱 두 개면 충분해요
AI가 건네준 코드를 프로젝트 폴더에 두 개의 파일로 저장해요.
my-telegram-bot/
├── main.py # 봇이 시작되는 코드 파일
└── requirements.txt # 필요한 라이브러리 목록
requirements.txt에는 사용한 패키지만 적어주면 돼요.
python-telegram-bot>=21.0
main.py는 가짜 웹 서버나 복잡한 포트 설정 없이 순수한 롱폴링 루프만 남겨두면 돼요.
import os
import logging
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
logging.basicConfig(level=logging.INFO)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("안녕하세요! DashCloud에서 24시간 깨어있는 봇입니다.")
async def ping(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("pong! 즉각 응답합니다.")
if __name__ == "__main__":
token = os.getenv("TELEGRAM_BOT_TOKEN")
if not token:
raise ValueError("TELEGRAM_BOT_TOKEN 환경변수가 설정되지 않았습니다.")
app = ApplicationBuilder().token(token).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("ping", ping))
# 웹 포트 개방 없이 순수 롱폴링으로 구동
app.run_polling()
6. 코드에 토큰을 그대로 두면 왜 안 될까요?
처음 봇을 만들 땐 main.py 맨 위에 봇 토큰 문자열을 그대로 적어두기 쉬워요.
혼자 내 컴퓨터에서 돌릴 때는 상관없지만, 깃허브나 클라우드에 올리는 순간 얘기가 달라져요. 토큰은 내 봇의 마스터키잖아요. 코드가 인터넷에 공개되면 누구든 내 봇의 권한을 가로챌 수 있거든요.
그래서 토큰은 코드 밖으로 빼서 환경변수에 따로 보관해요. 코드는 os.getenv("TELEGRAM_BOT_TOKEN")으로 열쇠 이름만 부르고, 실제 토큰 값은 DashCloud 대시보드 설정창에 적어두는 거예요.
이렇게 분리해 두면 코드가 어디에 올라가더라도 열쇠는 절대 새어나가지 않아요. 환경변수에 TZ=Asia/Seoul도 함께 넣어두면 서버 로그 시간이 한국 기준으로 맞춰져요.
7. 대시보드에서 백그라운드로 띄우는 순서
파일 준비가 끝났다면 배포는 정말 간단해요.
- 깃허브 개인 저장소에 코드를 올리거나, DashCloud 대시보드에서 프로젝트 폴더를 연결해요.
- 런타임으로 Python 3.12를 선택하고 시작 명령어로
python main.py를 입력해요. - 환경변수 메뉴에서 텔레그램 BotFather에게 발급받은 토큰을
TELEGRAM_BOT_TOKEN으로 등록해요. - 배포 버튼을 눌러요.
서버가 코드를 받으면 requirements.txt에 적힌 패키지를 자동으로 설치하고 프로세스를 띄워요.
[Build] Installing dependencies from requirements.txt...
[Build] python-telegram-bot installed successfully.
[Deploy] Container started (Background Worker mode)
[Runtime] INFO:telegram.ext.Application:Application started
[Runtime] INFO:telegram.ext.Updater:Polling loop started
콘솔에 폴링 루프 로그가 흐르기 시작하면 끝난 거예요. 이제 내 컴퓨터를 끄든 외출을 하든 봇은 24시간 내내 즉각 반응해요.
8. 배포했는데 왜 안 켜질까요? 가장 흔한 원인 3가지
배포 버튼을 눌렀는데 봇이 켜지지 않는다면 대부분 다음 세 가지 중 하나예요.
첫째는 라이브러리 이름 오타예요. requirements.txt에 패키지 이름을 telegram으로 적는 실수가 잦아요. 공식 패키지 이름은 python-telegram-bot이거든요.
둘째는 이전 세션 충돌이에요. 내 노트북 터미널에서 봇을 켠 채로 클라우드에 또 올리면 텔레그램 서버가 충돌 에러(Conflict: terminated by other getUpdates)를 뱉으며 연결을 끊어버려요. 로컬 터미널 프로세스를 먼저 끄고 올려야 충돌이 안 나요.
셋째는 코드에 남아있는 웹 서버 코드예요. Replit이나 다른 웹 예제를 복사해 와서 Flask나 app.run(), PORT 관련 코드가 섞여 있으면 포트 충돌로 무한 대기에 빠질 수 있어요. 웹 서버 코드를 지우고 순수한 run_polling()만 남겨두면 바로 해결돼요.
9. 기간 제한 없이 진짜 평생 무료로 쓸 수 있을까요?
보통 무료 클라우드를 쓰다 보면 '첫 달만 무료'이거나, '오픈베타가 끝나면 유료 구독으로 전환된다'는 함정에 빠지기 쉬워요. 매달 대시보드에 들어가서 무료 연장 버튼을 눌러야 하거나, 가입할 때 신용카드 번호를 요구해서 나중에 몰래 결제될까 봐 불안해지기도 하죠.
DashCloud 공식 홈페이지에서 제공하는 Free 샌드박스는 신용카드 등록 자체가 필요 없고, 오픈베타 연장 신청이나 기간 만료 스트레스 없이 평생 무료로 계속 쓸 수 있어요. 매달 연장 버튼을 누르러 올 필요도 전혀 없습니다.
| 항목 | Free 샌드박스 정책 |
|---|---|
| 메모리 | 256MB RAM |
| 영구 디스크 | 1GB 볼륨 (/app 경로 안전 보존) |
| 월간 트래픽 | 10GB |
| 이용 기간 | 기간 만료 없는 평생 무료 (오픈베타 연장 불필요) |
| 결제 수단 | 신용카드 등록 불필요 |
| 트래픽 초과 시 | 자동 결제 대신 128kbps 감속 유지 |
메시지를 주고받는 텔레그램 봇에게 256MB RAM은 넉넉해요. 10GB 트래픽을 다 쓰더라도 봇이 강제로 꺼지거나 과금되지 않고, 128kbps로 속도만 조절되면서 텍스트 알림은 끊김 없이 계속 처리되거든요.
10. 디스코드와 텔레그램을 함께 쓰는 팀의 팁
디스코드 커뮤니티 서버 운영에 DisHost가 든든한 보금자리라면, 서버 뒤편에서 돌아가는 각종 비상 알림과 모니터링은 DashCloud가 맡아요.
실제로 많은 커뮤니티 운영진이 디스코드 메인 서버가 점검에 들어가거나 장애가 생겼을 때, 관리자들만 모여 있는 비밀 텔레그램 방으로 실시간 알림을 쏴주는 관제 봇을 따로 운영하고 있어요.
디스코드 봇과 텔레그램 봇 모두 외부 웹 포트가 필요 없는 백그라운드 프로세스인 만큼, 안정적인 상시 런타임에 올려두면 관리 부담이 확 줄어듭니다.
포트 없는 봇에는 그에 맞는 가벼운 상시 런타임이 정답이에요. 지금 DashCloud 무료 콘솔에서 1분 만에 24시간 봇을 띄워보세요.