PC를 24시간 켜두던 습관, GitHub Actions 하나로 끊었다
자동화 스크립트를 매일 정해진 시간에 돌리려면 서버가 필요하다. 처음엔 집 PC를 24시간 켜뒀다. 전기세가 신경 쓰였다. 그 다음엔 월 5달러짜리 VPS를 빌렸다. 리눅스 크론잡 문법이 헷갈려서 설정할 때마다 구글을 뒤졌다. “이것보다 쉬운 방법이 없나” 싶던 차에 GitHub Actions를 제대로 파기 시작했다.
결론부터 말하면, 월 2,000분 이내 실행은 완전 무료다. 파이썬 스크립트를 깃허브 레포에 올리고 워크플로우 파일 하나를 추가하면, 깃허브 서버가 정해진 시간에 대신 실행해준다. 내 PC도, VPS도 필요 없다. 설정부터 실전 자동화 완성까지 직접 삽질한 과정을 그대로 공개한다.
1. GitHub Actions 무료 한도와 동작 원리
GitHub Actions는 깃허브가 제공하는 CI/CD 자동화 플랫폼이다. 원래는 코드 테스트와 배포용으로 만들어졌지만, 파이썬 스크립트 정기 실행에도 그대로 쓸 수 있다. 핵심은 무료 티어다. 퍼블릭 레포는 무제한 무료, 프라이빗 레포는 월 2,000분까지 무료다. 매일 한 번 실행되는 스크립트가 1분 안에 끝난다면 한 달에 30분 소비 — 한도의 1.5%도 안 쓴다.
동작 방식은 단순하다. 레포 안에 .github/workflows/ 폴더를 만들고 YAML 파일을 넣으면, 깃허브가 그 파일을 읽어서 조건에 맞게 가상 서버(Runner)를 띄우고 명령어를 실행한다. 서버 관리는 깃허브가 전담하고, 나는 YAML 파일 하나만 관리하면 된다.
2. 레포 구조 준비 및 시크릿 키 등록
레포 폴더 구조
아래 구조로 레포를 세팅한다. 스크립트 파일, 패키지 목록, 워크플로우 파일 세 가지만 있으면 된다.
my-auto-bot/
├── main.py ← 실행할 파이썬 스크립트
├── requirements.txt ← 필요한 패키지 목록
└── .github/
└── workflows/
└── daily_run.yml ← 자동 실행 설정 파일
requirements.txt는 pip freeze > requirements.txt 명령어로 자동 생성하거나, 쓰는 패키지만 직접 적어도 된다. 예시는 아래와 같다.
requests==2.31.0
pandas==2.2.0
anthropic==0.25.0
python-dotenv==1.0.1
API 키를 깃허브 시크릿에 등록하기
로컬에서는 .env 파일에 API 키를 저장하지만, 깃허브에는 절대 그 파일을 올리면 안 된다. 대신 깃허브 레포의 [Settings] → [Secrets and variables] → [Actions] → [New repository secret]에서 키를 등록한다. 이름을 OPENAI_API_KEY로 설정하면, YAML 파일에서 ${{ secrets.OPENAI_API_KEY }}로 안전하게 불러올 수 있다.
3. 워크플로우 YAML 파일 작성: 매일 자동 실행 설정
.github/workflows/daily_run.yml 파일을 만들고 아래 내용을 붙여 넣는다. 매일 한국 시간 오전 9시에 main.py를 자동 실행하는 완성형 워크플로우다.
name: 매일 자동 실행 봇
on:
schedule:
# UTC 기준 00:00 = 한국 시간 오전 09:00
- cron: '0 0 * * *'
workflow_dispatch: # 깃허브 UI에서 수동 실행도 가능하게 설정
jobs:
run-script:
runs-on: ubuntu-latest # 깃허브가 무료로 제공하는 우분투 서버 사용
steps:
- name: 코드 체크아웃
uses: actions/checkout@v4
- name: Python 3.12 세팅
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: 패키지 설치
run: pip install -r requirements.txt
- name: 스크립트 실행
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
run: python main.py
크론 문법(0 0 * * *)이 낯설다면 crontab.guru 사이트에서 원하는 시간을 입력하면 자동으로 표현식을 만들어준다. 중요한 점은 GitHub Actions의 크론은 UTC 기준이라는 것이다. 한국 시간(KST)은 UTC+9이므로, 오전 9시에 실행하려면 UTC 00:00으로 설정해야 한다.
4. 직접 맞은 에러 2가지와 해결법
에러 ① 크론 스케줄이 등록됐는데 실행이 안 됨
YAML 파일을 올리고 기다렸는데 예정된 시간이 지나도 Actions 탭에 아무 기록이 없었다. 알고 보니 두 가지 함정이 있었다. 첫째, 깃허브는 레포에 최근 60일간 활동이 없으면 스케줄 트리거를 자동으로 중지한다. 신규 레포를 만들고 YAML만 올린 뒤 커밋을 멈추면 이 조건에 걸린다. 둘째, 스케줄 트리거는 기본 브랜치(main)에 YAML 파일이 있어야만 작동한다. 다른 브랜치에 올리면 실행되지 않는다. workflow_dispatch를 함께 넣어두면 수동으로 즉시 테스트할 수 있어서 디버깅이 훨씬 편하다.
에러 ② 로컬에서는 되는데 Actions에서만 ModuleNotFoundError
로컬에서 잘 돌아가던 스크립트가 Actions에서 ModuleNotFoundError를 뱉었다. 원인은 requirements.txt에 패키지를 빠뜨린 것이었다. 로컬에는 예전에 설치해 둔 패키지가 남아 있어서 문제없이 돌아갔지만, Actions의 가상 서버는 완전히 새로운 환경이라 requirements.txt에 명시된 것만 설치한다. 로컬 터미널에서 pip freeze > requirements.txt를 실행해 현재 환경의 패키지를 전부 기록한 뒤 다시 푸시하면 해결된다.
5. 실제로 돌려보니 달라진 것들
집 PC를 24시간 켜두던 습관이 사라졌다. 전기세 걱정도 없어졌다. 매달 5달러씩 내던 VPS 구독도 끊었다. 대신 깃허브가 매일 아침 9시에 조용히 스크립트를 실행하고 텔레그램으로 결과를 보내준다.
- 비용: 프라이빗 레포 기준 월 실행 시간 약 30분 소비 — 무료 한도 2,000분의 1.5%. 사실상 영구 무료로 운영 중이다
- 안정성: 집 PC 자동화는 재부팅이나 절전 모드 진입으로 스크립트가 멈추는 일이 잦았다. GitHub Actions는 그런 변수가 없다. 한 달째 단 한 번도 누락 없이 실행됐다
- 확장성: YAML 파일 하나에
strategy.matrix를 추가하면 여러 키워드나 조건을 병렬로 동시에 처리할 수 있다. 스크립트 하나를 10개 조건으로 동시에 돌리는 데 추가 비용이 없다
YAML 문법이 처음엔 생소하지만, 오늘 공개한 템플릿에서 크론 시간과 스크립트 파일명만 바꾸면 어떤 파이썬 자동화에도 바로 적용된다. 서버 없이 자동화를 돌리는 가장 현실적인 방법이다.