| backup | ||
| compose/mail | ||
| config | ||
| data | ||
| scripts | ||
| README.md | ||
Perfekt. Dann bekommst du jetzt das komplette Zielbild fuer den Mailserver auf 10.100.20.16 mit:
- Zielstruktur auf der VM
- Repo-Struktur analog zu deinen Infra-Repos
- Compose-Dateien
- Config-Grundstruktur
- Scripts fuer Verzeichnisse und Deployment
- Certbot-Pfade passend zu
/srv/mail-fetch01/data/mailserver/certs/fullchain.pem/srv/mail-fetch01/data/mailserver/certs/privkey.pem
Ich halte es bewusst so, dass du es sauber ins Repo legen, pushen und auf der Mail-VM deployen kannst.
1. Zielbild
Dienste
mailservermit docker-mailserverdb-mailfuer Roundcuberoundcube
Domains
- Mailserver:
mail.theboxhub.ch - Webmail:
webmail.theboxhub.ch - Maildomain:
theboxhub.ch
DNS
mail.theboxhub.ch->10.100.20.16webmail.theboxhub.ch->10.100.20.10MX theboxhub.ch->mail.theboxhub.ch
Zertifikate lokal auf der Mail-VM
/srv/mail-fetch01/data/mailserver/certs/fullchain.pem/srv/mail-fetch01/data/mailserver/certs/privkey.pem
2. Repo-Struktur
Ich schlage fuer dein Repo vor:
/srv/workspace/infra/mail-fetch01/
├── backup
│ ├── compose
│ ├── databases
│ ├── mailserver
│ └── roundcube
├── compose
│ ├── mailserver
│ │ └── compose.yaml
│ ├── mariadb
│ │ └── compose.yaml
│ └── roundcube
│ └── compose.yaml
├── config
│ ├── mailserver
│ │ ├── postfix-main.cf
│ │ ├── postfix-master.cf
│ │ ├── dovecot.cf
│ │ ├── fetchmailrc
│ │ └── .gitkeep
│ ├── mariadb
│ │ └── .gitkeep
│ └── roundcube
│ └── .gitkeep
├── data
│ ├── mailserver
│ │ ├── certs
│ │ ├── config
│ │ ├── dkim
│ │ ├── logs
│ │ ├── maildata
│ │ └── state
│ ├── mariadb
│ │ └── .gitkeep
│ └── roundcube
│ └── .gitkeep
├── README.md
└── scripts
├── deploy.sh
└── init-dirs.sh
Wichtig:
- im Repo sind
data/...undbackup/...nur Strukturplatzhalter - echte produktive Daten liegen spaeter auf der VM unter
/srv/mail-fetch01/...
3. Repo-Struktur in code-server anlegen
Wenn du das Repo unter /srv/workspace/infra/mail-fetch01 vorbereitest:
cd /srv/workspace/infra
mkdir -p mail-fetch01
cd /srv/workspace/infra/mail-fetch01
mkdir -p backup/{compose,databases,mailserver,roundcube}
mkdir -p compose/{mailserver,mariadb,roundcube}
mkdir -p config/mailserver
mkdir -p config/{mariadb,roundcube}
mkdir -p data/mailserver/{certs,config,dkim,logs,maildata,state}
mkdir -p data/mariadb
mkdir -p data/roundcube
mkdir -p scripts
touch compose/mailserver/compose.yaml
touch compose/mariadb/compose.yaml
touch compose/roundcube/compose.yaml
touch config/mailserver/postfix-main.cf
touch config/mailserver/postfix-master.cf
touch config/mailserver/dovecot.cf
touch config/mailserver/fetchmailrc
touch config/mariadb/.gitkeep
touch config/roundcube/.gitkeep
touch data/mailserver/certs/.gitkeep
touch data/mailserver/config/.gitkeep
touch data/mailserver/dkim/.gitkeep
touch data/mailserver/logs/.gitkeep
touch data/mailserver/maildata/.gitkeep
touch data/mailserver/state/.gitkeep
touch data/mariadb/.gitkeep
touch data/roundcube/.gitkeep
touch scripts/init-dirs.sh
touch scripts/deploy.sh
touch README.md
4. Zielstruktur auf der Mail-VM
Das wird spaeter durch init-dirs.sh erzeugt:
/srv/mail-fetch01/
├── backup
│ ├── compose
│ ├── databases
│ ├── mailserver
│ └── roundcube
├── compose
│ ├── mailserver
│ ├── mariadb
│ └── roundcube
├── config
│ ├── mailserver
│ ├── mariadb
│ └── roundcube
└── data
├── mailserver
│ ├── certs
│ ├── config
│ ├── dkim
│ ├── logs
│ ├── maildata
│ └── state
├── mariadb
└── roundcube
5. scripts/init-dirs.sh
Datei:
/srv/workspace/infra/mail-fetch01/scripts/init-dirs.sh
#!/usr/bin/env bash
set -euo pipefail
echo "Erstelle Verzeichnisstruktur unter /srv/mail-fetch01 ..."
sudo mkdir -p /srv/mail-fetch01/backup/{compose,databases,mailserver,roundcube}
sudo mkdir -p /srv/mail-fetch01/compose/{mailserver,mariadb,roundcube}
sudo mkdir -p /srv/mail-fetch01/config/{mailserver,mariadb,roundcube}
sudo mkdir -p /srv/mail-fetch01/data/mailserver/{certs,config,dkim,logs,maildata,state}
sudo mkdir -p /srv/mail-fetch01/data/mariadb
sudo mkdir -p /srv/mail-fetch01/data/roundcube
echo "Setze Besitz auf aktuellen Benutzer: $USER"
sudo chown -R "$USER:$USER" /srv/mail-fetch01
echo "Fertig."
tree /srv/mail-fetch01 || true
Ausfuehrbar machen:
chmod +x /srv/workspace/infra/mail-fetch01/scripts/init-dirs.sh
6. scripts/deploy.sh
Datei:
/srv/workspace/infra/mail-fetch01/scripts/deploy.sh
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="/srv/workspace/infra/mail-fetch01"
TARGET_ROOT="/srv/mail-fetch01"
echo "Deploye Compose-Dateien ..."
sudo mkdir -p "$TARGET_ROOT/compose"
sudo cp -r "$REPO_ROOT/compose/." "$TARGET_ROOT/compose/"
echo "Deploye Konfigurationen ..."
sudo mkdir -p "$TARGET_ROOT/config"
sudo cp -r "$REPO_ROOT/config/." "$TARGET_ROOT/config/"
echo "Setze Besitz auf aktuellen Benutzer: $USER"
sudo chown -R "$USER:$USER" "$TARGET_ROOT"
echo "Fertig."
Ausfuehrbar machen:
chmod +x /srv/workspace/infra/mail-fetch01/scripts/deploy.sh
7. Compose mailserver
Datei:
/srv/workspace/infra/mail-fetch01/compose/mailserver/compose.yaml
x-logging: &default-logging
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
mailserver:
image: mailserver/docker-mailserver:latest
container_name: mailserver
hostname: mail
domainname: theboxhub.ch
restart: unless-stopped
stop_grace_period: 1m
dns:
- 10.100.20.49
- 1.1.1.1
environment:
TZ: Europe/Zurich
ENABLE_FETCHMAIL: 1
FETCHMAIL_POLL: 60
OVERTAKE_IP: 1
ENABLE_SPAMASSASSIN: 1
ENABLE_CLAMAV: 0
SSL_TYPE: manual
SSL_CERT_PATH: /etc/letsencrypt/live/mailserver/fullchain.pem
SSL_KEY_PATH: /etc/letsencrypt/live/mailserver/privkey.pem
PERMIT_DOCKER: connected-networks
ONE_DIR: 1
DMS_DEBUG: 0
ports:
- "25:25"
- "143:143"
- "465:465"
- "587:587"
- "993:993"
volumes:
- /srv/mail-fetch01/data/mailserver/maildata:/var/mail
- /srv/mail-fetch01/data/mailserver/config:/tmp/docker-mailserver
- /srv/mail-fetch01/data/mailserver/state:/var/mail-state
- /srv/mail-fetch01/data/mailserver/logs:/var/log/mail
- /srv/mail-fetch01/data/mailserver/dkim:/etc/opendkim/keys
- /srv/mail-fetch01/data/mailserver/certs/fullchain.pem:/etc/letsencrypt/live/mailserver/fullchain.pem:ro
- /srv/mail-fetch01/data/mailserver/certs/privkey.pem:/etc/letsencrypt/live/mailserver/privkey.pem:ro
cap_add:
- NET_ADMIN
- SYS_PTRACE
healthcheck:
test: ["CMD-SHELL", "ss -ltn | grep -q ':25' || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
logging: *default-logging
8. Compose MariaDB fuer Roundcube
Datei:
/srv/workspace/infra/mail-fetch01/compose/mariadb/compose.yaml
x-logging: &default-logging
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
db-mail:
image: mariadb:10.11
container_name: db-mail
restart: unless-stopped
environment:
TZ: Europe/Zurich
MYSQL_ROOT_PASSWORD: "MAILROOT_4mK9pL2xT7vQ1cD8"
MYSQL_DATABASE: "roundcube"
MYSQL_USER: "roundcube"
MYSQL_PASSWORD: "RCPASS_7xL2mQ9tK4pD1cV8"
volumes:
- /srv/mail-fetch01/data/mariadb:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
logging: *default-logging
9. Compose Roundcube
Datei:
/srv/workspace/infra/mail-fetch01/compose/roundcube/compose.yaml
x-logging: &default-logging
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
roundcube:
image: roundcube/roundcubemail:latest
container_name: roundcube
restart: unless-stopped
environment:
TZ: Europe/Zurich
ROUNDCUBEMAIL_DB_TYPE: mysql
ROUNDCUBEMAIL_DB_HOST: db-mail
ROUNDCUBEMAIL_DB_NAME: roundcube
ROUNDCUBEMAIL_DB_USER: roundcube
ROUNDCUBEMAIL_DB_PASSWORD: "RCPASS_7xL2mQ9tK4pD1cV8"
ROUNDCUBEMAIL_SKIN: elastic
ROUNDCUBEMAIL_DEFAULT_HOST: "tls://mail.theboxhub.ch"
ROUNDCUBEMAIL_DEFAULT_PORT: 143
ROUNDCUBEMAIL_SMTP_SERVER: "tls://mail.theboxhub.ch"
ROUNDCUBEMAIL_SMTP_PORT: 587
ROUNDCUBEMAIL_IMAP_CONN_OPTIONS: '{"ssl":{"verify_peer":false,"verify_peer_name":false,"allow_self_signed":true}}'
ROUNDCUBEMAIL_SMTP_CONN_OPTIONS: '{"ssl":{"verify_peer":false,"verify_peer_name":false,"allow_self_signed":true}}'
ports:
- "8080:80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 5
start_period: 20s
logging: *default-logging
Wichtig:
- NPM soll spaeter
webmail.theboxhub.chauf10.100.20.16:8080weiterleiten.
10. Wichtiger Hinweis zu den getrennten Compose-Dateien
Da du drei getrennte Compose-Dateien willst, brauchen die Dienste fuer roundcube und db-mail einen gemeinsamen Compose-Kontext oder ein gemeinsames Netz.
Am saubersten gibt es dafuer zwei Wege:
Variante A - alles in eine gemeinsame Mail-Compose
Einfacher im Betrieb.
Variante B - externes Docker-Netz
Sauber getrennt, aber etwas mehr Aufwand.
Da du explizit nach Compose, Struktur und Config fragst, empfehle ich fuer Mail hier klar:
Empfehlung
Mailserver, Roundcube und DB in eine gemeinsame Compose-Datei packen.
Das ist fuer dieses Stack viel robuster.
Wenn du willst, kannst du die Repo-Struktur trotzdem getrennt behalten, aber technisch ist eine einzige compose/mail/compose.yaml besser.
11. Deshalb meine echte Empfehlung: eine gemeinsame Mail-Compose
Wenn du es operativ sauber willst, nimm statt 3 Dateien besser diese Struktur:
compose/
└── mail
└── compose.yaml
Mit allen 3 Services zusammen.
Wenn du willst, schreibe ich dir diese Gesamtdatei sofort.
Das ist fuer dein Setup deutlich praktischer als drei isolierte Stacks.
12. Mailserver-Configstruktur
Fuer docker-mailserver liegen die aktiven Dateien unter:
/srv/mail-fetch01/data/mailserver/config/
Im Repo koennen wir Vorlagen unter:
/srv/workspace/infra/mail-fetch01/config/mailserver/
ablegen.
Minimal noetig
postfix-main.cfpostfix-master.cfdovecot.cffetchmailrc
Hinweis:
docker-mailserver braucht nicht zwingend alle davon. Vieles kann ueber setup und Standardconfig laufen.
13. fetchmailrc Vorlage
Datei:
/srv/workspace/infra/mail-fetch01/config/mailserver/fetchmailrc
set daemon 60
set syslog
poll imap.example.com with proto IMAP
user "dein.externes.postfach@example.com" there with password "DEIN_EXTERNES_PASSWORT" is "jonas@theboxhub.ch" here
ssl
fetchall
Wichtig:
- das ist nur eine Vorlage
- Rechte spaeter auf der Ziel-VM unbedingt restriktiv setzen:
chmod 600 /srv/mail-fetch01/config/mailserver/fetchmailrc
14. Zertifikate
Du hast bestaetigt:
/srv/mail-fetch01/data/mailserver/certs/fullchain.pem
/srv/mail-fetch01/data/mailserver/certs/privkey.pem
Das passt genau zu obiger Compose.
15. Setup nach Clone auf Ziel-VM
Repo klonen
cd /srv/workspace/infra
git clone <dein-repo> mail-fetch01
cd mail-fetch01
Zielstruktur erzeugen
./scripts/init-dirs.sh
Compose und Config deployen
./scripts/deploy.sh
Zertifikate ablegen
sudo cp /etc/letsencrypt/live/mail.theboxhub.ch/fullchain.pem /srv/mail-infetch01t01/data/mailserver/certs/fullchain.pem
sudo cp /etc/letsencrypt/live/mail.theboxhub.ch/privkey.pem /srv/mail-fetch01/data/mailserver/certs/privkey.pem
sudo chmod 600 /srv/mail-fetch01/data/mailserver/certs/privkey.pem
16. Erster Start
Wenn du bei den 3 Compose-Dateien bleibst:
cd /srv/mail-fetch01/compose/mariadb && docker compose up -d
cd /srv/mail-fetch01/compose/mailserver && docker compose up -d
cd /srv/mail-fetch01/compose/roundcube && docker compose up -d
17. Aber nochmals: meine klare Empfehlung
Fuer diesen Mail-Stack solltest du wirklich lieber eine gemeinsame Compose-Datei verwenden.
Sonst bekommst du unnoetig Aufwand mit Netzwerken, DNS innerhalb von Docker und Service-Namen.
Wenn du magst
schreibe ich dir jetzt direkt als naechsten Schritt:
- die finale empfohlene Gesamtstruktur
- eine einzige saubere
compose/mail/compose.yaml - die finalen Repo-Befehle zum Anlegen
Das waere fuer deinen Mailserver die bessere produktive Variante.