# ========================================== # 운영 서버의 백업 · 감시 설정 (13단계 — mail/README.md "백업" · "감시") # # 이 파일은 예시다. 서버에서는 저장소 밖에 둔다 — root 만 읽게: # sudo install -d -m 0700 -o root -g root /etc/arasystem # sudo install -m 0600 -o root -g root ops/ops.env.example /etc/arasystem/ops.env # 그다음 값을 채운다 (sudoedit /etc/arasystem/ops.env) # restic 저장소 비밀번호는 따로 /etc/arasystem/restic-password (0600) — 한 줄, 무작위로. 비밀번호 관리자의 생성기로 먼저 만들어 저장한 뒤(40자 이상 · 영문 · 숫자) # 화면 · 셸 기록에 남기지 않고 붙여 넣는다(restic 은 끝 줄바꿈을 떼고 읽는다): # read -rsp 'restic 비밀번호: ' P; echo; printf '%s\n' "$P" | sudo install -m 0600 -o root -g root /dev/stdin /etc/arasystem/restic-password; unset P # (서버에서 만들려면 sudo sh -c 'umask 077; openssl rand -base64 33 > /etc/arasystem/restic-password' — 그때는 sudo cat 으로 한 번 보고 비밀번호 관리자로 옮긴다) # ⚠️ restic 비밀번호 · S3 키는 서버 밖(회사의 비밀번호 관리자 — 운영자 한 사람만이 아니라 회사가 꺼낼 수 있는 곳)에도 둔다 — 서버를 잃었는데 비밀번호가 서버에만 있으면 백업을 풀 수 없다. # # 형식: KEY=값 한 줄씩. 스크립트는 이 파일을 셸로 실행(source)하지 않고 줄마다 읽는다 — 값에 공백이 있으면 작은따옴표로 감싼다. # ========================================== # 저장소 폴더 (git clone 한 곳) — 스크립트가 여기의 .env.production · backend/.env.production 을 읽는다 # (PROJECT_NAME · 메일 도메인 · 관리자 비밀번호(대기열 확인) · Spamhaus 키 — 따로 복사해 두지 않는다) ARASYSTEM_DIR=/home/ubuntu/arasystem # 프로젝트 이름 — 볼륨 · 컨테이너 이름(_mail-data · -mail)과 백업 스냅숏의 host 이름이 이 값이다. # 비우면 위 저장소의 .env.production 에서 읽는다. ⚠️ 새 서버를 되살릴 때는 적는다(옛 서버의 값 — 예: arasystem) — 그 단계에는 .env.production 이 # 아직 없다(restore.sh files 가 백업에서 꺼낸다). 둘 다 있고 다르면 스크립트가 멈춘다 PROJECT_NAME= # 백업 스냅숏의 host 이름 — 비우면 PROJECT_NAME. 다른 이름으로 받던 백업을 이어 쓸 때만 적는다 BACKUP_HOST= # ------------------------------------------ # 백업 (ops/backup/arasystem-backup.sh — systemd 타이머 매일 03:30 KST) # ------------------------------------------ # restic 저장소 — NCP Object Storage(S3 호환). 버킷은 콘솔에서 먼저 만든다(공개 안 함). 뒤의 /arasystem 은 버킷 안의 접두어 RESTIC_REPOSITORY=s3:https://kr.object.ncloudstorage.com/change-me-bucket/arasystem # NCP 의 S3 옵션 — 지역 kr-standard(서명 V4 에 쓴다) · 경로 방식(https://<엔드포인트>/<버킷> — NCP 는 경로 · 가상 호스트 방식 둘 다 받는다) # (근거: NCP API 가이드 Object Storage — https://api.ncloud-docs.com/docs/storage-objectstorage · …-listobjects) RESTIC_OPTIONS='-o s3.region=kr-standard -o s3.bucket-lookup=path' # NCP API 인증키 — 버킷에는 따로 키가 없다. 서버 B 는 메인 계정의 백업 전용 키(My Account › 계정 및 보안 관리 › 보안 관리 › 접근 관리 › API 인증키 관리 — 2026-11-03 결정). # ⚠️ 메인 계정 키는 그 계정의 모든 API 를 연다 — 범위를 줄이려면 Object Storage 만 쓰는 서브 계정의 키로(mail/README.md "백업 › 설치"). 어느 쪽이든 버킷 하나로는 좁히지 못한다 AWS_ACCESS_KEY_ID=change-me AWS_SECRET_ACCESS_KEY=change-me # 보존 — 매일 7 · 매주 4 · 매달 6 (그보다 오래된 백업은 지운다 — 지운 메일도 이 기간까지만 백업에 남는다) BACKUP_KEEP_DAILY=7 BACKUP_KEEP_WEEKLY=4 BACKUP_KEEP_MONTHLY=6 # 메일 엔진을 멈추고 올리는 final 한 번의 시간 상한(숫자 + s · m · h) — 넘으면 restic 을 멈추고 엔진을 다시 띄운 뒤 실패로 알린다. # 평소 final 은 몇 초다(바뀐 것만 올린다). 바깥 대역폭이 아주 느리면 늘린다 BACKUP_FINAL_TIMEOUT=15m # 사전 확인에서 메일 엔진 · DB 가 healthy 가 되기를 기다리는 시간(초) — 부팅 직후 타이머가 놓친 백업을 바로 할 때 엔진이 아직 starting 이다 BACKUP_HEALTHY_WAIT=300 # ------------------------------------------ # 알림 — Healthchecks.io (무료). 체크 둘을 만들고 각자의 ping 주소를 넣는다 (mail/README.md "감시" — 체크 만드는 차례) # 비우면 알리지 않는다(로그 · 상태 파일은 그대로). 주소를 아는 사람은 거짓 신호를 보낼 수 있다 — 이 파일 밖에 적어 두지 않는다 # ------------------------------------------ HC_BACKUP_URL= HC_CHECK_URL= # ------------------------------------------ # 15분 점검 (ops/monitor/arasystem-check.sh) — 비운 값은 기본값 # ------------------------------------------ # 디스크 — 볼 마운트 지점(공백으로) · 넘으면 알리는 사용률(%). 비우면 / 와 도커 데이터 폴더(docker info 의 DockerRootDir) CHECK_DISKS= CHECK_DISK_MAX_PERCENT=85 # 인증서 — host:port (공백으로). 비우면 .env.production 의 MAIL_HOSTNAME:993 · CORS_ORIGIN 의 호스트:443 · SHARE_PUBLIC_URL 의 호스트:443 CHECK_CERTS= CHECK_CERT_MIN_DAYS=14 # 메일 대기열 — 쌓인 수 · 가장 오래 머문 시간(시간) CHECK_QUEUE_MAX=50 CHECK_QUEUE_MAX_AGE_HOURS=24 # 마지막 백업 성공에서 지난 시간(시간) CHECK_BACKUP_MAX_AGE_HOURS=26