131 lines
4.9 KiB
Markdown
131 lines
4.9 KiB
Markdown
# Mailbox migration: docker-mailserver → Stalwart
|
|
|
|
Tools to move accounts, aliases, and mail from a `docker-mailserver` instance into
|
|
this Stalwart deployment.
|
|
|
|
## Overview
|
|
|
|
| Step | Linux (bash) | Windows (PowerShell) | Purpose |
|
|
|---|---|---|---|
|
|
| 1 | `export-docker-mailserver.sh` | *(run on the Linux docker-mailserver host)* | Dumps accounts + aliases from docker-mailserver's config files into `accounts.csv` |
|
|
| 2 | *(manual)* | *(manual)* | Fill in `new_password` (and `old_password` if not already known) in `accounts.csv` |
|
|
| 3 | `generate-account-plan.sh` | `New-AccountPlan.ps1` | Turns `accounts.csv` into a `stalwart-cli apply` NDJSON plan that creates the domain, accounts, and aliases in Stalwart |
|
|
| 4 | `stalwart-cli apply` | `stalwart-cli apply` | Applies the generated plan to Stalwart |
|
|
| 5 | `sync-mailboxes.sh` | `Sync-Mailboxes.ps1` | Runs `imapsync` (via Docker) for every account, copying all folders/messages from docker-mailserver to Stalwart |
|
|
| 6 | *(manual)* | *(manual)* | Verify, then repoint MX/DNS and decommission docker-mailserver |
|
|
|
|
Both old and new mail servers run Linux, so the bash scripts are the primary path;
|
|
the PowerShell scripts are equivalent for driving the migration from a Windows
|
|
workstation. Make the bash scripts executable once: `chmod +x migration/*.sh`.
|
|
`generate-account-plan.sh` requires `jq` (`apt install jq` / `dnf install jq`).
|
|
|
|
docker-mailserver stores passwords as one-way hashes (`config/postfix-accounts.cf`),
|
|
so they cannot be reused directly in Stalwart. Each account gets a **new** password
|
|
during migration; `old_password` is only needed temporarily so `imapsync` can log in
|
|
to the source server to copy mail.
|
|
|
|
## 1. Export accounts and aliases from docker-mailserver
|
|
|
|
Run on the docker-mailserver host (or `docker exec` into its container), pointing at
|
|
its config directory:
|
|
|
|
```bash
|
|
./export-docker-mailserver.sh /path/to/docker-mailserver/config > accounts.csv
|
|
```
|
|
|
|
This produces `accounts.csv` with columns `email,new_password,old_password,aliases,quota_mb`,
|
|
`new_password` and `old_password` left blank for you to fill in.
|
|
|
|
## 2. Fill in passwords
|
|
|
|
Edit `accounts.csv`:
|
|
- `new_password`: the password the account will have on Stalwart. Generate strong
|
|
random values; users can change them later via the WebUI.
|
|
- `old_password`: the account's **current, plaintext** docker-mailserver password,
|
|
needed only so `imapsync` can authenticate to the source during copy. If you don't
|
|
have it, reset it temporarily on docker-mailserver with
|
|
`setup email update <email> <temp-password>` and record that value here.
|
|
- `aliases`: optional, `;`-separated list of extra local-parts on the same domain
|
|
that should deliver to this mailbox (e.g. `info;sales`).
|
|
- `quota_mb`: optional mailbox quota in MB (blank = unlimited).
|
|
|
|
Never commit a filled-in `accounts.csv`; it contains plaintext passwords.
|
|
|
|
## 3. Generate the Stalwart account plan
|
|
|
|
Linux:
|
|
|
|
```bash
|
|
./generate-account-plan.sh -c accounts.csv -d eternityproject.fi -o accounts-plan.ndjson
|
|
```
|
|
|
|
Windows:
|
|
|
|
```powershell
|
|
./New-AccountPlan.ps1 -CsvPath accounts.csv -Domain eternityproject.fi -OutFile accounts-plan.ndjson
|
|
```
|
|
|
|
This upserts the `Domain`, one `Account/User` per row (with a `Password` credential
|
|
set to `new_password` and any `aliases`), so re-running after edits is safe.
|
|
|
|
## 4. Apply the plan to Stalwart
|
|
|
|
Linux:
|
|
|
|
```bash
|
|
export STALWART_URL="https://mail.eternityproject.fi"
|
|
export STALWART_USER="admin"
|
|
export STALWART_PASSWORD="<admin password>"
|
|
|
|
stalwart-cli apply --file accounts-plan.ndjson --dry-run
|
|
stalwart-cli apply --file accounts-plan.ndjson
|
|
```
|
|
|
|
Windows:
|
|
|
|
```powershell
|
|
$env:STALWART_URL = "https://mail.eternityproject.fi"
|
|
$env:STALWART_USER = "admin"
|
|
$env:STALWART_PASSWORD = "<admin password>"
|
|
|
|
stalwart-cli apply --file accounts-plan.ndjson --dry-run
|
|
stalwart-cli apply --file accounts-plan.ndjson
|
|
```
|
|
|
|
## 5. Copy mail with imapsync
|
|
|
|
The sync scripts use the upstream `gilleslamiral/imapsync` Docker image. The first
|
|
run pulls the image automatically, so Docker Hub access is required.
|
|
|
|
Linux:
|
|
|
|
```bash
|
|
./sync-mailboxes.sh -c accounts.csv -s mail.old-domain.example -t mail.eternityproject.fi -n
|
|
```
|
|
|
|
Windows:
|
|
|
|
```powershell
|
|
./Sync-Mailboxes.ps1 `
|
|
-CsvPath accounts.csv `
|
|
-SourceHost mail.old-domain.example `
|
|
-DestHost mail.eternityproject.fi `
|
|
-DryRun
|
|
```
|
|
|
|
(`-n` / `-DryRun` runs imapsync in dry-run mode first; drop it to actually copy messages.)
|
|
|
|
Review the dry-run output, then re-run without `-DryRun` to actually copy messages.
|
|
The script is safe to re-run: `imapsync` skips messages that already exist at the
|
|
destination.
|
|
|
|
## 6. Cut over
|
|
|
|
- Spot-check folder counts/message counts on a few mailboxes in the Stalwart WebUI.
|
|
- Run `Sync-Mailboxes.ps1` once more shortly before cutover to catch mail received
|
|
during the migration window.
|
|
- Update MX records to point at `mail.eternityproject.fi` (see the top-level
|
|
[README.md](../README.md)).
|
|
- Once confirmed, decommission docker-mailserver and rotate the temporary
|
|
`old_password` values you set in step 2.
|