listmonk logo

listmonk

High performance, self-hosted newsletter and mailing list manager

Alternative to: mailchimp


listmonk is a standalone, self-hosted newsletter and mailing list manager packed into a single fast Go binary with a modern Vue dashboard. It handles subscriber management, SQL-based segmentation, double opt-in lists, campaign analytics, and both bulk and transactional email sending via your own SMTP relay.

listmonk Docker Compose example

Self-host listmonk on your own server, homelab, or VPS starting from this Docker Compose example. It runs listmonk in Docker containers using the official listmonk/listmonk:latest, postgres:17-alpine images, with persistent volumes and automatic restarts preconfigured. Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.

services:
  app:
    image: listmonk/listmonk:latest
    restart: unless-stopped
    command: [sh, -c, "./listmonk --install --idempotent --yes --config '' && ./listmonk --upgrade --yes --config '' && ./listmonk --config ''"]
    depends_on:
      db:
        condition: service_healthy
    environment:
      LISTMONK_app__address: "0.0.0.0:9000"
      LISTMONK_db__user: "listmonk"
      LISTMONK_db__password: "listmonk"
      LISTMONK_db__database: "listmonk"
      LISTMONK_db__host: "db"
      LISTMONK_db__port: "5432"
      LISTMONK_db__ssl_mode: "disable"
      LISTMONK_db__max_open: "25"
      LISTMONK_db__max_idle: "25"
      LISTMONK_db__max_lifetime: "300s"
      # Timezone for the container and scheduled campaigns.
      TZ: "Etc/UTC"
      # Optional super admin username, created on first startup. Leave blank to set it up through the web UI on first visit.
      LISTMONK_ADMIN_USER: ""
      # Optional super admin password, created on first startup. Leave blank to set it up through the web UI.
      LISTMONK_ADMIN_PASSWORD: ""
    volumes:
      - uploads:/listmonk/uploads

  db:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: "listmonk"
      POSTGRES_PASSWORD: "listmonk"
      POSTGRES_DB: "listmonk"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U listmonk"]
      interval: 10s
      timeout: 5s
      retries: 6
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  uploads:
  data:

Prefer a managed setup? WinterFlow installs, configures, and updates listmonk for you using this same Docker Compose configuration.