Docker db backup
Twelve Greek gods. One command. A working SaaS. 98 skills + 49 agents + 13 hooks for Claude Code + Codex CLI + Gemini CLI. Cross-CLI persistent memory, zero-interaction full pipeline (design → build → inspect → test → ship).
npx -y skills add Dannykkh/skill-olympus --skill docker-db-backupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Docker 환경에서 DB 자동 백업이 필요할 때 사용. PostgreSQL, MySQL, MariaDB 지원. /docker-db-backup으로 실행.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
9.8 KB, ~3.3k tokens by cl100k_base, as published. Nobody here has run it
Docker DB Backup Skill
Docker Compose 프로젝트에 cron 기반 자동 DB 백업 컨테이너를 추가하는 스킬입니다.
Skill Description
Triggers:
/docker-db-backup— 대화형으로 DB 종류를 확인 후 백업 서비스 추가/docker-db-backup pg— PostgreSQL 백업 서비스 추가/docker-db-backup mysql— MySQL/MariaDB 백업 서비스 추가
생성/수정되는 파일:
{compose-dir}/backup-entrypoint.sh— 백업 실행 엔트리포인트{compose-dir}/docker-compose.yml— db-backup 서비스 추가{compose-dir}/.env— 백업 설정 변수 추가
Execution Steps
Step 1: 프로젝트 분석
docker-compose.yml위치를 찾는다 (프로젝트 루트 또는docker-images/등)- 기존 DB 서비스를 파악한다:
postgres/pg이미지 → PostgreSQLmysql/mariadb이미지 → MySQL/MariaDB
- DB 서비스명, 환경변수명, 포트, 헬스체크 조건을 추출한다
- 인자가 없으면 사용자에게 DB 종류를 확인한다
Step 2: backup-entrypoint.sh 생성
반드시 LF 줄바꿈으로 생성해야 한다. Windows에서 CRLF로 생성하면 컨테이너에서 깨진다.
생성 후 아래 명령을 실행:
sed -i 's/\r$//' {compose-dir}/backup-entrypoint.sh
PostgreSQL 템플릿
#!/bin/sh
set -e
BACKUP_DIR="${BACKUP_DIR:-/backups}"
RETENTION_DAYS="${RETENTION_DAYS:-7}"
CRON_SCHEDULE="${CRON_SCHEDULE:-0 2 * * *}"
mkdir -p "$BACKUP_DIR"
cat > /usr/local/bin/run-backup.sh << 'SCRIPT'
#!/bin/sh
set -e
BACKUP_DIR="${BACKUP_DIR:-/backups}"
RETENTION_DAYS="${RETENTION_DAYS:-7}"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${POSTGRES_DB}_${TIMESTAMP}.sql.gz"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 백업 시작: ${POSTGRES_DB}"
PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \
-h "$POSTGRES_HOST" \
-p "${POSTGRES_PORT:-5432}" \
-U "$POSTGRES_USER" \
"$POSTGRES_DB" \
--no-owner --no-acl \
| gzip > "$BACKUP_FILE"
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 백업 완료: $BACKUP_FILE ($SIZE)"
DELETED=$(find "$BACKUP_DIR" -name "${POSTGRES_DB}_*.sql.gz" -mtime +"$RETENTION_DAYS" -print -delete | wc -l)
if [ "$DELETED" -gt 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 오래된 백업 ${DELETED}개 삭제 (보관: ${RETENTION_DAYS}일)"
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 현재 백업 목록:"
ls -lh "$BACKUP_DIR"/${POSTGRES_DB}_*.sql.gz 2>/dev/null || echo " (없음)"
SCRIPT
chmod +x /usr/local/bin/run-backup.sh
env | grep -E '^(POSTGRES_|BACKUP_|RETENTION_)' > /etc/backup.env
echo "${CRON_SCHEDULE} . /etc/backup.env; /usr/local/bin/run-backup.sh >> /var/log/backup.log 2>&1" > /etc/crontabs/root
echo "============================================"
echo " DB Backup Service Started (PostgreSQL)"
echo " Schedule: ${CRON_SCHEDULE}"
echo " Retention: ${RETENTION_DAYS} days"
echo " Backup dir: ${BACKUP_DIR}"
echo "============================================"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 초기 백업 실행..."
/usr/local/bin/run-backup.sh
exec crond -f -l 2
MySQL/MariaDB 템플릿
#!/bin/sh
set -e
BACKUP_DIR="${BACKUP_DIR:-/backups}"
RETENTION_DAYS="${RETENTION_DAYS:-7}"
CRON_SCHEDULE="${CRON_SCHEDULE:-0 2 * * *}"
mkdir -p "$BACKUP_DIR"
# crond 설치 (mysql 이미지에는 없을 수 있음)
if ! command -v crond > /dev/null 2>&1 && ! command -v cron > /dev/null 2>&1; then
if command -v apt-get > /dev/null 2>&1; then
apt-get update -qq && apt-get install -y -qq cron > /dev/null 2>&1
CRON_CMD="cron -f"
elif command -v apk > /dev/null 2>&1; then
CRON_CMD="crond -f -l 2"
fi
else
if command -v crond > /dev/null 2>&1; then
CRON_CMD="crond -f -l 2"
else
CRON_CMD="cron -f"
fi
fi
cat > /usr/local/bin/run-backup.sh << 'SCRIPT'
#!/bin/sh
set -e
BACKUP_DIR="${BACKUP_DIR:-/backups}"
RETENTION_DAYS="${RETENTION_DAYS:-7}"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${MYSQL_DATABASE}_${TIMESTAMP}.sql.gz"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 백업 시작: ${MYSQL_DATABASE}"
mysqldump \
-h "$MYSQL_HOST" \
-P "${MYSQL_PORT:-3306}" \
-u "$MYSQL_USER" \
-p"$MYSQL_PASSWORD" \
--single-transaction \
--routines \
--triggers \
--events \
"$MYSQL_DATABASE" \
| gzip > "$BACKUP_FILE"
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 백업 완료: $BACKUP_FILE ($SIZE)"
DELETED=$(find "$BACKUP_DIR" -name "${MYSQL_DATABASE}_*.sql.gz" -mtime +"$RETENTION_DAYS" -print -delete | wc -l)
if [ "$DELETED" -gt 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 오래된 백업 ${DELETED}개 삭제 (보관: ${RETENTION_DAYS}일)"
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 현재 백업 목록:"
ls -lh "$BACKUP_DIR"/${MYSQL_DATABASE}_*.sql.gz 2>/dev/null || echo " (없음)"
SCRIPT
chmod +x /usr/local/bin/run-backup.sh
env | grep -E '^(MYSQL_|BACKUP_|RETENTION_)' > /etc/backup.env
# crontab 설정 (Debian/Alpine 분기)
if [ -d /etc/crontabs ]; then
echo "${CRON_SCHEDULE} . /etc/backup.env; /usr/local/bin/run-backup.sh >> /var/log/backup.log 2>&1" > /etc/crontabs/root
else
echo "${CRON_SCHEDULE} root . /etc/backup.env; /usr/local/bin/run-backup.sh >> /var/log/backup.log 2>&1" > /etc/cron.d/db-backup
chmod 0644 /etc/cron.d/db-backup
fi
echo "============================================"
echo " DB Backup Service Started (MySQL)"
echo " Schedule: ${CRON_SCHEDULE}"
echo " Retention: ${RETENTION_DAYS} days"
echo " Backup dir: ${BACKUP_DIR}"
echo "============================================"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 초기 백업 실행..."
/usr/local/bin/run-backup.sh
exec $CRON_CMD
Step 3: docker-compose.yml에 서비스 추가
기존 volumes: 선언 바로 위에 서비스를 추가한다.
PostgreSQL용 서비스
db-backup:
image: postgres:{DB와 동일 버전}-alpine
container_name: ${PROJECT_NAME}-db-backup
restart: unless-stopped
environment:
POSTGRES_HOST: {DB 서비스명}
POSTGRES_PORT: "5432"
POSTGRES_USER: ${DB_USER변수}
POSTGRES_PASSWORD: ${DB_PASSWORD변수}
POSTGRES_DB: ${DB_NAME변수}
BACKUP_DIR: /backups
RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7}
CRON_SCHEDULE: ${BACKUP_CRON_SCHEDULE:-0 2 * * *}
TZ: ${TZ:-Asia/Seoul}
volumes:
- db_backups:/backups
- ./backup-entrypoint.sh:/entrypoint.sh:ro
entrypoint: ["/bin/sh", "/entrypoint.sh"]
depends_on:
{DB 서비스명}:
condition: service_healthy
networks:
- {기존 네트워크명}
MySQL/MariaDB용 서비스
db-backup:
image: mysql:{DB와 동일 버전} # 또는 mariadb:{버전}
container_name: ${PROJECT_NAME}-db-backup
restart: unless-stopped
environment:
MYSQL_HOST: {DB 서비스명}
MYSQL_PORT: "3306"
MYSQL_USER: ${DB_USER변수}
MYSQL_PASSWORD: ${DB_PASSWORD변수}
MYSQL_DATABASE: ${DB_NAME변수}
BACKUP_DIR: /backups
RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7}
CRON_SCHEDULE: ${BACKUP_CRON_SCHEDULE:-0 2 * * *}
TZ: ${TZ:-Asia/Seoul}
volumes:
- db_backups:/backups
- ./backup-entrypoint.sh:/entrypoint.sh:ro
entrypoint: ["/bin/sh", "/entrypoint.sh"]
depends_on:
{DB 서비스명}:
condition: service_healthy
networks:
- {기존 네트워크명}
volumes 섹션에 추가:
volumes:
db_backups: # ← 이 줄 추가
Step 4: .env에 변수 추가
# DB 백업 설정
BACKUP_RETENTION_DAYS=7
BACKUP_CRON_SCHEDULE=0 2 * * *
Step 5: LF 변환 + 테스트
# 1. LF 변환 (필수)
sed -i 's/\r$//' {compose-dir}/backup-entrypoint.sh
# 2. 백업 서비스 시작
cd {compose-dir} && docker compose up -d db-backup
# 3. 로그 확인 (초기 백업 성공 여부)
docker logs {프로젝트}-db-backup
# 4. 백업 파일 확인
MSYS_NO_PATHCONV=1 docker exec {프로젝트}-db-backup ls -lh /backups/
Step 6: 결과 보고
실행 후 사용자에게 다음을 알려준다:
- 생성/수정된 파일 목록
- 백업 스케줄 (기본 매일 02:00)
- 보관 기간 (기본 7일)
- 운영 명령어 (수동 백업, 복원 방법)
DB별 주요 차이점
| 항목 | PostgreSQL | MySQL/MariaDB |
|---|---|---|
| 이미지 | postgres:{ver}-alpine | mysql:{ver} 또는 mariadb:{ver} |
| 덤프 도구 | pg_dump (이미지 내장) | mysqldump (이미지 내장) |
| cron | Alpine crond 내장 | Debian이면 cron 설치 필요 |
| 환경변수 prefix | POSTGRES_ | MYSQL_ |
| 덤프 옵션 | --no-owner --no-acl | --single-transaction --routines --triggers --events |
| 복원 명령 | gunzip -c file.sql.gz | psql -U user -d db | gunzip -c file.sql.gz | mysql -u user -p db |
주의사항
- backup-entrypoint.sh는 반드시 LF 줄바꿈이어야 한다. Windows CRLF → 컨테이너에서
/bin/sh: set: illegal option에러 발생 - 백업 도구 버전 ≥ DB 서버 버전. pg_dump/mysqldump는 forward-compatible이 아니라, 구버전 도구로 newer 서버를 덤프하면
server version mismatch로 실패한다. 백업 이미지를 DB 이미지와 동일 태그로 고정하라(DB를 올리면 백업 이미지도 같이 올림). MySQL은 버전이 같아야caching_sha2_password인증 핸드셰이크도 안전하다 - **Docker volume
db_backups**에 저장되므로 컨테이너 삭제해도 백업은 유지된다 - 호스트로 백업을 꺼내려면:
docker cp {컨테이너}:/backups/{파일} ./ .env의BACKUP_CRON_SCHEDULE은 cron 5-field 표현식 (초 없음)
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.