손 안 가는 서버 — cron으로 굴러가는 작은 자동화들

작성자

카테고리:

This post is written in Korean. Most browsers (Chrome, Edge) can translate it automatically — look for a translate icon in the address bar, or right-click the page and choose “Translate to English.”

셀프호스팅 구축기 14편(마지막). 백업도(12편) 동기화도(13편) 결국 “정해진 시각에 알아서” 돌아야 한다. 그 엔진이 cron이다.

← 이전 편: 13편 — 내 노트는 내 서버에 (Obsidian LiveSync)
→ 다음 편: 15편 — 탭이 안 되는 링크 (텔레그램→옵시디언)

요약

  • cron(크론)은 정해진 시각에 명령을 돌리는 리눅스 기본 스케줄러 — 따로 설치할 것 없다
  • 우리 서버가 매일 알아서 하는 일: 백업 · DB 덤프 · 캐시 정리 · 헬스체크 · 요약 생성
  • crontab 한 줄 = 분·시·일·월·요일 + 실행할 명령
  • 함정 1: cron엔 PATH가 거의 없다 → 절대경로 안 쓰면 “command not found”
  • 함정 2: 조용한 실패 — 로그로 안 남기면, 안 돈 걸 며칠 뒤에야 안다

1. cron이 뭔가 — 설치 없는 알람시계

cron은 리눅스에 기본으로 들어 있는 알람시계다. “매일 새벽 4시 반에 이 스크립트 실행”처럼 시각과 명령을 등록해 두면, 컴퓨터가 켜져 있는 한 알아서 돌린다. 셀프호스팅에서 반복되는 잡일은 거의 다 cron에 맡길 수 있다.

2. crontab 한 줄 읽는 법

등록 목록을 crontab이라 부른다. 한 줄은 다섯 칸의 시각 + 명령으로 이루어진다.

칸 의미 범위
1 분 0–59
2 시 0–23
3 일 1–31
4 월 1–12
5 요일 0–6 (0=일)

*는 “매번”이라는 뜻이다. 그래서 30 4 * * *는 매일 4시 30분이 된다.

30 4 * * *   /home/user/bin/db-dump.sh    >> /var/log/db-dump.log 2>&1
0  5 * * *   /home/user/bin/backup.sh      >> /var/log/backup.log 2>&1
crontab 한 줄 뜯어보기 예시 줄 30 4 * * * /home/user/bin/db-dump.sh >> 로그 2>&1 을 칸별로 나눈 그림. 앞의 다섯 칸은 분, 시, 일, 월, 요일이고 합치면 매일 4시 30분이다. 별표는 매번이라는 뜻이다. 이어지는 실행할 명령은 절대경로로 쓰고(함정 1), 마지막 부분은 출력과 에러를 로그 파일에 남긴다(함정 2). 시각은 서버 시계 기준이라 서버가 UTC면 한국 시각으로 오후 1시 반에 돈다(함정 3). crontab 한 줄 = 시각 다섯 칸 + 명령 30 4 * * * /home/user/bin/db-dump.sh >> 로그 2>&1 분 시 일 월 요일 실행할 명령 출력과 에러를 파일로 함정 ①: 절대경로로 쓴다 함정 ②: 로그로 남긴다 = 매일 4시 30분 * 는 “매번”이라는 뜻 함정 ③: 이 시각은 서버 시계 기준이다. 서버가 UTC면 한국 시각으로는 오후 1시 반에 돈다.
그림 1. crontab 한 줄을 칸별로 나눠 본 모습. 앞 다섯 칸이 시각, 그 뒤가 명령이고, 함정 3개가 각각 어디에 걸리는지 표시했다.

3. 우리 서버가 매일 하는 일

작은 cron들이 쌓여 “손 안 가는 서버”를 만든다.

  • DB 덤프 — 데이터베이스를 안전한 파일로 (백업보다 먼저)
  • 파일 백업 — NAS로 전송 (12편)
  • 캐시 정리 — 쌓인 임시 파일·만료 캐시 비우기
  • 헬스체크 — 서비스가 살아 있는지 확인, 죽었으면 알림
  • 요약 생성 — 어제 방문자·에러 한 장으로 정리
매일 알아서 도는 작은 cron 다섯 개 왼쪽의 cron이 매일 정해진 시각에 다섯 작업을 돌린다. DB 덤프는 데이터베이스를 안전한 파일로 만들며 백업보다 먼저 돈다(예시 04시 30분). 파일 백업은 NAS로 전송한다(예시 05시). 캐시 정리는 쌓인 임시 파일과 만료 캐시를 비운다. 헬스체크는 서비스가 살아 있는지 확인하고 죽었으면 알린다. 요약 생성은 어제 방문자와 에러를 한 장으로 정리한다. 이것들이 쌓이면 매일 손대지 않아도 스스로를 돌보는 서버가 된다. 매일 알아서 도는 작은 cron 다섯 개 cron 정해진 시각에 매일 실행 DB 덤프 파일 백업 캐시 정리 헬스체크 요약 생성 데이터베이스를 안전한 파일로 (백업보다 먼저) NAS로 전송 (12편) 쌓인 임시 파일, 만료 캐시 비우기 서비스가 살아 있는지 확인, 죽었으면 알림 어제 방문자와 에러를 한 장으로 정리 예시 04:30 예시 05:00 쌓이면: 매일 손대지 않아도 스스로를 돌보는 서버
그림 2. 우리 서버가 매일 알아서 하는 다섯 가지. 시각은 2절 crontab 예시의 두 줄에서 가져왔고, 나머지 셋은 본문에 시각을 정하지 않아 비워 뒀다.

4. 초보가 꼭 밟는 함정 3개

① PATH가 없다. 터미널에서 잘 되던 명령이 cron에선 “command not found”로 죽는다. cron은 최소한의 환경에서 돌아 PATH가 거의 비어 있기 때문이다. 해결: 명령을 절대경로로 쓰거나(/usr/bin/python3), 스크립트 맨 위에 PATH를 직접 지정한다.

② 조용한 실패. cron은 에러가 나도 화면에 안 띄운다. 기본적으로 메일로만 보내는데 아무도 안 본다. 그래서 위 예시처럼 >> 로그파일 2>&1로 출력과 에러를 파일에 남겨야, 안 돌았을 때 추적이 된다.

③ 시간대. 서버 시계가 UTC인지 한국 시간(KST)인지 확인하자. 30 4 * * *로 “새벽 4시 반”을 노렸는데 서버가 UTC면 한국 시각으로는 오후 1시 반에 돈다.

5. 작은 자동화의 복리

cron 하나하나는 사소하다. 백업 한 줄, 캐시 정리 한 줄. 그런데 이게 쌓이면 내가 매일 손대지 않아도 서버가 스스로를 돌보는 상태가 된다. 셀프호스팅의 목표는 결국 이거다 — 만들어 놓고, 잊어버려도 굴러가는 것.

이 시리즈도 여기서 한 바퀴를 돈다. 빈 컴퓨터 한 대에서 시작해(1편), 블로그를 올리고, 도메인을 붙이고, 막고, 백업하고, 이제 자동으로 굴러가게 했다. 다음은 직접 한 대 세워 보는 일만 남았다.


한 줄 정리

cron은 “정해진 시각에 알아서”의 엔진이다. 한 줄에 분·시·일·월·요일 + 명령. 단 세 가지만 조심하자 — 절대경로로 쓰고, 로그를 남기고, 시간대를 확인할 것. 작은 자동화가 쌓이면 서버는 손이 안 가게 된다.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다