[태그:] cron

  • 자기 PC가 알아서 — 백업·캐시·이미지 압축

    자기 PC가 알아서 — 백업·캐시·이미지 압축

    자기 PC가 알아서 — 백업·캐시·이미지 압축

    셀프호스팅 구축기 4편. 운영은 자동화로 푼다.


    TL;DR

    • 백업: 매일 03:00 mariadb-dump → gzip → Obsidian Vault. 30일 회전. 미니PC 죽어도 글 안전
    • DB 캐시: Redis Object Cache로 반복 쿼리 메모리 캐싱. 페이지 응답 30% 빨라짐
    • 페이지 캐시: WP Super Cache로 정적 HTML 생성. 두 번째 방문자부터 PHP 안 거침
    • 이미지: EWWW로 자동 WebP 변환. 평균 30~70% 용량 ↓
    • 셋업 한 번, 잊는다

    1. 셀프호스팅의 진짜 일은 운영

    처음 셋업은 30분이지만, 그 후가 진짜다. 매일 누가 백업하고, 누가 캐시 비우고, 누가 이미지 압축하나? 사람이 하면 까먹는다. 자동화한다.

    

    2. 백업 — wp-backup.sh

    /home/worker/scripts/wp-backup.sh:

    #!/bin/bash
    set -euo pipefail
    
    BACKUP_DIR="/home/user/문서/Obsidian Vault/KnowledgeVault/Meta/backups/wordpress"
    DATE=$(date +%Y-%m-%d)
    LOG_DIR="/home/worker/logs"
    WEEK=$(date +%Y-W%V)
    LOG_FILE="$LOG_DIR/kimcorp-${WEEK}.log"
    
    mkdir -p "$BACKUP_DIR" "$LOG_DIR"
    
    START=$(date +%s)
    TARGET="$BACKUP_DIR/wp-${DATE}.sql.gz"
    
    # mariadb-dump → gzip
    if sudo docker exec wordpress-db-1 \
       mariadb-dump --single-transaction -u root -p"${DB_ROOT_PW}" wp \
       | gzip > "$TARGET"; then
        SIZE=$(du -h "$TARGET" | cut -f1)
        ELAPSED=$(( $(date +%s) - START ))
        echo "$(date '+%Y-%m-%d %H:%M') | [wp-backup] | OK | ${SIZE} | ${ELAPSED}s" >> "$LOG_FILE"
    else
        echo "$(date '+%Y-%m-%d %H:%M') | [wp-backup] | FAIL-L2 | dump error" >> "$LOG_FILE"
        exit 1
    fi
    
    # 30일 이상 회전
    find "$BACKUP_DIR" -name "wp-*.sql.gz" -mtime +30 -delete
    

    권한: chmod +x. crontab:

    0 3 * * * /home/worker/scripts/wp-backup.sh
    

    매일 새벽 03:00 자동 실행. 첫 백업 검증:

    ls -la "$BACKUP_DIR"
    # wp-2026-05-27.sql.gz  20K
    

    20KB는 콘텐츠 없는 초기 DB. 글 100편 + 이미지 메타 = 보통 500KB~5MB.

    왜 Obsidian Vault에 저장?

    Obsidian Vault는 이미 사장님 노트 시스템 = 자동으로 다른 PC·폰에 동기화됨 (OneDrive·Syncthing 사용 시). 별도 백업 매체 셋업 불필요. 미니PC 죽어도 사장님 노트북·폰에 백업 사본 살아있음.


    3. Redis Object Cache — DB 쿼리 캐싱

    WordPress는 페이지 한 번 표시할 때 평균 50~200개 DB 쿼리를 던진다. 그중 80%가 반복(메뉴·옵션·설정).

    Redis Object Cache가 이 반복 쿼리를 메모리에 캐싱:

    wp config set WP_REDIS_HOST redis --allow-root
    wp config set WP_REDIS_PORT 6379 --allow-root
    wp config set WP_REDIS_PREFIX byeolgorae: --allow-root
    wp config set WP_CACHE true --raw --allow-root
    wp plugin install redis-cache --activate --allow-root
    wp redis enable --allow-root
    

    검증:

    wp redis status --allow-root
    # Status: Connected
    # Client: PhpRedis (v6.x)
    

    체감: 페이지 응답 300ms → 200ms (30% 단축).


    4. WP Super Cache — 페이지 캐시

    Redis가 DB 쿼리 캐시라면, WP Super Cache는 완성된 HTML 자체를 캐싱.

    방문 Redis만 Redis + Super Cache
    첫 방문자 PHP 실행 + Redis 캐시 미스 → DB → 응답 PHP 실행 + 정적 HTML 생성
    두 번째~ 방문자 PHP 실행 + Redis 캐시 히트 → 응답 (~200ms) PHP 안 거침. 정적 파일 직접 응답 (~50ms)

    플러그인 설치 후 활성화는 GUI에서:
    – 설정 → WP Super Cache → Easy 탭
    – “Caching On (Recommended)” 라디오
    – Update Status

    wp-cli로는 활성 못함 (커맨드 미등록). 사장님이 직접 한 번 클릭.

    ⚠ 함정: 로그인된 사용자(사장님)는 페이지 캐시 안 받음 (의도된 동작). 사장님이 글 발행 후 “왜 안 보여?” 할 수 있는데 시크릿 모드로 열어보면 보임.


    5. EWWW Image Optimizer — 이미지 자동 압축

    업로드한 이미지를 자동으로 WebP로 변환 + 무손실 압축.

    형식 같은 사진 용량
    JPEG (원본) 800KB
    WebP (EWWW) 250KB (-69%)
    AVIF (EWWW 유료) 150KB (-81%)

    설치 후 기본 설정 그대로면 OK. 새 이미지 업로드 시 자동 변환. 옛 이미지 일괄 변환은 Bulk Optimize 메뉴.

    체감: 모바일 페이지 LCP(Largest Contentful Paint) 2.5초 → 1.2초.


    6. 종합 — 셋업 한 번, 운영 0

    작업 셋업 시간 이후
    wp-backup.sh + cron 10분 매일 03:00 자동
    Redis Object Cache 3분 영구 자동
    WP Super Cache GUI 활성 1분 영구 자동
    EWWW Image Optimizer 1분 새 이미지 업로드 시 자동

    총 15분 한 번 = 운영 자동화 완료.


    FAQ

    Q. 백업 복원은 어떻게?

    gunzip -c wp-2026-05-30.sql.gz | sudo docker exec -i wordpress-db-1 mariadb -u root -p"${DB_ROOT_PW}" wp
    

    한 줄. 실제 복원은 분기에 한 번 정도 리허설 권장.

    Q. wp_content/uploads 이미지도 백업되나?
    위 스크립트는 DB만. 이미지는 tar -czf uploads-$DATE.tar.gz wp-content/uploads/ 한 줄 추가하면 됨. 또는 Obsidian Vault에 직접 첨부하는 워크플로면 별도 백업 불필요.

    Q. UpdraftPlus 같은 WP 백업 플러그인 쓰면 안 되나?
    가능. 단 WP 안에서 백업 = WP 죽으면 백업도 죽음. 시스템 레벨 cron이 더 안전. UpdraftPlus는 보조로 설치만 해두고 비활성.

    Q. Redis 메모리 차면?
    별고래 트래픽 규모(월 1만 미만)에선 100MB 이하. 메모리 차도 LRU(Least Recently Used)로 자동 정리. 걱정 X.

    Q. WP Super Cache + Cloudflare CDN 중복 아닌가?
    중복 아님. CDN은 정적 파일(이미지·CSS), Super Cache는 HTML. 둘 다 켜는 게 정답.


    다음 편 예고

    5편 — 별고래 분석실: Umami로 방문자 통계. Google Analytics 대신 자체 호스팅. 쿠키 없음 + 사장님이 데이터 소유.


    한 줄 정리

    셋업 15분으로 백업·DB 캐시·페이지 캐시·이미지 압축이 매일 자동. 운영 시간 0, 페이지 30% 빠름, 이미지 70% 작음, 데이터 안전.