Skip to main content

Quick Start Guide

From zero to sending and receiving email on your own hardware.

30-60 minutes setup 8 steps 4-6 weeks warmup

Prerequisites

  • A domain name you control (DNS API or manual access)
  • A VPS with port 25 ($3-6/month — Hetzner, Vultr, OVH)
  • A home device running Docker or Podman (RPi 4+, NAS, Linux PC)
  • 30-60 minutes for initial setup + patience for IP warmup
  1. Step 1: Provision Your Cloud Relay

    You need a VPS with port 25 open for SMTP. Most cloud providers block it — choose one that doesn't.

    Recommended

    Hetzner — No restrictions, great price/performance, EU-based

    Vultr — Port 25 after account verification

    Avoid

    DigitalOcean, Google Cloud, AWS EC2 (port 25 blocked)

    Minimum specs: 1 vCPU, 1GB RAM, 20GB SSD ($3-6/month). Set hostname to relay.yourdomain.com, configure reverse DNS (PTR record), and install Docker.

    # Set hostname
    hostnamectl set-hostname relay.yourdomain.com
    
    # Update system
    apt update && apt upgrade -y
    
    # Install Docker
    curl -fsSL https://get.docker.com | sh
    
    # Verify port 25 is open
    telnet gmail-smtp-in.l.google.com 25

    Podman users: Install Podman 5.3+ and podman-compose instead of Docker. See the Podman platform guide.

  2. Step 2: Set Up Transport Layer

    Choose an encrypted transport between your cloud relay and home device:

    WireGuard (Recommended)

    Full encrypted tunnel. Simpler setup, widely supported. Uses UDP port 51820.

    mTLS

    Mutual TLS authentication. No VPN needed, minimal footprint. Uses step-ca for internal PKI.

    WireGuard setup

    # On cloud relay VPS
    apt install -y wireguard
    curl -LO https://raw.githubusercontent.com/trek-e/darkpipe/main/deploy/wireguard/cloud-setup.sh
    chmod +x cloud-setup.sh && ./cloud-setup.sh
    
    # On home device
    sudo apt install -y wireguard
    curl -LO https://raw.githubusercontent.com/trek-e/darkpipe/main/deploy/wireguard/home-setup.sh
    chmod +x home-setup.sh
    ./home-setup.sh --cloud-endpoint YOUR_VPS_IP:51820 --cloud-pubkey CLOUD_PUBLIC_KEY
    sudo wg-quick up wg0 && sudo systemctl enable wg-quick@wg0
    
    # Verify: ping 10.8.0.2 from cloud relay
  3. Step 3: Run the Setup Wizard

    The darkpipe-setup wizard generates configuration for both cloud relay and home device.

    # Download for your platform
    curl -LO https://github.com/trek-e/darkpipe/releases/latest/download/darkpipe-setup-linux-amd64
    chmod +x darkpipe-setup-linux-amd64
    
    # Run the wizard
    ./darkpipe-setup-linux-amd64

    The wizard asks for your domain, relay hostname, mail server choice (Stalwart/Maddy/Postfix+Dovecot), webmail preference, transport type, and admin credentials. It generates .env and docker-compose.yml for both deployments.

    Available for Linux amd64/arm64 and macOS Intel/Apple Silicon. See .env.example files for all configurable variables.

  4. Step 4: Configure DNS

    Email requires SPF, DKIM, and DMARC records. The dns-setup tool automates this.

    # Preview changes (dry-run by default)
    ./dns-setup-linux-amd64 \
      --domain example.com \
      --relay-hostname relay.example.com \
      --relay-ip YOUR_VPS_IP
    
    # Apply with Cloudflare API
    export CLOUDFLARE_API_TOKEN=your_token
    ./dns-setup-linux-amd64 \
      --domain example.com \
      --relay-hostname relay.example.com \
      --relay-ip YOUR_VPS_IP \
      --provider cloudflare --apply
    
    # Validate after DNS propagation (5-60 min)
    ./dns-setup-linux-amd64 --domain example.com --validate-only

    Supports Cloudflare and Route53 API automation, or manual setup via your DNS provider's control panel. Records created: MX, A, SPF, DKIM, DMARC.

  5. Step 5: Deploy Services

    Start the cloud relay on your VPS and the home device stack on your hardware.

    Cloud Relay (VPS)

    cd cloud-relay
    docker compose up -d
    docker compose ps
    docker compose logs -f

    Home Device

    cd home-device
    
    # Stalwart + SnappyMail
    docker compose --profile stalwart \
      --profile snappymail up -d
    
    # Or Postfix+Dovecot + Roundcube + Radicale
    docker compose --profile postfix-dovecot \
      --profile roundcube \
      --profile radicale up -d

    Podman: Add -f docker-compose.podman.yml after the base compose file. Cloud relay requires rootful Podman; home device supports rootless.

  6. Step 6: Test Email Delivery

    Send a test email from an external account (Gmail, Outlook, etc.) to admin@yourdomain.com.

    1. 1. Access webmail at https://mail.yourdomain.com
    2. 2. Log in with your admin credentials
    3. 3. Check inbox for the test message
    4. 4. Send a reply back to test outbound delivery
    5. 5. Forward to check-auth@verifier.port25.com to verify SPF/DKIM/DMARC

    New IPs have no reputation — mail may land in spam initially. This improves over 4-6 weeks of IP warmup.

  7. Step 7: Onboard Devices

    Configure mail on all your devices via the profile server at http://HOME_IP:8090.

    iOS / macOS

    Download .mobileconfig profile — configures IMAP, SMTP, CalDAV, and CardDAV in one tap.

    Android

    Scan QR code with your mail app (K-9 Mail, FairEmail, Gmail app).

    Desktop

    Thunderbird and Outlook use autodiscovery. Manual config: IMAP 993, SMTP 587.

    Generate app-specific passwords for individual devices via the profile server for enhanced security.

  8. Step 8: Monitor & Maintain

    Access the monitoring dashboard at http://HOME_IP:8090/monitoring for queue status, service health, certificate expiry, and delivery logs.

    # Configure alerts in home-device/.env
    MONITOR_ALERT_EMAIL=personal@gmail.com
    MONITOR_WEBHOOK_URL=https://hooks.slack.com/...
    MONITOR_HEALTHCHECK_URL=https://hc-ping.com/...
    
    # IP warmup (4-6 weeks)
    # Week 1: 10-20 emails/day
    # Week 2: 50-100 emails/day
    # Week 3: 200-500 emails/day
    # Week 4-6: Normal volume

    Logs redact email addresses by default. Enable RELAY_DEBUG=true for full PII during troubleshooting (disable after).

Need help?

Check the FAQ or ask in GitHub Discussions.