[Web][Restic][Dovecot][Dockerapi] Add restic backups with restore in the UI

- Scheduled, encrypted backups to S3, SFTP, REST or a local folder (new restic-mailcow container)
- Restore of mailboxes and whole domains in the UI, also deleted ones, for admins and domain admins
- Scope set by RESTIC_BACKUP_MODE in mailcow.conf (all, data, config)
- Optional backup before updates (update.sh), helper-scripts/restic.sh for a full restore
This commit is contained in:
FreddleSpl0it committed 2026-11-08 22:56:27 +01:00
1 parent a64ee13670
commit 6cf0390d58
66 files changed
+15214 -97

No files matched your search

+133 -83
View File
@@ -1,83 +1,133 @@
.pagination a {
text-decoration: none !important;
}
.panel.panel-default {
overflow: visible !important;
}
.table-responsive {
overflow: visible !important;
}
.table-responsive {
overflow-x: scroll !important;
}
body {
overflow-y:scroll;
}
/* Fix modal moving content left */
body.modal-open {
overflow-y:scroll;
padding-right: inherit !important;
}
@media (min-width: 992px) {
.container {
width: 80%;
}
}
.mass-actions-admin {
user-select: none;
}
.inputMissingAttr {
border-color: #FF4136;
}
.rotate {
-moz-transition: all 0.3s linear;
-webkit-transition: all 0.3s linear;
transition: all 0.3s linear;
}
.rotate.animation {
-ms-transform:rotateX(180deg);
-moz-transform:rotateX(180deg);
-webkit-transform:rotateX(180deg);
transform:rotateX(180deg);
}
.anchor {
display: block;
height: 65px;
margin-top: -65px;
visibility: hidden;
}
.thumbnail img {
min-height:100px;
height:100px;
}
.nav-tabs>li>a {
z-index: 1;
}
.table-condensed .input-sm {
width: 100%!important;
}
.table-condensed > thead > tr > th, .table-condensed > tbody > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > thead > tr > td, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > td {
padding: 3px;
}
table tbody tr td input[type="checkbox"] {
cursor: pointer;
}
#quarantine_template {
margin:20px;
}
.regex-input {
font-family: Consolas,monaco,monospace;
font-size: 1rem;
}
.label-keys {
font-size:100%;
margin: 0px !important;
white-space: normal !important;
}
.key-action {
font-weight:bold;
color:white !important;
}
.dkim-label {
margin: 0 0 8px !important;
}
.pagination a {
text-decoration: none !important;
}
.panel.panel-default {
overflow: visible !important;
}
.table-responsive {
overflow: visible !important;
}
.table-responsive {
overflow-x: scroll !important;
}
body {
overflow-y:scroll;
}
/* Fix modal moving content left */
body.modal-open {
overflow-y:scroll;
padding-right: inherit !important;
}
@media (min-width: 992px) {
.container {
width: 80%;
}
}
.mass-actions-admin {
user-select: none;
}
.inputMissingAttr {
border-color: #FF4136;
}
.rotate {
-moz-transition: all 0.3s linear;
-webkit-transition: all 0.3s linear;
transition: all 0.3s linear;
}
.rotate.animation {
-ms-transform:rotateX(180deg);
-moz-transform:rotateX(180deg);
-webkit-transform:rotateX(180deg);
transform:rotateX(180deg);
}
.anchor {
display: block;
height: 65px;
margin-top: -65px;
visibility: hidden;
}
.thumbnail img {
min-height:100px;
height:100px;
}
.nav-tabs>li>a {
z-index: 1;
}
.table-condensed .input-sm {
width: 100%!important;
}
.table-condensed > thead > tr > th, .table-condensed > tbody > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > thead > tr > td, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > td {
padding: 3px;
}
table tbody tr td input[type="checkbox"] {
cursor: pointer;
}
#quarantine_template {
margin:20px;
}
.regex-input {
font-family: Consolas,monaco,monospace;
font-size: 1rem;
}
.label-keys {
font-size:100%;
margin: 0px !important;
white-space: normal !important;
}
.key-action {
font-weight:bold;
color:white !important;
}
.dkim-label {
margin: 0 0 8px !important;
}
/* backup schedule: the weekday toggles and the remove buttons of the entries react to the mouse, in every theme */
.backup-schedule-days .btn:hover {
background-image: linear-gradient(rgba(128, 128, 128, .3), rgba(128, 128, 128, .3));
}
.backup-schedule-remove {
opacity: .6;
}
.backup-schedule-remove:hover, .backup-schedule-remove:focus-visible {
opacity: 1;
color: var(--bs-danger) !important;
}
/* result and log of a backup job: the border of the theme in light and dark mode (Bootstrap's .border stays light) */
.backup-pre {
border: 1px solid var(--mc-border);
}
/* result of a restore job: an entry to open per mailbox, numbers in columns */
.backup-result {
border: 1px solid var(--mc-border);
}
.backup-result > details + details {
border-top: 1px solid var(--mc-border);
}
.backup-result summary {
list-style: none;
cursor: pointer;
}
.backup-result summary::-webkit-details-marker {
display: none;
}
.backup-result summary:hover {
background-image: linear-gradient(rgba(128, 128, 128, .12), rgba(128, 128, 128, .12));
}
.backup-result summary .bi-chevron-right {
transition: transform .15s;
}
.backup-result details[open] > summary .bi-chevron-right {
transform: rotate(90deg);
}
.backup-result-body {
padding-left: 2.6rem !important;
}
.backup-result-body .table {
--bs-table-bg: transparent;
}
.backup-result-body .num {
width: 8.5rem;
text-align: right;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}