Skip to content

feat(backup): backup katalogu konfiguracyjnego (.env z kluczem szyfrowania) w cyklu nocnym - #42

Merged
mpasternak merged 2 commits into
mainfrom
feat/backup-env
Oct 24, 2026
Merged

mpasternak merged 2 commits into
mainfrom
feat/backup-env

Conversation

@mpasternak

Copy link
Copy Markdown
Member

Po co

Od #41 .env trzyma DJANGO_BPP_FIELD_ENCRYPTION_KEY — bez niego odtworzona baza ma nieczytelne tokeny PBN / hasła integracji. Do tej pory backup obejmował tylko bazę i media; .env trzeba było kopiować ręcznie.

Co

Katalog konfiguracyjny ($BPP_CONFIGS_DIR: .env, rclone/rclone.conf, ssl/, letsencrypt/, monitoring; bez logs/, *.log) jest archiwizowany tak samo jak baza (decyzja właściciela: bez obowiązkowego szyfrowania hasłem):

  • Nocny cykl (scripts/backup-cycle.sh, krok 2b): config-backup-<TS>.tar.gz obok zrzutów, ten sam timestamp, tryb 0600 (umask 077 przed utworzeniem), właściciel = właściciel katalogu backupów; ta sama rotacja (prune_type config-backup, KEEP_LAST) i ta sama wysyłka rclone copy do katalogu miesięcznego. Osobny plik, nie wewnątrz dumpu bazy.
  • Nieblokujące: brak mountu (kontener sprzed make up) → config=BRAK-MOUNTU(make up); błąd tar → config=BLAD(exit=N) — ostrzeżenie w logu + adnotacja w komunikacie do Rollbara, kod wyjścia cyklu bez zmian (sam git pull zmienia scripts/ na bind-mouncie, więc fatalny krok wywracałby każdy nocny backup bazy aż do make up).
  • backup-runner: nowy mount ${BPP_CONFIGS_DIR}:/configs:ro → wymaga make up.
  • scripts/config-backup.sh — jedno źródło (POSIX, przetestowane pod busybox ash) dla cyklu i make config-backup (efemeryczny alpine, jak media-backup); make backup = baza + media + konfiguracja.
  • make restore-config FILE=... [ONLY_ENV=1] [BPP_CONFIGS_DIR=...] (scripts/restore-config.sh): walidacja wpisów (../ścieżki absolutne → odmowa), różnice tylko po nazwach zmiennych + osobne ostrzeżenie przy zmianie klucza, potwierdzenie słowem tak (EOF/brak TTY = nic się nie zmienia), kopia .env.przed-restore-<TS> (0600) i archiwum poprzedniego katalogu, rozpakowanie z zachowaniem uprawnień. Zdefiniowany przed ifdef FIRST_RUN — na świeżym hoście make → init-configs wygenerowałby nowy klucz; restore sam zapisuje repo-lokalny .env.

Testy

  • tests/test_makefile.sh: test_config_backup_script, test_restore_config, test_restore_config_first_run, test_backup_runner_mounts_configs (mutacyjnie sprawdzone: usunięcie umask/chmod i akceptacja dowolnej odpowiedzi zapalają testy).
  • scripts/test-rclone.sh §3b: e2e cyklu (archiwum z .env, ten sam TS, 0600, rotacja do 7, brak mountu i błąd tar → exit 0 + adnotacja) oraz §6 pod busybox ash (docker:28-cli).

Docs

docs/eksploatacja/backup-i-rclone.md (nowa sekcja „Backup konfiguracji (.env)” z odtwarzaniem i procedurą nowego serwera po awarii), link z sekcji klucza w docs/konfiguracja/architektura.md, przenosiny-serwera.md, komendy.md, CLAUDE.md.

Po wdrożeniu (admin)

  1. git pull && make up (nowy mount w backup-runner).
  2. Następnego dnia sprawdź w logu/Rollbarze config=<rozmiar> (nie BRAK-MOUNTU).
  3. Zapisz hasło (i salt) remote'a backup_enc: w menedżerze haseł — rclone.conf jest w archiwum, które samo leży za tym hasłem na zdalnym.
  4. Katalog backupów chroń jak sam serwer — kto ma backup, ma też dane i klucz.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UJ23Rb1c5UtxHTfAke9ENQ

mpasternak and others added 2 commits October 24, 2026 20:11
.env trzyma klucz szyfrowania sekretow integracji
(DJANGO_BPP_FIELD_ENCRYPTION_KEY, #41) - bez niego odtworzona baza ma
nieczytelne tokeny PBN/hasla integracji. Katalog konfiguracyjny jest teraz
archiwizowany tak samo jak baza:

- krok 2b backup-cycle.sh: config-backup-<TS>.tar.gz (0600, ten sam
  timestamp) obok zrzutow, ta sama rotacja (KEEP_LAST) i wysylka rclone copy;
  blad lub brak mountu to ostrzezenie + adnotacja config=... w Rollbarze,
  nigdy zmiana kodu wyjscia (sam git pull nie dodaje mountu);
- backup-runner: mount ${BPP_CONFIGS_DIR}:/configs:ro (wymaga make up);
- scripts/config-backup.sh: jedno zrodlo dla cyklu i `make config-backup`
  (efemeryczny alpine); `make backup` obejmuje konfiguracje;
- `make restore-config FILE=...` (scripts/restore-config.sh): walidacja
  archiwum, roznice tylko po nazwach zmiennych, potwierdzenie "tak",
  kopia .env.przed-restore-<TS>; dziala bez repo .env (swiezy host),
  zeby nie odpalac init-configs generujacego nowy klucz;
- testy: tests/test_makefile.sh (config-backup, restore-config, FIRST_RUN,
  mount), scripts/test-rclone.sh §3b + busybox ash;
- docs: backup-i-rclone.md, architektura.md, przenosiny-serwera.md,
  komendy.md, CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UJ23Rb1c5UtxHTfAke9ENQ
@mpasternak
mpasternak merged commit ff6a6f8 into main Oct 24, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant