mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-11-09 02:13:38 +00:00
[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:
66 files changed
+15214
-97
No files matched your search
+133
-83
@@ -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;
|
||||
}
|
||||
@@ -495,4 +495,16 @@ input::placeholder {
|
||||
}
|
||||
.btn-light, .btn-light:hover {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
/* native time picker icon and popup in dark mode */
|
||||
input[type="time"] {
|
||||
color-scheme: dark;
|
||||
}
|
||||
/* switches while off: a light knob and a visible border (Bootstrap's dark knob is for light pages, the dark mode
|
||||
does not set data-bs-theme) */
|
||||
.form-switch .form-check-input:not(:checked):not(:focus) {
|
||||
--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.6%29'/%3e%3c/svg%3e");
|
||||
}
|
||||
.form-switch .form-check-input:not(:checked) {
|
||||
border-color: var(--mc-btn-outline-border);
|
||||
}
|
||||
Reference in new issue
Block a user