Pierre Palatin's corner

Random posts about some stuff I’ve been doing.

Migrating from an IMAP server to Gmail

Posted at — Jun 25, 2010

I started to configure a Google Apps for domains and I want to cleanly migrate existing mails from my server. The wonderful imapsync does all the hard work. However, to have a clean migration to GMail, you need to have the right flags.

Here is what I’m using:

imapsync \
   --host1 imap.example.com \
   --user1 myuser \
   --passfile1 passwd1 \
   --port1 993 \
   --ssl1 \
   --authmech1 LOGIN \
   --prefix1 INBOX. \
   --host2 imap.gmail.com \
   --port2 993 \
   --ssl2 \
   --user2 myuser@mygoogleappsdomain \
   --passfile2 passwd-gmail \
   --prefix2 '' \
   --regextrans2 's/Drafts/[Gmail]\/Brouillons/' \
   --regextrans2 's/Sent/[Gmail]\/Messages envoy&AOk-s/' \
   --regextrans2 's/Spam/[Gmail]\/Spam/' \
   --regextrans2 's/Trash/[Gmail]\/Corbeille/' \
   --authmech2 LOGIN \
   --syncinternaldates \
   --skipsize \
   --useheader 'Message-Id' \
   --useheader 'Date' \
   --exclude 'INBOX.Trash' \
   --exclude 'INBOX.Spam' \
   --expunge \
   --delete2

Those parameters work perfectly for migrating from a Courier-IMAP server to a GMail configured in french. It would work with GMail in other languages, you just have to change the regextrans2 options to match your locale.

A few details about the flags I’m using:

 --regextrans2 's/Drafts/[Gmail]\/Brouillons/' \
 --regextrans2 's/Sent/[Gmail]\/Messages envoy&AOk-s/' \
 --regextrans2 's/Spam/[Gmail]\/Spam/' \
 --regextrans2 's/Trash/[Gmail]\/Corbeille/' \

Those regexps will make sure that your “special” folders (sent mail, spam, trash, drafts) are correctly mapped in GMail. Be careful, the target name depends on your locale in GMail.

 --exclude 'INBOX.Trash' \
 --exclude 'INBOX.Spam' \

There’s probably no need to sync up your trash and even less your spam box.

 --skipsize \
 --useheader 'Message-Id' \
 --useheader 'Date' \

imapsync is a synchronization tool, you can re-run it several time to keep the copy up to date. However, it needs for that to be able to identify what is a duplicated message. That’s an harder job than what one can think of as the semantic of each imap server can differ quite a lot. The best combination I’ve found to move to gmail is to ignore the size and rely on Message-Id and Date headers. Message-Id is supposed to be unique, which should be enough. However, it can happens that a message has no Message-Id; in my case, it was a bunch of sent mail from an old outlook express. To avoid having to restransfer those messages at each sync, adding header Date helps a lot.

 --delete2 \

Be careful with this flag. This flag will delete any message on the target mailbox which is not anymore on the source mailbox. It’s really useful when you do a several step synchronization for a migration, as it will take into account messages removed between each sync.

 --expunge \

This flag will expunge messages on the source server. It will avoid having to (slowly) copy messages already marked as \Deleted on the source. It should be safe, but still keep an eye on what you’re doing. In practice, IMap deletion works in 2 times: messages is marked as \Deleted and then those deleted messages can be finally deleted, during an expunge. Depending on your server configuration, messages can be automatically expunged or not. In my case, I had a few not expunged messages dating from when my mail server was not doing automatic expunge.