A Docker container running Email OAuth 2.0 Proxy in headless (--no-gui) mode on a Debian-based environment, with the configuration file exposed via a Docker volume.
The image ships with a default emailproxy.config template. On the first start the container automatically copies this template to your mounted /config directory if no config file is found there yet. Edit the created file to add your email server and account details. See the upstream sample config for full documentation and provider-specific examples.
Important: Always mount a volume at
/config. Without a mount the config file is stored only inside the ephemeral container layer and all changes — including OAuth tokens written by the proxy — will be lost when the container is removed or recreated.
The config file must be named emailproxy.config and lives inside the directory mounted at /config.
How the proxy handles its config file (by design) The
emailproxydaemon loads the entireemailproxy.configinto memory at startup. On every clean shutdown it writes the in-memory state back to the file. This means:
- ✅ OAuth tokens acquired during runtime are written back and persist across restarts.
- ✅ All settings present at startup are preserved across restarts.
⚠️ Manual edits made toemailproxy.configwhile the container is running will be overwritten when the container stops, because the daemon saves its in-memory state (= the config as it was at startup) back to disk.Conclusion: Always stop the container before editing
emailproxy.config. Changes made while the container is stopped will be picked up correctly on the next start and will persist.
docker build -t email-oauth2-proxy-docker .docker compose up -dThe default Compose file uses a named volume (emailproxy-config). Docker initialises a named volume only on first creation — it never overwrites existing data on subsequent docker compose down / up or docker compose up --build cycles. If you prefer to store the config in a specific host directory, switch to the bind-mount option in docker-compose.yml.
docker run -d \
--name emailproxy \
--restart unless-stopped \
-e DEBUG=false \
-e LOGFILE=true \
-e CACHE_STORE=/config/credstore.config \
-e LOCAL_SERVER_AUTH=false \
-v emailproxy-config:/config \
-p 1993:1993 \
-p 1587:1587 \
email-oauth2-proxy-dockerMount a volume at /config inside the container. This is required to persist your configuration (including OAuth tokens) across container restarts and upgrades.
| Mount | Container path | Description |
|---|---|---|
| named volume or bind-mount | /config |
Directory where emailproxy.config and optional credential/log files are stored |
On the first start the container seeds /config/emailproxy.config from the built-in default template if the file does not already exist. On every subsequent start the existing file is loaded as-is.
Edit the config only while the container is stopped. The proxy rewrites the config file on shutdown (see note in step 1). Any changes made while the container is running will be lost when it stops.
To reload the configuration file without restarting the container, send a SIGHUP signal:
docker kill --signal=SIGHUP emailproxyNote that a SIGHUP reload only applies to settings the proxy supports reloading at runtime. Structural changes (servers, accounts) require a full restart.
| Variable | Default | Description |
|---|---|---|
DEBUG |
false |
Enable debug logging (--debug) |
LOGFILE |
false |
Write logs to /config/emailproxy.log (--log-file) |
CACHE_STORE |
(unset) | Path or AWS ARN for token cache storage (--cache-store). If set to a file path, use a path inside /config so it persists. |
LOCAL_SERVER_AUTH |
false |
Start a local web server to handle OAuth redirects (--local-server-auth) |
EXTERNAL_AUTH |
false |
Use external browser + copy/paste for OAuth (--external-auth). Ignored when LOCAL_SERVER_AUTH=true. |
| Port | Protocol | Provider example |
|---|---|---|
1993 |
IMAP | Office 365 / Outlook |
1995 |
POP | Office 365 / Outlook |
1587 |
SMTP | Office 365 / Outlook (STARTTLS) |
2993 |
IMAP | Gmail |
2995 |
POP | Gmail |
2465 |
SMTP | Gmail |
8080 |
HTTP | OAuth redirect for LOCAL_SERVER_AUTH |
Only expose the ports you actually need; remove unused entries from docker-compose.yml or the docker run command.
When running in --no-gui mode, accounts must be authorised before the proxy can function. Use one of the following approaches:
LOCAL_SERVER_AUTH=true— The proxy starts a temporary web server to receive the OAuth redirect. Visit the authorisation URL printed in the logs, authenticate, and the proxy captures the token automatically. Map port8080:8080and ensureredirect_uri = http://localhost:8080is set in your config (this is the default in the sampleemailproxy.config).EXTERNAL_AUTH=true— The proxy prints an authorisation URL to the logs. Open it in a browser, authenticate, then copy the final redirect URL from the browser address bar and paste it back into the container standard input viadocker attach emailproxy.- Pre-authorised config — If the
emailproxy.configfile already contains cached tokens (from a previous GUI-mode authorisation), no interaction is needed.
This container wraps simonrob/email-oauth2-proxy. Refer to the upstream README for full details on OAuth 2.0 client credentials, provider-specific setup and advanced options.
This project is licensed under the Apache License 2.0, matching the upstream email-oauth2-proxy license.
This project is provided "as is", without warranty of any kind. The authors and contributors are not responsible for any damage, data loss, or other issues arising from the use of this software. Use at your own risk. See the LICENSE for full terms.