Cron Manager를 활용한 작업 스케줄링 가이드
앱이 매일 밤 캐시를 재구축하거나, 오래된 데이터를 정리하거나, 사용자에게 주간 뉴스레터를 이메일로 보내야 한다면 cron 작업을 실행할 방법이 필요할 거예요. Fly.io는 이를 해결할 몇 가지 방법을 제공하며, 이 가이드는 가장 견고한 옵션부터 "그래도 동작은 하겠지" 수준의 옵션까지 작업 스케줄링 옵션을 안내합니다.
출처: 문서
본문
개요 (Overview)
일정에 따라 실행하는 것은 기차만의 전유물이 아니에요. 앱이 매일 밤 캐시를 재구축해야 하거나, 오래된 데이터를 정리해야 하거나, 사용자에게 주간 뉴스레터를 이메일로 보내야 한다면, cron 작업을 실행할 방법을 찾고 있을 거예요. Fly.io는 그 작업을 해결할 몇 가지 방법을 제공합니다.
가장 견고한 것부터 시작해서 "그래도 동작은 하지, 응?" 수준까지, 작업 스케줄링 옵션을 차례로 살펴볼게요.
Cron Manager
Cron Manager는 예약 작업 실행을 위한 저희의 "배터리 포함(batteries-included)" 솔루션이에요. 작업당 하나씩 임시 Machine을 띄우고 그 후에 없애는 작은 Fly 앱입니다. 종을 울리고, 집사가 없다는 사실을 기억하기 전에 조용히 사라지는 아주 예의 바른 집사라고 생각하면 돼요.
동작 방식
Cron Manager를 별도의 Fly 앱으로 배포합니다. 앱은 온라인 상태를 유지하며 schedules.json 파일을 지켜봐요. 작업의 예약 시간이 되면, 지정한 이미지, 리전, 리소스로 일회성 Machine을 부팅합니다. 그 Machine은 명령을 실행하고, 종료되며, 좋은 컨테이너답게 사라집니다.
작업은 완전한 격리 상태로 실행됩니다. 공유 환경도, 이전 작업에서 이어받은 이상한 상태도 없어요. 그리고 Fly Machine일 뿐이므로 모든 이점을 누릴 수 있습니다. 리전 배치, 리소스 제어, 이미지 선택, 깔끔한 로그까지요.
이걸 왜 쓸까
- 격리 (Isolation): 각 작업은 자체 Machine을 얻습니다. 아무것도 새지 않아요.
- 중앙 구성 (Central config):
schedules.json은 Git에 보관됩니다. 변경 사항은 버전 관리되고, 감사 가능하며, 배포할 수 있어요. - 쉬운 업데이트: 명령이나 일정을 바꾸고 싶나요? 파일을 업데이트하고 재배포하세요.
- 작업 로그: 각 Machine은 자체 로그와 수명 주기를 갖습니다. 디버깅이 보물찾기가 아니에요.
설정 (Setup)
- cron-manager를 클론합니다
- 새 Fly 앱을 만들고
fly deploy로 배포합니다 - 앱의 시크릿으로
FLY_API_TOKEN을 설정합니다 schedules.json에 작업 일정을 정의합니다
샘플 작업은 다음과 같아요:
{
"name": "daily-cache-rebuild",
"app_name": "my-app",
"schedule": "0 3 * * *",
"region": "lhr",
"command": ["bin/rebuild-cache"],
"command_timeout": 300,
"enabled": true,
"config": {
"image": "my-app-image",
"guest": { "cpu_kind": "shared", "cpus": 1, "memory_mb": 256 },
"restart": { "policy": "no" }
}
}
작업 관리 (Managing Jobs)
배포가 끝나면 다음을 할 수 있어요:
- 작업 나열:
cm schedules list - 기록 확인:
cm jobs list <schedule-id> - 세부 정보 들여다보기:
cm jobs show <job-id> - 수동으로 하나 트리거:
cm jobs trigger <schedule-id>
탐색할 게 있다면 Cron Manager VM에 SSH로 접속하세요.
Supercronic
때로는 완전한 오케스트레이션 계층이 필요하지 않아요. 그냥 앱 컨테이너 안에서 crontab을 실행하고 싶을 뿐이죠. Supercronic이 그걸 해 줍니다. 환경 변수를 올바르게 처리하는 컨테이너 친화적인 cron 러너입니다.
동작 방식
Supercronic은 앱 안에서 백그라운드 프로세스로 실행됩니다. crontab 파일을 추가하고, Dockerfile에 Supercronic을 설치하고, fly.toml에 cron 프로세스를 정의하면 끝이에요.
음, 거의 끝이죠. 올바르게 확장하는 것을 잊지 마세요.
설정 (Setup)
- 표준 문법을 사용해 crontab 파일(
/app/crontab)을 추가합니다 - Dockerfile에 Supercronic을 설치합니다
fly.toml에서:
[processes]
app = "bin/server"
cron = "supercronic /app/crontab"
- 확장합니다:
fly scale count app=2 cron=1
cron 프로세스는 하나의 복사본만 실행하세요. 같은 알림 이메일을 네 번 보내는 게 목표가 아니라면요. (그게 목표라면, 계속 하세요.)
예약된 Machine (Scheduled Machines)
Fly Machines는 기본적으로 기본적인 스케줄링을 지원합니다. Machine에 매시간, 매일, 매주, 매월 시작하라고 지시할 수 있어요. API는 간단합니다. 단점? 세밀한 제어는 얻지 못합니다. 단지 간격 버킷만 있을 뿐이에요.
비필수적인 정리 작업이나 "하루에 대략 한 번 정도"로 충분한 작업에는 충분합니다.
앱 내 스케줄링 (In-App Scheduling)
Python 앱에서 apscheduler 같은 스케줄러를 이미 사용하고 있거나, Node에서 직접 만들어 사용하고 있다면, 그걸 사용해 fly machine run --rm을 호출하고 임시 Machine을 수동으로 띄울 수 있어요.
이렇게 하면 완전한 제어를 얻을 수 있고 기술적으로도 우아하지만, 신중한 발놀림이 필요합니다. "자체 트리거 시스템 구축" 옵션으로, 이미 절반쯤 진행된 상황에 가장 적합해요.
추가 옵션 (Additional Options)
위의 옵션 외에도 GitHub Actions schedule이나, 머신을 깨우기 위해 API 요청을 보낼 수 있는 온라인 cron 서비스인 easycron 같은 외부 스케줄링 서비스를 사용할 수 있어요.
요약 (Summary)
| 옵션 | 이럴 때 사용 | 알아두면 좋은 점 |
|---|---|---|
| Cron Manager | 격리되고 감사 가능한 작업 실행을 원할 때 | 별도의 앱이 필요함 |
| Supercronic | 컨테이너 안에서 빠른 cron 작업을 원할 때 | 프로세스 수를 1로 유지 |
| 예약된 Machine | 단순하고 낮은 빈도의 작업(~1x/day)을 원할 때 | 정밀한 타이밍에는 부적합 |
| 앱 내 스케줄러 | 완전한 제어를 원하고 배관 작업을 신경 쓰지 않을 때 | 자체 오케스트레이션 작성 |
어디서부터 시작할지 모르겠다면, Cron Manager가 가장 프로덕션에 검증된 옵션이에요. 하지만 Supercronic은 거의 설정 없이 80%의 길을 갈 수 있게 해 주며, 때로는 그것만으로 충분할 때도 있습니다.