A small Docker image for running mbsync/isync and syncing a Gmail account into a local Maildir directory.
This project is intended for email backups or scheduled mailbox syncs without installing isync directly on the host.
This repository is based on the article Backup de Gmail pra Maildir em Linux by AkitaOnRails.
- Installs
isyncon top ofdebian:bookworm-slim. - Runs
mbsyncwith a config file mounted at/config/isyncrc. - Uses
flockto prevent concurrent sync runs. - Writes logs to
/logs/mbsync.log. - Runs as a non-root user with UID/GID
568:568, which matches the commonappsuser/group used by TrueNAS SCALE.
docker pull luizfilipemoresco/mbsync:latestExample:
mbsync/
├── config/
│ └── isyncrc
├── mail/
├── logs/
└── state/
Create the directories:
mkdir -p config mail logs stateThe container runs as UID/GID 568:568. This is intentional for TrueNAS SCALE users, where 568:568 commonly maps to the apps user/group used by containerized apps. Make sure the mounted directories are writable by that user/group.
sudo chown -R 568:568 mail logs state
chmod 600 config/isyncrcCreate config/isyncrc:
IMAPAccount gmail
Host imap.gmail.com
User your-email@gmail.com
PassCmd "cat /config/gmail-app-password"
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore gmail-remote
Account gmail
MaildirStore gmail-local
Path /mail/
Inbox /mail/INBOX
SubFolders Verbatim
Channel gmail-backup
Far :gmail-remote:
Near :gmail-local:
Patterns *
Create Near
SyncState *
Sync PullFor Gmail, use an app password instead of your main account password. Mount it as a file or adapt PassCmd to your preferred secret management method.
Example using a local file:
printf '%s\n' 'your-app-password' > config/gmail-app-password
chmod 600 config/gmail-app-passworddocker run --rm \
-v "$PWD/config:/config:ro" \
-v "$PWD/mail:/mail" \
-v "$PWD/logs:/logs" \
-v "$PWD/state:/state" \
luizfilipemoresco/mbsync:latestBy default, the container uses:
- Config file:
/config/isyncrc - Channel:
gmail-backup - Lock file:
/state/mbsync.lock - Log file:
/logs/mbsync.log
| Variable | Default | Description |
|---|---|---|
MBSYNC_CONFIG |
/config/isyncrc |
Path to the mbsync configuration file. |
MBSYNC_CHANNEL |
gmail-backup |
Channel passed to mbsync. |
MBSYNC_LOCK_FILE |
/state/mbsync.lock |
File used by flock to prevent concurrent runs. |
MBSYNC_LOG_FILE |
/logs/mbsync.log |
File where logs are written. |
Example using a custom channel:
docker run --rm \
-e MBSYNC_CHANNEL=my-channel \
-v "$PWD/config:/config:ro" \
-v "$PWD/mail:/mail" \
-v "$PWD/logs:/logs" \
-v "$PWD/state:/state" \
luizfilipemoresco/mbsync:latestYou can schedule the container with cron, a systemd timer, a Kubernetes CronJob, or any other scheduler.
Example cron entry to run once per hour:
0 * * * * cd /path/to/mbsync && docker run --rm -v "$PWD/config:/config:ro" -v "$PWD/mail:/mail" -v "$PWD/logs:/logs" -v "$PWD/state:/state" luizfilipemoresco/mbsync:latestdocker build -t mbsync-gmail .docker run --rm \
-v "$PWD/config:/config:ro" \
-v "$PWD/mail:/mail" \
-v "$PWD/logs:/logs" \
-v "$PWD/state:/state" \
mbsync-gmailThe release.sh script checks Docker Hub for the latest semantic version tag, increments the patch version, builds the image, pushes the Docker tags, creates the matching git tag, and publishes a GitHub Release.
luizfilipemoresco/mbsync:vX.Y.Zluizfilipemoresco/mbsync:latestvX.Y.Zgit tagvX.Y.ZGitHub Release
Run:
./release.shRequirements:
- Docker installed and authenticated with Docker Hub.
- Permission to push to
luizfilipemoresco/mbsync. - A clean git working tree.
curl,grep,sed, andsortavailable on the host.- GitHub CLI installed and authenticated with permission to create releases.
By default, the git tag is pushed to origin. Use GIT_REMOTE to override that remote:
GIT_REMOTE=upstream ./release.shTo skip GitHub Release creation:
CREATE_GITHUB_RELEASE=false ./release.sh- Do not commit passwords, tokens, or credential files.
- Prefer Gmail app passwords.
- Keep
config/isyncrcand secret files restricted. - Validate your configuration carefully before automating recurring syncs.