Install on xcloud.host

Deploy Maillayer to xcloud.host as a Docker Compose site. Roughly five minutes end-to-end.

xcloud.host runs Docker workloads on managed VPS infrastructure. Maillayer ships as a single image, so the flow is: spin up a server, drop in a Compose file, set two env vars, and deploy.

Deploy

  1. Sign in to xcloud.host and create a new server (or pick an existing one). The free plan is enough to evaluate Maillayer; resize later when you outgrow it.

    xcloud.host All Servers view with a + New Server button
    Step 1 — Create or pick a server.
  2. Open the server, go to SitesAdd Site, then choose Custom DockerDocker Compose.

    Custom Docker tab with the Docker Compose card selected
    Step 2 — Pick Docker Compose under Custom Docker.
  3. Fill in Site Title (e.g. Maillayer App) and pick a domain. You can use the free *.xc1.app demo domain to start — you can move to a custom domain later — then click Next.

    Site Details and Domain Setup form
    Step 3 — Site title and domain.
  4. Under Docker Compose Source, choose Paste docker-compose.yml content and paste:

    services:
      maillayer:
        image: ghcr.io/mddanishyusuf/maillayer-pro:1
        restart: unless-stopped
        ports:
          - "3000:3000"
        volumes:
          - maillayer-data:/app/data
        environment:
          AUTH_SECRET: ${AUTH_SECRET}
          APP_URL: ${APP_URL}
    
    volumes:
      maillayer-data:
    docker-compose.yml pasted into the editor
    Step 4 — Paste the Compose file.
  5. In Port & Domain Configuration, set the primary port to 3000 (the domain auto-fills from step 3).

    Toggle Provide Environment File (.env) on and paste:

    # Required: public URL where this install is reachable.
    # Used for tracking-link generation, unsubscribe URLs, and the
    # domain reported to the license server during activation.
    APP_URL=https://maillayer.example.com
    
    # Required (or generated on first boot — see callout below).
    # Decrypts every stored provider credential — back this up.
    AUTH_SECRET=$(openssl rand -base64 48)

    Replace https://maillayer.example.com with the actual primary URL xcloud shows you (the https://<your-subdomain>.xc1.app value, or your custom domain). For AUTH_SECRET, run openssl rand -base64 48 locally and paste the output — the $(...) form in the snippet doesn't expand inside an .env file.

    Port 3000 selected and Environment File toggled on
    Step 5 — Port 3000 and the .env file.
  6. Click Deploy. Once the container is healthy, open the URL and sign up — the first account becomes the owner.

Why AUTH_SECRET matters
AUTH_SECRET decrypts every stored provider credential (SES keys, SendGrid tokens, Stripe webhooks, Firebase service-account JSON…). If you lose it, those credentials become unreadable and you'll need to re-enter them. Keep a copy in a password manager.

Custom domain

In xcloud, open the site → Domains and add your domain. Point a CNAME at the target xcloud provides; HTTPS is provisioned automatically via Let's Encrypt.

Once the domain resolves, update APP_URL=https://your-domain.com in the env file and redeploy so tracking links and unsubscribe URLs use the right host.

Replicas

Stay at 1 replica
SQLite is single-writer and the queue/cron run in-process. Multiple replicas will corrupt the database and run every job N times. Keep Replicas = 1.

Volume management

  • Resize: grow the server's disk from xcloud's settings. The maillayer-data named volume rides along with the host filesystem.
  • Inspect: the in-container mount path is /app/data. Use xcloud's shell or SSH and docker exec into the container to peek.
  • Backup: Maillayer takes nightly VACUUM backups in /app/data/backups. See Backups.