Add migration scripts and other fixes
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# 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
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user