Guides and tutorials

Install Mailwake Core

Copy the configuration, start Core and open the console.

Run Core on your server or NAS to receive notifications from selected email folders. You need Docker, plus Docker Compose v2 for the recommended Compose installation.

1. Choose an installation method

Docker Compose is recommended: installation, updates and backups use the same configuration. The image is ghcr.io/mingzaily/mailwake:latest, for Linux amd64 / arm64. latest follows stable releases; use an existing release tag to pin a version.

In your server terminal:

mkdir -p ~/mailwake
cd ~/mailwake

Create compose.yaml in that directory with this complete configuration:

services:
  core:
    image: ghcr.io/mingzaily/mailwake:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      MAILWAKE_LISTEN: "0.0.0.0:8080"
      MAILWAKE_DATA_DIR: "/data"
      MAILWAKE_RELAY_URL: "${MAILWAKE_RELAY_URL:-}"
    volumes:
      - core-data:/data
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    stop_grace_period: 30s
volumes:
  core-data:

Pull the image and start Core:

docker compose pull core
docker compose up -d
docker compose ps
docker compose logs --tail=50 core

Check the result: core shows Up / running, and the logs contain the initial setup code. Keep the terminal available for the next step. Run future Compose commands from ~/mailwake.

The core-data Docker volume stores /data. With this directory name, its default Docker name is mailwake_core-data. Recreating the container preserves it; docker compose down -v deletes the volume and its contents.

Docker Run

Choose this equivalent installation if you prefer a single command. Use one installation method for your instance.

docker volume create mailwake-data
docker run -d \
  --name mailwake \
  --restart unless-stopped \
  --stop-timeout 30 \
  --read-only \
  --security-opt no-new-privileges:true \
  --cap-drop ALL \
  -p 127.0.0.1:8080:8080 \
  -v mailwake-data:/data \
  ghcr.io/mingzaily/mailwake:latest
docker logs --tail=50 mailwake

This installation uses the mailwake-data volume. The following management commands use Compose; see the Docker Run backup instructions for the alternative.

2. Open the console

On the Docker host: open http://127.0.0.1:8080.

On a remote server or NAS: run this command on your own computer, replacing user@server with your server's SSH user and address:

ssh -L 18080:127.0.0.1:8080 user@server

Keep the connection open and visit http://127.0.0.1:18080 on your computer. This is enough to complete initial setup. Configure HTTPS below when you want ongoing access through a domain.

Check the result: the Mailwake setup screen opens. Enter the setup code from the logs and create an administrator password of at least 12 characters. Restarting Core before setup generates a new setup code.

Continue with your first notification to connect a mailbox and a notification channel.

3. Configure HTTPS

Point your domain to the server and configure your reverse proxy to forward to http://127.0.0.1:8080. For Caddy installed on the same host, add your domain to Caddyfile:

mail.example.org {
    reverse_proxy 127.0.0.1:8080
}

Verify DNS and allow inbound ports 80 / 443, then validate and reload:

sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

Open https://mail.example.org, confirm the certificate is valid, and check that you can sign in and open a mailbox. See the official Caddy installation guide to install Caddy. In a proxy panel such as Nginx Proxy Manager, enter the domain and forwarding address and request a certificate in the panel.

For a proxy in another container, join it to Core's Docker network and forward to http://core:8080; its 127.0.0.1 refers to itself. Preserve the original Host and set X-Forwarded-For. Core accepts proxy information from loopback and private networks; expose port 8080 only to the proxy and trusted local clients.

4. Update Core

Complete a backup, then run in the Compose directory:

docker compose pull core
docker compose up -d
docker compose ps
docker compose logs --tail=50 core

For a pinned version, change the image tag in compose.yaml first. Open the console, check mailbox monitoring, and send a new email to verify delivery. Keep the pre-update backup. To roll back, restore both its data and its matching image using the restore tutorial.

5. Troubleshooting

The image cannot be pulled

Check whether GHCR contains the requested version. Images are pending the first release; manifest unknown usually means a missing tag. After publication, check the image address and package visibility for denied errors, or server connectivity to GHCR for timeouts.

The console will not open

127.0.0.1 refers to the computer you are using. Use the SSH tunnel or an HTTPS domain for a remote installation. Check docker compose ps and docker compose logs --tail=50 core first. If 8080 is occupied, change the mapping to 127.0.0.1:18080:8080 and use host port 18080 in the browser and reverse proxy.

Reset an administrator password

Run in the Compose directory and enter the new password at the terminal prompt:

docker compose stop core
docker compose run --rm -it core admin reset-password
docker compose start core

The recovery command acquires the data directory lock, so stop Core first. Resetting the password revokes browser sessions and preserves API tokens, mailboxes and the queue.

Connect the official App and Pro

The Free Web console and Bark / Pushover / Webhook delivery work independently. For the official App, follow App integration for HTTPS, trust files and pairing.

Source builds and local development are covered in the development guide.