Files

151 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
APP_ENV_FILE="${ROOT_DIR}/.env"
MAIL_ENV_FILE="${ROOT_DIR}/.env.mail"
MAIL_ENV_EXAMPLE="${ROOT_DIR}/.env.mail.example"
APP_COMPOSE_FILE="${ROOT_DIR}/compose.yaml"
MAIL_COMPOSE_FILE="${ROOT_DIR}/compose.mail.yaml"
MAIL_SERVICE="stalwart"
usage() {
cat <<'EOF'
Использование:
./scripts/mail-server.sh init
./scripts/mail-server.sh up
./scripts/mail-server.sh down
./scripts/mail-server.sh restart
./scripts/mail-server.sh status
./scripts/mail-server.sh logs
./scripts/mail-server.sh credentials
./scripts/mail-server.sh shell
Первый запуск:
1. ./scripts/mail-server.sh init
2. Проверь .env.mail
3. Создай A-запись mail.<домен> на IP сервера
4. ./scripts/mail-server.sh up
5. ./scripts/mail-server.sh credentials
6. Открой SSH-туннель к 127.0.0.1:8081 и заверши мастер настройки
EOF
}
fail() {
printf '[mail:error] %s\n' "$*" >&2
exit 1
}
log() {
printf '[mail] %s\n' "$*"
}
require_command() {
command -v "$1" >/dev/null 2>&1 || fail "Не найдена команда: $1"
}
mail_env_value() {
local key="$1"
grep -E "^${key}=" "$MAIL_ENV_FILE" | tail -n 1 | cut -d '=' -f 2- | sed -e 's/^"//' -e 's/"$//'
}
compose() {
local env_args=(--env-file "$MAIL_ENV_FILE")
if [[ -f "$APP_ENV_FILE" ]]; then
env_args=(--env-file "$APP_ENV_FILE" --env-file "$MAIL_ENV_FILE")
fi
docker compose \
"${env_args[@]}" \
-f "$APP_COMPOSE_FILE" \
-f "$MAIL_COMPOSE_FILE" \
--profile mail \
"$@"
}
init() {
if [[ -f "$MAIL_ENV_FILE" ]]; then
log "${MAIL_ENV_FILE} уже существует"
return
fi
cp "$MAIL_ENV_EXAMPLE" "$MAIL_ENV_FILE"
chmod 600 "$MAIL_ENV_FILE"
log "Создан ${MAIL_ENV_FILE}; проверь домен перед запуском"
}
validate_config() {
[[ -f "$MAIL_ENV_FILE" ]] || fail "Сначала выполни: ./scripts/mail-server.sh init"
local hostname
local domain
hostname="$(mail_env_value MAIL_HOSTNAME)"
domain="$(mail_env_value MAIL_DOMAIN)"
[[ -n "$hostname" ]] || fail "MAIL_HOSTNAME не задан в .env.mail"
[[ -n "$domain" ]] || fail "MAIL_DOMAIN не задан в .env.mail"
[[ "$hostname" == *."$domain" ]] || fail "MAIL_HOSTNAME должен принадлежать MAIL_DOMAIN"
}
show_credentials() {
compose logs "$MAIL_SERVICE" 2>&1 \
| sed -n '/bootstrap mode/,+20p' \
| tail -n 24
}
main() {
require_command docker
docker compose version >/dev/null 2>&1 || fail "Не найден Docker Compose Plugin"
local action="${1:-}"
case "$action" in
init)
init
;;
up)
validate_config
compose up -d "$MAIL_SERVICE"
log "Stalwart запущен"
log "Временные реквизиты: ./scripts/mail-server.sh credentials"
;;
down)
validate_config
compose stop "$MAIL_SERVICE"
;;
restart)
validate_config
compose restart "$MAIL_SERVICE"
;;
status)
validate_config
compose ps "$MAIL_SERVICE"
;;
logs)
validate_config
compose logs --tail=200 -f "$MAIL_SERVICE"
;;
credentials)
validate_config
show_credentials
;;
shell)
validate_config
compose exec "$MAIL_SERVICE" /bin/sh
;;
-h|--help|help)
usage
;;
*)
usage
exit 1
;;
esac
}
main "$@"