Install it · 7 of 7
Moving accounts with inbuxa-migrate
inbuxa-migrate moves an account into inbuxa from IMAP, JMAP, DAV, Maildir, Google Takeout or Exchange: mail, calendars, contacts, identities, Sieve scripts and files, through an archive file that is also a backup.
On this page
inbuxa-migrate moves one account at a time into inbuxa: its mail,
calendars, contacts, identities, Sieve scripts and files. It is a program of
its own, and runs on any Linux machine that can reach both servers. Nothing
is installed on either of them.
Where it fits:
- Coming from another server: it does the work of parts 2 and 3, the mail and everything else, in place of imapsync and exported files. Deciding who people are (part 1) and the cutover (part 4) are the same either way.
- Coming from Stalwart: copying the store moves the
whole server at once, and stays the way to do that. Use
inbuxa-migrateinstead to move only some accounts, or into an inbuxa server that is already running. - As a backup: an account's archive can be filled on a schedule and written back later.
Install it
Linux, on amd64 or arm64. Each release carries one archive per architecture
and a SHA256SUMS file:
base=https://git.coffeylabs.org/inbuxa/inbuxa-migrate/releases/latest/download
curl -fLO "$base/inbuxa-migrate-linux-amd64.tar.gz"
curl -fLO "$base/SHA256SUMS"
sha256sum --check --ignore-missing SHA256SUMS
tar -xzf inbuxa-migrate-linux-amd64.tar.gz
./inbuxa-migrate --version
On arm64, fetch inbuxa-migrate-linux-arm64.tar.gz instead. The binary is
the whole program.
How it works
Three commands, and a file between them:
inbuxa-migrate import imap … alice.sqlite # the old account into an archive
inbuxa-migrate inspect alice.sqlite # what landed
inbuxa-migrate export … alice.sqlite # the archive into inbuxa
The archive is one SQLite file holding one account. import fills it from
the old server and export writes it into inbuxa. The two never talk to
each other, only to the archive, so the old server can be gone before the
new one exists.
Both commands pick up where they stopped. Run import again and it adds
what arrived since; run export again and it brings inbuxa up to date,
read and flagged state included. Every command takes --dry-run, which
reports the plan and writes nothing.
Sources
| Source | What comes across |
|---|---|
| JMAP: inbuxa, Stalwart, or any JMAP server | Everything the server offers: mail, calendars, contacts, identities, Sieve scripts and files |
| IMAP | Mail, chosen by folder name or pattern |
| CalDAV, CardDAV | Calendars and events, address books and contacts |
| WebDAV | A plain file collection, as a file tree |
| ManageSieve | Sieve scripts, with the active one marked |
| Maildir | Mail, read from a local Maildir++ tree |
| Google Takeout | The .mbox, .ics and .vcf files in an export |
| Exchange Server | Mail, calendars and contacts, through EWS |
| Exchange Online | Mail, calendars and contacts, through Microsoft Graph |
For one account on a server with several of these, run one import per
source into the same archive: IMAP for the mail, CalDAV for the calendars,
and so on.
Scripts that came from Stalwart keep working: their vnd.stalwart.*
extensions are renamed to inbuxa's on the way in.
One account, end to end
Passwords are asked for at a prompt. For a script, put them in
INBUXA_MIGRATE_PASSWORD instead, never on the command line.
inbuxa-migrate import imap \
--url imaps://old.example.com \
--auth-basic alice@example.com \
alice.sqlite
inbuxa-migrate inspect alice.sqlite
Then write it into inbuxa. The account has to exist there first, either made in the console or created by a directory on first use. A dry run first shows what would happen, and names anything the server would refuse, such as a message over its size limit:
inbuxa-migrate export \
--url https://mail.example.net \
--auth-basic 'alice@example.com%migrator@example.net' \
--account-name alice@example.com \
--dry-run \
alice.sqlite
Run it again without --dry-run to write. The sign-in there is
on Alice's behalf: the migrator account's role lets it
act for anyone, so nobody hands over a password.
Signing in to inbuxa
inbuxa's JMAP takes a token, not a password, so the sign-in above is
refused on a server as it ships. There are two ways to give export what it
needs:
- For the migration, let JMAP take passwords. Start the server with
INBUXA_HTTP_BASIC_AUTH=allin its environment, as described for the server's environment, run the exports, then take the variable out and restart. This is the only way to sign in on someone else's behalf, and it is what the loop below assumes. - Or use the account's own API key, made in the console under the
account's API keys, with
--auth-bearerin place of--auth-basic.INBUXA_MIGRATE_TOKENholds it for a script. The key only reaches its own account, so this suits a handful of people more than a whole server.
At cutover
Run import and then export again for each account after MX has moved.
Only what changed comes across: new mail, changed flags, edited contacts and
events. A day later, once more for stragglers.
Many accounts
The archive holds one account, so many accounts are a loop. With administrator sign-ins on both sides, no one's password is needed. On the inbuxa side that needs JMAP to take passwords while it runs:
read -rs -p 'Source admin password: ' SRC; echo
read -rs -p 'Migrator password: ' DST; echo
while read -r addr; do
INBUXA_MIGRATE_PASSWORD="$SRC" inbuxa-migrate import imap \
--url imaps://old.example.com --auth-basic "$addr*admin" "$addr.sqlite"
INBUXA_MIGRATE_PASSWORD="$DST" inbuxa-migrate export \
--url https://mail.example.net --auth-basic "$addr%migrator@example.net" \
--account-name "$addr" "$addr.sqlite"
done < accounts.txt
$addr*admin is Dovecot's master-user form.
A server that signs in for someone else only through a separate
authorization name, as imapsync's --authuser1 does, needs each person's
own password here, or imapsync as its page describes.
What it doesn't move
- Accounts themselves. It writes into accounts that exist. Make them first, or let a directory create them.
- Passwords. Those come with a directory, or are handed out new.
- Server settings, spam training and sessions, as on Coming from another server.
Keep the archives safe
An archive holds a whole mailbox in the clear. It is created readable by
its owner only, and inbuxa-migrate warns if an existing one isn't. Delete
the archives once the move is done, unless you keep them as backups.
The full reference for every source and flag is in the usage guide.