nordabiz/docs/architecture/diagrams/a8-backup-dr.drawio

162 lines
16 KiB
Plaintext

<mxfile host="draw.io" modified="2026-02-12" agent="Claude Code" type="device">
<diagram id="a8-backup-dr" name="Backup i Disaster Recovery">
<mxGraphModel dx="1400" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1600" pageHeight="1000" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="title" value="NordaBiz — Backup &amp; Disaster Recovery" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=22;fontStyle=1;fontColor=#1a1a2e;" vertex="1" parent="1">
<mxGeometry x="440" y="15" width="480" height="36" as="geometry"/>
</mxCell>
<mxCell id="subtitle" value="Strategia backupu, retencja danych i procedury odtwarzania po awarii" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=11;fontColor=#888;" vertex="1" parent="1">
<mxGeometry x="430" y="48" width="480" height="20" as="geometry"/>
</mxCell>
<!-- ŹRÓDŁO: PRODUKCJA -->
<mxCell id="prod_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E3F2FD;strokeColor=#1565C0;shadow=1;" vertex="1" parent="1">
<mxGeometry x="40" y="90" width="300" height="280" as="geometry"/>
</mxCell>
<mxCell id="prod_title" value="&lt;b style=&quot;font-size:15px;color:#1565C0&quot;&gt;Produkcja (VM 249)&lt;/b&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="55" y="96" width="200" height="26" as="geometry"/>
</mxCell>
<mxCell id="prod_db" value="&lt;b&gt;PostgreSQL&lt;/b&gt;&lt;br&gt;nordabiz (80+ tabel)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#1565C0;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="65" y="130" width="250" height="40" as="geometry"/>
</mxCell>
<mxCell id="prod_app" value="&lt;b&gt;Aplikacja Flask&lt;/b&gt;&lt;br&gt;Gunicorn :5000" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#1565C0;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="65" y="180" width="250" height="40" as="geometry"/>
</mxCell>
<mxCell id="prod_env" value="&lt;b&gt;.env&lt;/b&gt; — credentials, API keys" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#1565C0;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="65" y="230" width="250" height="32" as="geometry"/>
</mxCell>
<mxCell id="prod_code" value="&lt;b&gt;Kod źródłowy&lt;/b&gt; — Git (Gitea + GitHub)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#1565C0;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="65" y="270" width="250" height="32" as="geometry"/>
</mxCell>
<mxCell id="prod_cron" value="&lt;b&gt;Cron&lt;/b&gt; — harmonogram automatyczny" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#1565C0;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="65" y="310" width="250" height="32" as="geometry"/>
</mxCell>
<!-- BACKUP LOKALNY -->
<mxCell id="local_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E8F5E9;strokeColor=#2E7D32;shadow=1;" vertex="1" parent="1">
<mxGeometry x="440" y="90" width="340" height="280" as="geometry"/>
</mxCell>
<mxCell id="local_title" value="&lt;b style=&quot;font-size:15px;color:#2E7D32&quot;&gt;Backup Lokalny (VM 249)&lt;/b&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="455" y="96" width="260" height="26" as="geometry"/>
</mxCell>
<mxCell id="hourly" value="&lt;b style=&quot;color:#2E7D32&quot;&gt;Co godzinę&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;pg_dump -Fc (custom format)&lt;br&gt;Retencja: 24 godziny&lt;br&gt;/var/backups/nordabiz/hourly/&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#2E7D32;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="455" y="130" width="310" height="60" as="geometry"/>
</mxCell>
<mxCell id="daily" value="&lt;b style=&quot;color:#2E7D32&quot;&gt;Codziennie (02:00)&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;pg_dump -Fc (custom format)&lt;br&gt;Retencja: 30 dni&lt;br&gt;/var/backups/nordabiz/daily/&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#2E7D32;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="455" y="200" width="310" height="60" as="geometry"/>
</mxCell>
<mxCell id="config" value="&lt;b style=&quot;color:#2E7D32&quot;&gt;Konfiguracja (niedz. 03:00)&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;.env, systemd, nginx&lt;br&gt;Retencja: 4 tygodnie&lt;br&gt;/var/backups/nordabiz/config/&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#2E7D32;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="455" y="270" width="310" height="60" as="geometry"/>
</mxCell>
<!-- BACKUP OFFSITE -->
<mxCell id="offsite_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF3E0;strokeColor=#E65100;shadow=1;" vertex="1" parent="1">
<mxGeometry x="880" y="90" width="340" height="280" as="geometry"/>
</mxCell>
<mxCell id="offsite_title" value="&lt;b style=&quot;font-size:15px;color:#E65100&quot;&gt;Offsite (PBS 10.22.68.127)&lt;/b&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="895" y="96" width="280" height="26" as="geometry"/>
</mxCell>
<mxCell id="pbs_daily" value="&lt;b style=&quot;color:#E65100&quot;&gt;Kopia dzienna (rsync 04:00)&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Mirror /daily/ → PBS&lt;br&gt;Retencja: 30 dni&lt;br&gt;/backup/nordabiz/daily/&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#E65100;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="895" y="130" width="310" height="60" as="geometry"/>
</mxCell>
<mxCell id="pbs_config" value="&lt;b style=&quot;color:#E65100&quot;&gt;Kopia konfiguracji (rsync 04:30)&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Mirror /config/ → PBS&lt;br&gt;Retencja: 30 dni&lt;br&gt;/backup/nordabiz/config/&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#E65100;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="895" y="200" width="310" height="60" as="geometry"/>
</mxCell>
<mxCell id="pbs_vm" value="&lt;b style=&quot;color:#E65100&quot;&gt;VM Snapshots (Proxmox)&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Manualne (przed wdrożeniem)&lt;br&gt;Max 3 snapshoty&lt;br&gt;LVM/PBS storage&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#E65100;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="895" y="270" width="310" height="60" as="geometry"/>
</mxCell>
<!-- STRZAŁKI BACKUP -->
<mxCell id="arr1" value="pg_dump" style="rounded=1;strokeColor=#2E7D32;strokeWidth=2;fontSize=10;fontColor=#2E7D32;fontStyle=1;" edge="1" source="prod_bg" target="local_bg" parent="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="arr2" value="rsync" style="rounded=1;strokeColor=#E65100;strokeWidth=2;fontSize=10;fontColor=#E65100;fontStyle=1;" edge="1" source="local_bg" target="offsite_bg" parent="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<!-- SLA -->
<mxCell id="sla_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F3E5F5;strokeColor=#7B1FA2;shadow=1;" vertex="1" parent="1">
<mxGeometry x="40" y="420" width="300" height="140" as="geometry"/>
</mxCell>
<mxCell id="sla_title" value="&lt;b style=&quot;font-size:15px;color:#7B1FA2&quot;&gt;Cele SLA&lt;/b&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="55" y="426" width="100" height="26" as="geometry"/>
</mxCell>
<mxCell id="rto" value="&lt;b style=&quot;font-size:18px;color:#7B1FA2&quot;&gt;RTO: 30-60 min&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Recovery Time Objective&lt;br&gt;Czas przywrócenia do produkcji&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#7B1FA2;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="55" y="458" width="270" height="44" as="geometry"/>
</mxCell>
<mxCell id="rpo" value="&lt;b style=&quot;font-size:18px;color:#7B1FA2&quot;&gt;RPO: 1 godzina&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Recovery Point Objective&lt;br&gt;Maks. akceptowalna utrata danych&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#7B1FA2;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="55" y="508" width="270" height="44" as="geometry"/>
</mxCell>
<!-- SCENARIUSZE DR -->
<mxCell id="dr_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFEBEE;strokeColor=#C62828;shadow=1;" vertex="1" parent="1">
<mxGeometry x="380" y="420" width="840" height="220" as="geometry"/>
</mxCell>
<mxCell id="dr_title" value="&lt;b style=&quot;font-size:15px;color:#C62828&quot;&gt;Scenariusze Disaster Recovery&lt;/b&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="395" y="426" width="300" height="26" as="geometry"/>
</mxCell>
<mxCell id="sc1" value="&lt;b style=&quot;color:#C62828&quot;&gt;Uszkodzenie bazy&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;dr-restore.sh + hourly backup&lt;br&gt;&lt;b&gt;RTO: 15 min&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="395" y="460" width="195" height="55" as="geometry"/>
</mxCell>
<mxCell id="sc2" value="&lt;b style=&quot;color:#C62828&quot;&gt;Awaria VM&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Restart VM / rollback snapshot&lt;br&gt;&lt;b&gt;RTO: 5-10 min&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="600" y="460" width="195" height="55" as="geometry"/>
</mxCell>
<mxCell id="sc3" value="&lt;b style=&quot;color:#C62828&quot;&gt;Utrata całego VM&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Nowy VM + PBS restore&lt;br&gt;&lt;b&gt;RTO: 60 min&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="805" y="460" width="195" height="55" as="geometry"/>
</mxCell>
<mxCell id="sc4" value="&lt;b style=&quot;color:#C62828&quot;&gt;Ransomware&lt;/b&gt;&lt;br&gt;&lt;font style=&quot;font-size:10px&quot;&gt;Izolacja + nowy VM + PBS + rotacja kluczy&lt;br&gt;&lt;b&gt;RTO: 60-120 min&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#C62828;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="1010" y="460" width="195" height="55" as="geometry"/>
</mxCell>
<!-- RESTORE FLOW -->
<mxCell id="restore_title" value="&lt;b style=&quot;font-size:13px;color:#C62828&quot;&gt;Procedura przywracania (dr-restore.sh):&lt;/b&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="395" y="530" width="340" height="22" as="geometry"/>
</mxCell>
<mxCell id="step1" value="1. Stop&lt;br&gt;aplikacji" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFCDD2;strokeColor=#C62828;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="395" y="558" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="step2" value="2. Safety&lt;br&gt;backup" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFCDD2;strokeColor=#C62828;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="510" y="558" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="step3" value="3. Drop +&lt;br&gt;Restore DB" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFCDD2;strokeColor=#C62828;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="625" y="558" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="step4" value="4. GRANT&lt;br&gt;permissions" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFCDD2;strokeColor=#C62828;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="740" y="558" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="step5" value="5. Start +&lt;br&gt;Health check" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFCDD2;strokeColor=#C62828;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="855" y="558" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="step6" value="6. Weryfikacja&lt;br&gt;firm w bazie" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#C8E6C9;strokeColor=#2E7D32;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="970" y="558" width="100" height="40" as="geometry"/>
</mxCell>
<mxCell id="sarr1" style="strokeColor=#C62828;strokeWidth=2;" edge="1" source="step1" target="step2" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="sarr2" style="strokeColor=#C62828;strokeWidth=2;" edge="1" source="step2" target="step3" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="sarr3" style="strokeColor=#C62828;strokeWidth=2;" edge="1" source="step3" target="step4" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="sarr4" style="strokeColor=#C62828;strokeWidth=2;" edge="1" source="step4" target="step5" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="sarr5" style="strokeColor=#2E7D32;strokeWidth=2;" edge="1" source="step5" target="step6" parent="1"><mxGeometry relative="1" as="geometry"/></mxCell>
<!-- MONITORING -->
<mxCell id="mon_bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E0F7FA;strokeColor=#00838F;shadow=1;" vertex="1" parent="1">
<mxGeometry x="40" y="610" width="300" height="110" as="geometry"/>
</mxCell>
<mxCell id="mon_title" value="&lt;b style=&quot;font-size:15px;color:#00838F&quot;&gt;Monitoring Backupów&lt;/b&gt;" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="55" y="616" width="200" height="26" as="geometry"/>
</mxCell>
<mxCell id="mon1" value="&lt;font style=&quot;font-size:10px&quot;&gt;✓ Backup exists &amp;lt; 2h old&lt;br&gt;✓ Backup size ≥ 1 MB&lt;br&gt;✓ Size consistent (±50%)&lt;br&gt;✓ dr-restore.sh executable&lt;br&gt;✓ Cron job configured&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff;strokeColor=#00838F;fontSize=11;align=left;spacingLeft=8;" vertex="1" parent="1">
<mxGeometry x="55" y="646" width="270" height="66" as="geometry"/>
</mxCell>
<!-- PODSUMOWANIE -->
<mxCell id="summary" value="&lt;font style=&quot;font-size:11px;color:#888&quot;&gt;&lt;b&gt;3 warstwy backupu&lt;/b&gt; (lokalny godzinowy + lokalny dzienny + offsite PBS) &amp;nbsp;|&amp;nbsp; &lt;b&gt;RTO 15-60 min&lt;/b&gt; &amp;nbsp;|&amp;nbsp; &lt;b&gt;RPO 1h&lt;/b&gt; &amp;nbsp;|&amp;nbsp; Automatyczne testy zdrowia backupów&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="280" y="750" width="820" height="24" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>