바이브코딩2026-10-15·8분 읽기

Cursor로 봇 만들었는데 노트북 닫으면 끝일까요? 터미널 없이 24시간 띄우는 법

내 컴퓨터에선 잘 돌아가던 봇을 24시간 꺼지지 않는 클라우드로 옮기는 법. 복잡한 서버 설정 없이 파일 업로드와 토큰 등록만으로 백그라운드 배포를 끝내는 과정을 정리했어요.

Cursor로 봇 만들었는데 노트북 닫으면 끝일까요? 터미널 없이 24시간 띄우는 법

Cursor나 ChatGPT로 텔레그램이나 디스코드 봇을 만들었어요. 터미널에서 python main.py를 실행하고 메시지를 보내보면 답장도 잘 오죠.

문제는 노트북 화면을 덮는 순간이에요. 화면을 닫으면 실행 중이던 프로세스가 죽고, 봇도 그 자리에서 멈추거든요.

집에 남는 컴퓨터를 24시간 켜두자니 소음과 전기세가 걸리고, 그렇다고 AWS EC2나 Docker, 리눅스 명령어(nohup, systemctl)를 공부하자니 봇 하나 띄우기에 너무 먼 길을 돌아가는 느낌이 들잖아요.

필요한 건 거창한 인프라가 아니에요. 내가 짠 코드만 클라우드에 올려두고, 터미널 없이 24시간 꺼지지 않게 돌리는 일이죠.

내 컴퓨터에서 돌던 봇을 클라우드 백그라운드로 옮길 때 꼭 알아야 할 핵심을 차분히 짚어봤어요.

1. 24시간 켜둔다는 건 무슨 뜻일까요?

디스코드 개발자 포털이나 텔레그램 BotFather에서 봇을 등록한 건, 이름표와 열쇠(API 토큰)를 발급받은 상태예요. 실제로 메시지를 읽고 답장하는 코드는 아직 서버 어디에도 없거든요.

봇은 컴퓨터 어딘가에서 파이썬 프로그램이 계속 실행되고 있어야만 살아요. 내 노트북에서 실행하면 내 컴퓨터의 CPU와 메모리를 쓰는 거고, 화면을 닫으면 그 프로그램도 함께 꺼지는 식이죠.

클라우드 호스팅은 단순해요. 내 노트북 대신 24시간 켜져 있는 데이터센터 컴퓨터를 빌려 그 프로그램을 대신 돌려두는 일이에요.

SSH 접속을 하거나 복잡한 리눅스 명령어를 외울 필요는 없어요. 프로젝트 폴더를 올리고 토큰만 입력하면, 서버가 알아서 백그라운드 프로세스로 띄워주거든요.

2. 서버에 올릴 파일은 딱 두 개면 충분해요

프로젝트 폴더를 열어보면 파일이 많아 보이지만, 서버가 봇을 실행하는 데 필요한 파일은 사실 두 개뿐이에요.

my-bot/
├── main.py            # 봇이 시작되는 코드 파일
└── requirements.txt   # 필요한 라이브러리 목록

내 노트북에는 패키지가 이미 깔려 있어서 잘 돌았지만, 새 서버 컴퓨터는 어떤 라이브러리가 필요한지 모르거든요. requirements.txt가 빠지면 패키지를 찾지 못해 ModuleNotFoundError를 내며 바로 꺼져요.

작업하던 터미널에서 명령어 한 줄만 치면 바로 만들어져요.

pip freeze > requirements.txt

Node.js 프로젝트라면 package.json과 index.js가 같은 역할을 해요.

여기서 주의할 점이 하나 있어요. node_modules나 .venv, .git 폴더는 절대 같이 올리지 않는 게 좋아요. 용량만 클 뿐더러, 서버가 requirements.txt나 package.json을 읽고 알아서 깨끗하게 설치해 주거든요.

3. 코드에 토큰을 그대로 두면 왜 안 될까요?

처음 봇 코드를 짤 때는 코드 맨 위에 토큰을 그대로 적어두기 쉬워요.

# 위험한 형태: 코드에 토큰이 그대로 노출됨
BOT_TOKEN = "7123456789:AAF..."
bot = TeleBot(BOT_TOKEN)

혼자 내 컴퓨터에서 돌릴 때는 아무 문제 없거든요.
하지만 이 코드를 깃허브나 서버에 올리는 순간 얘기가 달라져요. 토큰은 내 봇의 마스터키잖아요. 문자열이 코드에 박힌 채로 인터넷에 올라가면, 누구든 내 봇의 권한을 그대로 가로챌 수 있거든요.

그래서 토큰은 코드 밖으로 빼서 '환경변수'에 따로 보관해요.

# 안전한 형태: 시스템 환경변수에서 읽어옴
import os
 
BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
bot = TeleBot(BOT_TOKEN)

코드는 "시스템에 등록된 TELEGRAM_BOT_TOKEN을 가져와 줘"라고 이름만 부르고, 진짜 토큰 값은 대시보드 설정창에 적어두는 거예요.
이렇게 분리해 두면 코드가 어디에 공개되더라도 열쇠는 새어나가지 않아요.

TELEGRAM_BOT_TOKEN=7123456789:AAF...
TZ=Asia/Seoul

환경변수에 TZ=Asia/Seoul도 함께 넣어두면 서버 로그 시간과 정기 예약 스케줄이 한국 시간 기준으로 딱 맞춰져요.

4. 대시보드에서 백그라운드로 띄우는 순서

파일 준비가 끝났다면 배포는 정말 간단해요.

  1. DashCloud 대시보드에서 프로젝트 폴더를 끌어다 놓거나 ZIP 파일로 올려요.
  2. 환경변수 탭에서 코드에 적어둔 변수 이름(TELEGRAM_BOT_TOKEN)과 토큰 값을 등록해요.
  3. 배포 버튼을 눌러요.

서버가 코드를 받으면 requirements.txt에 적힌 패키지를 자동으로 설치하고, main.py를 백그라운드 프로세스로 띄워요.

콘솔 탭을 열었을 때 초기화 로그가 실시간으로 흐르기 시작하면 성공이에요. 이제 노트북 화면을 덮든 Cursor를 완전히 끄든 봇은 클라우드에서 24시간 계속 돌아가거든요.

5. 배포했는데 왜 안 켜질까요? 가장 흔한 원인 4가지

배포 버튼을 눌렀는데 봇이 시작되지 않는다면 대부분 다음 네 가지 중 하나예요.

1. ModuleNotFoundError: No module named '...'

가장 흔해요. 내 컴퓨터엔 깔려 있던 패키지가 requirements.txt에 빠진 경우예요. 로컬 터미널에서 pip freeze > requirements.txt를 다시 실행해 목록을 최신으로 갱신하고 프로젝트를 다시 올리면 바로 해결돼요.

2. 401 Unauthorized 또는 Improper token

토큰 인증 실패예요. 파이썬 코드의 os.getenv("TELEGRAM_BOT_TOKEN") 변수 이름과 대시보드에 입력한 환경변수 이름이 한 글자라도 다르면 토큰을 읽지 못하거든요. 대시보드에 값을 넣을 때 앞뒤에 빈칸이나 따옴표("...")가 섞여 들어가지 않았는지도 확인해 봐야 해요.

3. Conflict: terminated by other getUpdates

같은 봇 토큰으로 두 곳 이상에서 동시에 메시지를 받으려 할 때 텔레그램이 뱉는 에러예요. 내 노트북 터미널에서 켜두었던 파이썬 프로세스가 아직 백그라운드에 살아있을 가능성이 높아요. 로컬 터미널 프로세스를 완전히 종료하면 바로 정상 동작해요.

4. Address already in use 또는 무한 대기

Replit 예제를 참고했거나 AI에게 작성을 부탁했을 때, 코드에 Flask나 FastAPI 같은 웹 서버 코드가 끼어 있는 경우가 있어요.

텔레그램 롱폴링과 디스코드 봇은 외부에서 들어오는 웹 포트가 전혀 필요 없거든요. 봇이 외부 서버로 직접 요청을 보내 메시지를 가져오는 구조니까요.

코드에서 Flask, app.run(), PORT 관련 줄을 지우고 순수한 폴링 루프만 남겨주면 말끔히 해결돼요.

# 수정 후: 웹 서버 없이 롱폴링만 남김
if __name__ == "__main__":
    bot.polling(none_stop=True)

6. 자고 일어났더니 봇이 꺼져 있으면 어떡하죠?

봇을 24시간 돌릴 때 가장 곤란한 순간은 자고 일어났더니 새벽에 봇이 조용히 멈춰있을 때예요. 안정적인 가동을 위해 세 가지만 챙겨두면 돼요.

첫째는 자동 재시작 기능이에요. 네트워크가 잠깐 끊기거나 일시적인 오류로 프로세스가 꺼져도, 플랫폼 데몬이 감지해서 알아서 다시 띄워주거든요.

둘째는 실시간 로그 스트리밍이에요. 대시보드 콘솔 탭에서 메시지가 오갈 때마다 로그가 실시간으로 찍히는지 확인해요. 계속 멈춰 있다면 로그의 마지막 줄 에러를 보면 바로 답이 나와요.

셋째는 장애 알림 웹훅이에요. 혹시라도 치명적인 버그로 프로세스가 완전히 멈추면 내 스마트폰 텔레그램이나 디스코드로 즉시 알림이 오도록 웹훅을 걸어둘 수 있어요.

7. 다시 배포하면 그동안 쌓인 데이터는 날아갈까요?

봇이 유저 상태나 처리 내역을 파일(SQLite, JSON, 텍스트)로 저장하고 있다면 저장 위치가 중요해요.

데이터 파일은 반드시 프로젝트 폴더 안(/app 하위 경로)에 두어야 해요. 이 영역은 1GB 영구 볼륨 디스크에 연결되어 있어서, 컨테이너가 재시작되거나 코드를 고쳐 새로 배포해도 파일이 그대로 남거든요.

반대로 /tmp 같은 임시 시스템 경로에 저장하면 컨테이너가 다시 만들어질 때 데이터가 다 사라져버려요. SQLite를 쓸 때는 파일 경로를 data/bot.db처럼 프로젝트 기준 상대경로로 지정하는 편이 안전해요.

8. 무료 플랜으로 24시간 돌려도 진짜 돈이 안 나갈까요?

많은 무료 호스팅 서비스는 15분 동안 외부 웹 요청이 없으면 서버를 강제로 잠재워버려요. 웹 트래픽을 직접 받지 않는 백그라운드 봇이 무료 호스팅에서 자꾸 꺼지던 이유가 바로 이것 때문이거든요.

DashCloud Free 샌드박스는 절전 모드로 들어가지 않고 24시간 상시 가동을 유지해요.

항목Free 샌드박스 (오픈베타)
메모리256MB RAM
디스크1GB 영구 볼륨
트래픽월 10GB
가동 시간24시간 연속 가동 (절전 모드 없음)
비용오픈베타 기간 무료 (신용카드 등록 불필요)
트래픽 초과 시자동 종료나 결제 대신 128kbps 감속 (텍스트 봇 정상 가동 유지)

256MB RAM은 메시지를 주고받는 텔레그램이나 디스코드 봇을 돌리기에 충분히 넉넉해요. 10GB 트래픽을 다 쓰더라도 결제창이 뜨거나 프로세스가 꺼지지 않고, 128kbps로 속도만 줄어들어 텍스트 봇은 중단 없이 계속 돌아가거든요.

9. 자주 묻는 질문

코드를 고쳤을 때는 어떻게 다시 올리나요?
수정한 폴더나 압축 파일을 대시보드에 다시 업로드하고 재배포 버튼을 누르면 끝나요. requirements.txt에 새 패키지가 추가되었다면 서버가 알아서 추가 설치하고, 기존에 쌓인 DB 파일도 안전하게 유지되거든요.

Cursor 안에서 대화하듯 바로 배포할 수도 있나요?
네, 가능해요. DashCloud MCP 서버를 연동해 두면 에디터 채팅창에서 "지금 작업 중인 봇 배포해줘"라고 말하는 것만으로 배포가 끝나요. 자세한 설정법은 Cursor MCP 연동 가이드에 정리해 두었어요.

Node.js로 만든 봇도 지원하나요?
지원해요. 프로젝트 폴더 안에 package.json이 들어 있으면 Node.js 런타임으로 감지해 의존성을 설치하고 실행해 주거든요.


배포 절차는 빠른 시작 가이드에서 확인할 수 있어요.

DashCloud는 오픈베타 기간 동안 신용카드 등록 없이 무료로 제공돼요. GitHub 또는 Discord 계정 로그인 후 휴대폰 인증 1회를 마치면 지금 바로 무료 샌드박스를 띄울 수 있어요.