Listmonk
★ 24.3kA self-hosted alternative to Mailchimp, Substack
About
Community Ratings
No ratings yetNew this week
Read recap →Features
- newsletter management
- mailing list management
- single-binary deployment
- Docker deployment
- database setup and upgrade
- live demo
Details
- Last Updated
- Nov 11, 2026
- Created
- Jun 26, 2019
- Install Methods
- dockerdocker-composebinary
- Requirements
- PostgreSQL database
- Default Port
- 9000web UI
- Backup & Export
- database-dump
- Runtime / Stack
- GoDocker
- Privacy & Independence
- No Cloud RequiredOffline Capable
- User Model
- Multi-User
- Deployment
Deployment: Docker Compose ✓2 Containers — light hosting footprintRuns as 2 containers
Run Listmonk yourself
Pick how much you want to manage.
CoolifyBest match
One click on your server
Coolify template for your own server.
About 10 minutes if you run Coolify
netcup
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
Hetzner
Full control
A small server, then Docker Compose.
About 20 minutes with Docker
5 more ways to host
DigitalOceanA small server, then Docker Compose.(opens in a new tab)
OVHcloudA small server, then Docker Compose.(opens in a new tab)
ElestioHosted for you, nothing to maintain.(opens in a new tab)
PikaPodsHosted for you, nothing to maintain.(opens in a new tab)YunoHostInstall it from YunoHost on your home server.(opens in a new tab)
Some links earn us a commission. netcup pays us one and is our preferred VPS host.
Is this your project? Sponsor a listing
Run Listmonk with Docker Compose
Compose file from the Listmonk project repository.
2 services · database: postgres · infra: postgres
no resource limits declared
needs persistent storage (2 volumes)
docker-compose.yml · @ 03fd8ce · scanned Nov 3, 2026
# All LISTMONK_* env variables also support the LISTMONK_*_FILE pattern for loading secrets from files with Docker secrets and Podman
# eg: LISTMONK_ADMIN_USER -> LISTMONK_ADMIN_USER_FILE=/path/to/file_with_value
x-db-credentials: &db-credentials # Use the default POSTGRES_ credentials if they're available or simply default to "listmonk"
POSTGRES_USER: &db-user listmonk # for database user, password, and database name
POSTGRES_PASSWORD: &db-password listmonk
POSTGRES_DB: &db-name listmonk
services:
# listmonk app
app:
image: listmonk/listmonk:latest
container_name: listmonk_app
restart: unless-stopped
ports:
- "9000:9000" # To change the externally exposed port, change to: $custom_port:9000
networks:
- listmonk
hostname: listmonk.example.com # Recommend using FQDN for hostname
depends_on:
- db
command: [sh, -c, "./listmonk --install --idempotent --yes --config '' && ./listmonk --upgrade --yes --config '' && ./listmonk --config ''"]
# --config (file) param is set to empty so that listmonk only uses the env vars (below) for config.
# --install --idempotent ensures that DB installation happens only once on an empty DB, on the first ever start.
# --upgrade automatically runs any DB migrations when a new image is pulled.
environment: # The same params as in config.toml are passed as env vars here.
LISTMONK_app__address: 0.0.0.0:9000
LISTMONK_db__user: *db-user
LISTMONK_db__password: *db-password
LISTMONK_db__database: *db-name
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
TZ: Etc/UTC
LISTMONK_ADMIN_USER: ${LISTMONK_ADMIN_USER:-} # If these (optional) are set during the first `docker compose up`, then the Super Admin user is automatically created.
LISTMONK_ADMIN_PASSWORD: ${LISTMONK_ADMIN_PASSWORD:-} # Otherwise, the user can be setup on the web app after the first visit to http://localhost:9000
volumes:
- ./uploads:/listmonk/uploads:rw # Mount an uploads directory on the host to /listmonk/uploads inside the container.
# To use this, change directory path in Admin -> Settings -> Media to /listmonk/uploads
# Postgres database
db:
image: postgres:17-alpine
container_name: listmonk_db
restart: unless-stopped
ports:
- "127.0.0.1:5432:5432" # Only bind on the local interface. To connect to Postgres externally, change this to 0.0.0.0
networks:
- listmonk
environment:
<<: *db-credentials
healthcheck:
test: ["CMD-SHELL", "pg_isready -U listmonk"]
interval: 10s
timeout: 5s
retries: 6
volumes:
- type: volume
source: listmonk-data
target: /var/lib/postgresql/data
networks:
listmonk:
volumes:
listmonk-data:
This file may be out of date. Check the Listmonk documentation for current setup steps.
Tags
Track your self-hosted stack
Bookmark software to try, rate tools you've used, and keep your collection in one place.