mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-01-04 03:48:28 +02:00
commit
3028a18a37
13
.github/ISSUE_TEMPLATE/pr_to_nighty_template.yml
vendored
Normal file
13
.github/ISSUE_TEMPLATE/pr_to_nighty_template.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
## :memo: Brief description
|
||||
<!-- Diff summary - START -->
|
||||
<!-- Diff summary - END -->
|
||||
|
||||
|
||||
## :computer: Commits
|
||||
<!-- Diff commits - START -->
|
||||
<!-- Diff commits - END -->
|
||||
|
||||
|
||||
## :file_folder: Modified files
|
||||
<!-- Diff files - START -->
|
||||
<!-- Diff files - END -->
|
@ -14,7 +14,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Mark/Close Stale Issues and Pull Requests 🗑️
|
||||
uses: actions/stale@v6.0.0
|
||||
uses: actions/stale@v6.0.1
|
||||
with:
|
||||
repo-token: ${{ secrets.STALE_ACTION_PAT }}
|
||||
days-before-stale: 60
|
||||
|
25
.github/workflows/pr_to_nightly.yml
vendored
Normal file
25
.github/workflows/pr_to_nightly.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: Create PR to merge to nightly from staging
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- staging
|
||||
jobs:
|
||||
action-pull-request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run the Action
|
||||
uses: devops-infra/action-pull-request@v0.5.1
|
||||
with:
|
||||
github_token: ${{ secrets.PRTONIGHTLY_ACTION_PAT }}
|
||||
title: Automatic PR to nightly from ${{ github.event.repository.updated_at}}
|
||||
assignee: DerLinkman
|
||||
source_branch: staging
|
||||
target_branch: nightly
|
||||
reviewer: DerLinkman
|
||||
label: upstream
|
||||
template: .github/ISSUE_TEMPLATE/pr_to_nighty_template.yml
|
||||
get_diff: true
|
3
data/Dockerfiles/backup/Dockerfile
Normal file
3
data/Dockerfiles/backup/Dockerfile
Normal file
@ -0,0 +1,3 @@
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
RUN apt update && apt install pigz
|
@ -252,7 +252,7 @@ def permBan(net, unban=False):
|
||||
if rule not in chain.rules and not unban:
|
||||
logCrit('Add host/network %s to blacklist' % net)
|
||||
chain.insert_rule(rule)
|
||||
r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time())))
|
||||
r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time())))
|
||||
elif rule in chain.rules and unban:
|
||||
logCrit('Remove host/network %s from blacklist' % net)
|
||||
chain.delete_rule(rule)
|
||||
@ -267,7 +267,7 @@ def permBan(net, unban=False):
|
||||
if rule not in chain.rules and not unban:
|
||||
logCrit('Add host/network %s to blacklist' % net)
|
||||
chain.insert_rule(rule)
|
||||
r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time())))
|
||||
r.hset('F2B_PERM_BANS', '%s' % net, int(round(time.time())))
|
||||
elif rule in chain.rules and unban:
|
||||
logCrit('Remove host/network %s from blacklist' % net)
|
||||
chain.delete_rule(rule)
|
||||
@ -346,6 +346,8 @@ def snat4(snat_target):
|
||||
rule.dst = '!' + rule.src
|
||||
target = rule.create_target("SNAT")
|
||||
target.to_source = snat_target
|
||||
match = rule.create_match("comment")
|
||||
match.comment = f'{int(round(time.time()))}'
|
||||
return rule
|
||||
|
||||
while not quit_now:
|
||||
@ -356,19 +358,26 @@ def snat4(snat_target):
|
||||
table.refresh()
|
||||
chain = iptc.Chain(table, 'POSTROUTING')
|
||||
table.autocommit = False
|
||||
if get_snat4_rule() not in chain.rules:
|
||||
logCrit('Added POSTROUTING rule for source network %s to SNAT target %s' % (get_snat4_rule().src, snat_target))
|
||||
chain.insert_rule(get_snat4_rule())
|
||||
table.commit()
|
||||
else:
|
||||
for position, item in enumerate(chain.rules):
|
||||
if item == get_snat4_rule():
|
||||
if position != 0:
|
||||
chain.delete_rule(get_snat4_rule())
|
||||
table.commit()
|
||||
new_rule = get_snat4_rule()
|
||||
for position, rule in enumerate(chain.rules):
|
||||
match = all((
|
||||
new_rule.get_src() == rule.get_src(),
|
||||
new_rule.get_dst() == rule.get_dst(),
|
||||
new_rule.target.parameters == rule.target.parameters,
|
||||
new_rule.target.name == rule.target.name
|
||||
))
|
||||
if position == 0:
|
||||
if not match:
|
||||
logInfo(f'Added POSTROUTING rule for source network {new_rule.src} to SNAT target {snat_target}')
|
||||
chain.insert_rule(new_rule)
|
||||
else:
|
||||
if match:
|
||||
logInfo(f'Remove rule for source network {new_rule.src} to SNAT target {snat_target} from POSTROUTING chain at position {position}')
|
||||
chain.delete_rule(rule)
|
||||
table.commit()
|
||||
table.autocommit = True
|
||||
except:
|
||||
print('Error running SNAT4, retrying...')
|
||||
print('Error running SNAT4, retrying...')
|
||||
|
||||
def snat6(snat_target):
|
||||
global lock
|
||||
@ -402,7 +411,7 @@ def snat6(snat_target):
|
||||
table.commit()
|
||||
table.autocommit = True
|
||||
except:
|
||||
print('Error running SNAT6, retrying...')
|
||||
print('Error running SNAT6, retrying...')
|
||||
|
||||
def autopurge():
|
||||
while not quit_now:
|
||||
@ -468,7 +477,7 @@ def whitelistUpdate():
|
||||
if Counter(new_whitelist) != Counter(WHITELIST):
|
||||
WHITELIST = new_whitelist
|
||||
logInfo('Whitelist was changed, it has %s entries' % len(WHITELIST))
|
||||
time.sleep(60.0 - ((time.time() - start_time) % 60.0))
|
||||
time.sleep(60.0 - ((time.time() - start_time) % 60.0))
|
||||
|
||||
def blacklistUpdate():
|
||||
global quit_now
|
||||
@ -479,7 +488,7 @@ def blacklistUpdate():
|
||||
new_blacklist = []
|
||||
if list:
|
||||
new_blacklist = genNetworkList(list)
|
||||
if Counter(new_blacklist) != Counter(BLACKLIST):
|
||||
if Counter(new_blacklist) != Counter(BLACKLIST):
|
||||
addban = set(new_blacklist).difference(BLACKLIST)
|
||||
delban = set(BLACKLIST).difference(new_blacklist)
|
||||
BLACKLIST = new_blacklist
|
||||
@ -490,7 +499,7 @@ def blacklistUpdate():
|
||||
if delban:
|
||||
for net in delban:
|
||||
permBan(net=net, unban=True)
|
||||
time.sleep(60.0 - ((time.time() - start_time) % 60.0))
|
||||
time.sleep(60.0 - ((time.time() - start_time) % 60.0))
|
||||
|
||||
def initChain():
|
||||
# Is called before threads start, no locking
|
||||
|
2
data/web/css/build/007-languages.min.css
vendored
2
data/web/css/build/007-languages.min.css
vendored
File diff suppressed because one or more lines are too long
@ -195,9 +195,65 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/sessions.inc.php';
|
||||
// Set language
|
||||
if (!isset($_SESSION['mailcow_locale']) && !isset($_COOKIE['mailcow_locale'])) {
|
||||
if ($DETECT_LANGUAGE && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
$header_lang = strtolower(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2));
|
||||
if (array_key_exists($header_lang, $AVAILABLE_LANGUAGES)) {
|
||||
$_SESSION['mailcow_locale'] = $header_lang;
|
||||
// regex inspired from @GabrielAnderson on http://stackoverflow.com/questions/6038236/http-accept-language
|
||||
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})*)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
|
||||
|
||||
$langs = $lang_parse[1];
|
||||
$ranks = $lang_parse[4];
|
||||
|
||||
// (create an associative array 'language' => 'preference')
|
||||
$lang2pref = array();
|
||||
for ($i=0; $i<count($langs); $i++) {
|
||||
$lang2pref[strtolower($langs[$i])] = (float) (!empty($ranks[$i]) ? $ranks[$i] : 1);
|
||||
}
|
||||
|
||||
// (comparison function for uksort)
|
||||
$cmpLangs = function ($a, $b) use ($lang2pref) {
|
||||
if ($lang2pref[$a] > $lang2pref[$b])
|
||||
return -1;
|
||||
elseif ($lang2pref[$a] < $lang2pref[$b])
|
||||
return 1;
|
||||
elseif (strlen($a) > strlen($b))
|
||||
return -1;
|
||||
elseif (strlen($a) < strlen($b))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
};
|
||||
|
||||
// sort the languages by prefered language and by the most specific region
|
||||
uksort($lang2pref, $cmpLangs);
|
||||
|
||||
// generate language array without the region part
|
||||
$AVAILABLE_BASE_LANGUAGES=array();
|
||||
foreach ($AVAILABLE_LANGUAGES as $code => $lang) {
|
||||
$base_code = substr($code, 0, 2);
|
||||
if (!array_key_exists($base_code, $AVAILABLE_BASE_LANGUAGES)) {
|
||||
$AVAILABLE_BASE_LANGUAGES[$base_code] = $code;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a perfect match or partial match
|
||||
// Match en-gb or en
|
||||
foreach ($lang2pref as $lang => $q) {
|
||||
if (array_key_exists($lang, $AVAILABLE_LANGUAGES)) {
|
||||
$_SESSION['mailcow_locale'] = $lang;
|
||||
break;
|
||||
} elseif (array_key_exists($lang, $AVAILABLE_BASE_LANGUAGES)) {
|
||||
$_SESSION['mailcow_locale'] = $AVAILABLE_BASE_LANGUAGES[$lang];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Try suggest match
|
||||
// e.g. suggest en-gb when only en-us is provided
|
||||
if (!isset($_COOKIE['mailcow_locale'])) {
|
||||
foreach ($lang2pref as $lang => $q) {
|
||||
if (array_key_exists(substr($lang, 0, 2), $AVAILABLE_BASE_LANGUAGES)) {
|
||||
$_SESSION['mailcow_locale'] = $AVAILABLE_BASE_LANGUAGES[substr($lang, 0, 2)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -215,7 +271,7 @@ if (isset($_GET['lang']) && array_key_exists($_GET['lang'], $AVAILABLE_LANGUAGES
|
||||
/*
|
||||
* load language
|
||||
*/
|
||||
$lang = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/lang/lang.en.json'), true);
|
||||
$lang = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/lang/lang.en-gb.json'), true);
|
||||
|
||||
$langFile = $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'.json';
|
||||
if(file_exists($langFile)) {
|
||||
|
@ -76,33 +76,35 @@ $autodiscover_config = array(
|
||||
$DETECT_LANGUAGE = true;
|
||||
|
||||
// Change default language
|
||||
$DEFAULT_LANG = 'en';
|
||||
$DEFAULT_LANG = 'en-gb';
|
||||
|
||||
// Available languages
|
||||
// https://www.iso.org/obp/ui/#search
|
||||
// https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
||||
// https://en.wikipedia.org/wiki/IETF_language_tag
|
||||
$AVAILABLE_LANGUAGES = array(
|
||||
'cs' => 'Čeština (Czech)',
|
||||
'da' => 'Danish (Dansk)',
|
||||
'de' => 'Deutsch (German)',
|
||||
'en' => 'English',
|
||||
'es' => 'Español (Spanish)',
|
||||
'fi' => 'Suomi (Finish)',
|
||||
'fr' => 'Français (French)',
|
||||
'hu' => 'Magyar (Hungarian)',
|
||||
'it' => 'Italiano (Italian)',
|
||||
'ko' => '한국어 (Korean)',
|
||||
'lv' => 'latviešu (Latvian)',
|
||||
'nl' => 'Nederlands (Dutch)',
|
||||
'pl' => 'Język Polski (Polish)',
|
||||
'pt' => 'Português (Portuguese)',
|
||||
'ro' => 'Română (Romanian)',
|
||||
'ru' => 'Pусский (Russian)',
|
||||
'sk' => 'Slovenčina (Slovak)',
|
||||
'sv' => 'Svenska (Swedish)',
|
||||
'tr' => 'Türkçe (Turkish)',
|
||||
'uk' => 'Українська (Ukrainian)',
|
||||
'zh' => '中文 (Chinese)'
|
||||
// 'ca-es' => 'Català (Catalan)',
|
||||
'cs-cz' => 'Čeština (Czech)',
|
||||
'da-dk' => 'Danish (Dansk)',
|
||||
'de-de' => 'Deutsch (German)',
|
||||
'en-gb' => 'English',
|
||||
'es-es' => 'Español (Spanish)',
|
||||
'fi-fi' => 'Suomi (Finish)',
|
||||
'fr-fr' => 'Français (French)',
|
||||
'hu-hu' => 'Magyar (Hungarian)',
|
||||
'it-it' => 'Italiano (Italian)',
|
||||
'ko-kr' => '한국어 (Korean)',
|
||||
'lv-lv' => 'latviešu (Latvian)',
|
||||
'nl-nl' => 'Nederlands (Dutch)',
|
||||
'pl-pl' => 'Język Polski (Polish)',
|
||||
'pt-pt' => 'Português (Portuguese)',
|
||||
'ro-ro' => 'Română (Romanian)',
|
||||
'ru-ru' => 'Pусский (Russian)',
|
||||
'sk-sk' => 'Slovenčina (Slovak)',
|
||||
'sv-se' => 'Svenska (Swedish)',
|
||||
'tr-tr' => 'Türkçe (Turkish)',
|
||||
'uk-ua' => 'Українська (Ukrainian)',
|
||||
'zh-cn' => '简体中文 (Simplified Chinese)',
|
||||
'zh-tw' => '繁體中文 (Traditional Chinese)',
|
||||
);
|
||||
|
||||
// Change theme (default: lumen)
|
||||
|
1187
data/web/lang/lang.zh-tw.json
Normal file
1187
data/web/lang/lang.zh-tw.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -32,12 +32,12 @@
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{% if mailcow_locale %}
|
||||
<li class="dropdown{% if available_languages|length == 1 %}lang-link-disabled{% endif %}">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="flag-icon flag-icon-{{ mailcow_locale }}"></span><span class="caret"></span></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="flag-icon flag-icon-{{ mailcow_locale[-2:] }}"></span><span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
{% for key, val in available_languages %}
|
||||
<li{% if mailcow_locale == key %} class="active"{% endif %}>
|
||||
<a href="?{{ query_string({'lang': key}) }}">
|
||||
<span class="flag-icon flag-icon-{{ key }}"></span>{{ val }}
|
||||
<span class="flag-icon flag-icon-{{ key[-2:] }}"></span>{{ val }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
@ -45,13 +45,13 @@
|
||||
</div>
|
||||
{% if not oauth2_request %}
|
||||
<button type="button" {% if available_languages|length == 1 %}disabled="true"{% endif %} class="btn btn-xs-lg btn-default pull-right dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="flag-icon flag-icon-{{ mailcow_locale }}"></span> <span class="caret"></span>
|
||||
<span class="flag-icon flag-icon-{{ mailcow_locale[-2:] }}"></span> <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu pull-right login">
|
||||
{% for key, val in available_languages %}
|
||||
<li{% if mailcow_locale == key %} class="active"{% endif %}>
|
||||
<a href="?{{ query_string({'lang': key}) }}">
|
||||
<span class="flag-icon flag-icon-{{ key }}"></span>{{ val }}
|
||||
<span class="flag-icon flag-icon-{{ key[-2:] }}"></span>{{ val }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
@ -41,7 +41,7 @@ services:
|
||||
- mysql
|
||||
|
||||
redis-mailcow:
|
||||
image: redis:6-alpine
|
||||
image: redis:7-alpine
|
||||
volumes:
|
||||
- redis-vol-1:/data/
|
||||
restart: always
|
||||
@ -76,7 +76,7 @@ services:
|
||||
- clamd
|
||||
|
||||
rspamd-mailcow:
|
||||
image: mailcow/rspamd:1.90
|
||||
image: mailcow/rspamd:1.91
|
||||
stop_grace_period: 30s
|
||||
depends_on:
|
||||
- dovecot-mailcow
|
||||
|
@ -26,7 +26,7 @@ if(empty($targetLang)) {
|
||||
}
|
||||
|
||||
// load master lang
|
||||
$masterLang = file_get_contents(__DIR__.'/../data/web/lang/lang.en.json');
|
||||
$masterLang = file_get_contents(__DIR__.'/../data/web/lang/lang.en-gb.json');
|
||||
$masterLang = json_decode($masterLang, true);
|
||||
|
||||
// load target lang
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
DEBIAN_DOCKER_IMAGE="debian:bullseye-slim"
|
||||
DEBIAN_DOCKER_IMAGE="mailcow/backup:1.0"
|
||||
|
||||
if [[ ! -z ${MAILCOW_BACKUP_LOCATION} ]]; then
|
||||
BACKUP_LOCATION="${MAILCOW_BACKUP_LOCATION}"
|
||||
@ -52,6 +52,15 @@ BACKUP_LOCATION=$(echo ${BACKUP_LOCATION} | sed 's#/$##')
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
COMPOSE_FILE=${SCRIPT_DIR}/../docker-compose.yml
|
||||
ENV_FILE=${SCRIPT_DIR}/../.env
|
||||
THREADS=$(echo ${THREADS:-1})
|
||||
|
||||
if ! [[ "${THREADS}" =~ ^[1-9]+$ ]] ; then
|
||||
echo "Thread input is not a number!"
|
||||
exit 1
|
||||
elif [[ "${THREADS}" =~ ^[1-9]+$ ]] ; then
|
||||
echo "Using ${THREADS} Thread(s) for this run."
|
||||
echo "Notice: You can set the Thread count with the THREADS Variable before you run this script."
|
||||
fi
|
||||
|
||||
if [ ! -f ${COMPOSE_FILE} ]; then
|
||||
echo "Compose file not found"
|
||||
@ -99,32 +108,32 @@ function backup() {
|
||||
docker run --name mailcow-backup --rm \
|
||||
-v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_vmail-vol-1$):/vmail:ro,z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="gzip --rsyncable" -Pcvpf /backup/backup_vmail.tar.gz /vmail
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_vmail.tar.gz /vmail
|
||||
;;&
|
||||
crypt|all)
|
||||
docker run --name mailcow-backup --rm \
|
||||
-v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_crypt-vol-1$):/crypt:ro,z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="gzip --rsyncable" -Pcvpf /backup/backup_crypt.tar.gz /crypt
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_crypt.tar.gz /crypt
|
||||
;;&
|
||||
redis|all)
|
||||
docker exec $(docker ps -qf name=redis-mailcow) redis-cli save
|
||||
docker run --name mailcow-backup --rm \
|
||||
-v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_redis-vol-1$):/redis:ro,z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="gzip --rsyncable" -Pcvpf /backup/backup_redis.tar.gz /redis
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_redis.tar.gz /redis
|
||||
;;&
|
||||
rspamd|all)
|
||||
docker run --name mailcow-backup --rm \
|
||||
-v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_rspamd-vol-1$):/rspamd:ro,z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="gzip --rsyncable" -Pcvpf /backup/backup_rspamd.tar.gz /rspamd
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_rspamd.tar.gz /rspamd
|
||||
;;&
|
||||
postfix|all)
|
||||
docker run --name mailcow-backup --rm \
|
||||
-v ${BACKUP_LOCATION}/mailcow-${DATE}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_postfix-vol-1$):/postfix:ro,z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="gzip --rsyncable" -Pcvpf /backup/backup_postfix.tar.gz /postfix
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --warning='no-file-ignored' --use-compress-program="pigz --rsyncable -p ${THREADS}" -Pcvpf /backup/backup_postfix.tar.gz /postfix
|
||||
;;&
|
||||
mysql|all)
|
||||
SQLIMAGE=$(grep -iEo '(mysql|mariadb)\:.+' ${COMPOSE_FILE})
|
||||
@ -191,7 +200,7 @@ function restore() {
|
||||
docker run -it --name mailcow-backup --rm \
|
||||
-v ${RESTORE_LOCATION}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_vmail-vol-1$):/vmail:z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar -Pxvzf /backup/backup_vmail.tar.gz
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --use-compress-program="pigz -d -p ${THREADS}" -Pxvf /backup/backup_vmail.tar.gz
|
||||
docker start $(docker ps -aqf name=dovecot-mailcow)
|
||||
echo
|
||||
echo "In most cases it is not required to run a full resync, you can run the command printed below at any time after testing wether the restore process broke a mailbox:"
|
||||
@ -210,7 +219,7 @@ function restore() {
|
||||
docker run -it --name mailcow-backup --rm \
|
||||
-v ${RESTORE_LOCATION}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_redis-vol-1$):/redis:z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar -Pxvzf /backup/backup_redis.tar.gz
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --use-compress-program="pigz -d -p ${THREADS}" -Pxvf /backup/backup_redis.tar.gz
|
||||
docker start $(docker ps -aqf name=redis-mailcow)
|
||||
;;
|
||||
crypt)
|
||||
@ -218,7 +227,7 @@ function restore() {
|
||||
docker run -it --name mailcow-backup --rm \
|
||||
-v ${RESTORE_LOCATION}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_crypt-vol-1$):/crypt:z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar -Pxvzf /backup/backup_crypt.tar.gz
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --use-compress-program="pigz -d -p ${THREADS}" -Pxvf /backup/backup_crypt.tar.gz
|
||||
docker start $(docker ps -aqf name=dovecot-mailcow)
|
||||
;;
|
||||
rspamd)
|
||||
@ -226,7 +235,7 @@ function restore() {
|
||||
docker run -it --name mailcow-backup --rm \
|
||||
-v ${RESTORE_LOCATION}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_rspamd-vol-1$):/rspamd:z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar -Pxvzf /backup/backup_rspamd.tar.gz
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --use-compress-program="pigz -d -p ${THREADS}" -Pxvf /backup/backup_rspamd.tar.gz
|
||||
docker start $(docker ps -aqf name=rspamd-mailcow)
|
||||
;;
|
||||
postfix)
|
||||
@ -234,7 +243,7 @@ function restore() {
|
||||
docker run -it --name mailcow-backup --rm \
|
||||
-v ${RESTORE_LOCATION}:/backup:z \
|
||||
-v $(docker volume ls -qf name=^${CMPS_PRJ}_postfix-vol-1$):/postfix:z \
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar -Pxvzf /backup/backup_postfix.tar.gz
|
||||
${DEBIAN_DOCKER_IMAGE} /bin/tar --use-compress-program="pigz -d -p ${THREADS}" -Pxvf /backup/backup_postfix.tar.gz
|
||||
docker start $(docker ps -aqf name=postfix-mailcow)
|
||||
;;
|
||||
mysql|mariadb)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
MASTER="en"
|
||||
MASTER="en-gb"
|
||||
|
||||
DIR = "#{__dir__}/.."
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user