listmonk update

This commit is contained in:
2026-05-08 13:14:01 +00:00
parent f1161db54d
commit 6c9c6ed9f0
7 changed files with 208 additions and 93 deletions
+112
View File
@@ -0,0 +1,112 @@
# listmonk
## Overview
Self-hosted newsletter and mailing list manager powered by PostgreSQL.
This stack deploys listmonk with persistent storage, automatic database
initialization/upgrades, and support for reverse proxy integration.
## Project Details
- **Project Repository:** https://github.com/knadh/listmonk
- **Container Image:** https://hub.docker.com/r/listmonk/listmonk
- **Compose Example:** https://github.com/knadh/listmonk/blob/master/docker-compose.yml
- **Documentation:** https://listmonk.app/docs/
- **Reverse Proxy Port:** `9000` (configurable with `LISTMONK_PORT`)
## Environment Variable Notes
Most variables are optional because sane defaults are already included
in the compose file.
### Database
POSTGRES_IMAGE PostgreSQL container image
POSTGRES_RESTART Restart policy for PostgreSQL
POSTGRES_USER PostgreSQL username
POSTGRES_PASSWORD PostgreSQL password
POSTGRES_DB PostgreSQL database name
### listmonk
LISTMONK_IMAGE listmonk container image
LISTMONK_RESTART Restart policy for listmonk
LISTMONK_PORT Web UI / proxy port
LISTMONK_HOSTNAME Container hostname
LISTMONK_SSLMODE PostgreSQL SSL mode
LISTMONK_MAX_OPEN Maximum open DB connections
LISTMONK_MAX_IDLE Maximum idle DB connections
LISTMONK_MAX_LIFETIME DB connection lifetime
### Initial Admin User
These are only used during first startup.
LISTMONK_ADMIN_USER Initial admin username
LISTMONK_ADMIN_PASSWORD Initial admin password
### General
VOL_PATH Base path for persistent storage
TZ Container timezone
## Volume Notes
/data/listmonk/db
PostgreSQL database storage
/data/listmonk/uploads
listmonk uploads and media storage
Back up both directories regularly.
## Network Notes
Requires an external Docker network named:
proxy
Create it manually if it does not already exist:
```bash
docker network create proxy
```
Internal application traffic uses the private:
listmonk
bridge network.
## Additional Notes / Gotchas
- The stack automatically runs:
- database installation
- schema upgrades
- application startup
on container launch.
- The install and upgrade commands are idempotent and safe to rerun.
- Change all default passwords before exposing publicly.
- Designed for use behind a reverse proxy such as Traefik, Caddy,
Nginx Proxy Manager, or SWAG.
## Dockhand Stack, Deploy from Git
Cookbooks Repository
stackname: listmonk
Compose file path: listmonk/compose.yaml
Additional env file (optional): listmonk/sample.env
Then load:
listmonk/sample.env
into the Environmental Variables section in Dockhand.
Create the Stack.
+68
View File
@@ -0,0 +1,68 @@
services:
listmonk-db:
image: ${POSTGRES_IMAGE:-postgres:18.3-alpine}
restart: ${POSTGRES_RESTART:-unless-stopped}
volumes:
- ${VOL_PATH:-/data}/listmonk/db:/var/lib/postgresql/data
environment:
- POSTGRES_USER=${POSTGRES_USER:-listmonk}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-securepassword}
- POSTGRES_DB=${POSTGRES_DB:-listmonk}
networks:
- listmonk
listmonk:
image: ${LISTMONK_IMAGE:-listmonk/listmonk:latest}
restart: ${LISTMONK_RESTART:-unless-stopped}
volumes:
- ${VOL_PATH:-/data}/listmonk/uploads:/listmonk/uploads:rw
environment:
- LISTMONK_app__address=0.0.0.0:${LISTMONK_PORT:-9000}
# Database
- LISTMONK_db__user=${POSTGRES_USER:-listmonk}
- LISTMONK_db__password=${POSTGRES_PASSWORD:-securepassword}
- LISTMONK_db__database=${POSTGRES_DB:-listmonk}
- LISTMONK_db__host=listmonk-db
- LISTMONK_db__port=5432
- LISTMONK_db__ssl_mode=${LISTMONK_SSLMODE:-disable}
# DB Pool
- LISTMONK_db__max_open=${LISTMONK_MAX_OPEN:-25}
- LISTMONK_db__max_idle=${LISTMONK_MAX_IDLE:-25}
- LISTMONK_db__max_lifetime=${LISTMONK_MAX_LIFETIME:-300s}
# Timezone
- TZ=${TZ:-America/Vancouver}
# Initial Admin User
- LISTMONK_ADMIN_USER=${LISTMONK_ADMIN_USER:-admin}
- LISTMONK_ADMIN_PASSWORD=${LISTMONK_ADMIN_PASSWORD:-changeme1234}
ports:
- "${LISTMONK_PORT:-9000}:${LISTMONK_PORT:-9000}"
networks:
- listmonk
- proxy
hostname: ${LISTMONK_HOSTNAME:-listmonk.example.com}
depends_on:
- listmonk-db
command:
[
sh,
-c,
"./listmonk --install --idempotent --yes --config '' &&
./listmonk --upgrade --yes --config '' &&
./listmonk --config ''"
]
networks:
listmonk:
driver: bridge
proxy:
external: true
+28
View File
@@ -0,0 +1,28 @@
# PostgreSQL
POSTGRES_IMAGE=postgres:18.3-alpine
POSTGRES_RESTART=unless-stopped
POSTGRES_USER=listmonk
POSTGRES_PASSWORD=securepassword
POSTGRES_DB=listmonk
# Storage
VOL_PATH=/data
# Listmonk
LISTMONK_IMAGE=listmonk/listmonk:latest
LISTMONK_RESTART=unless-stopped
LISTMONK_PORT=9000
LISTMONK_SSLMODE=disable
LISTMONK_MAX_OPEN=25
LISTMONK_MAX_IDLE=25
LISTMONK_MAX_LIFETIME=300s
# Timezone
TZ=America/Vancouver
# Admin user
LISTMONK_ADMIN_USER=admin
LISTMONK_ADMIN_PASSWORD=changeme1234
# Hostname
LISTMONK_HOSTNAME=listmonk.example.com
-5
View File
@@ -1,5 +0,0 @@
# listmonk
* [github](https://github.com/knadh/listmonk/tree/master)
* Proxy port: 9000
-24
View File
@@ -1,24 +0,0 @@
[app]
# Interface and port where the app will run its webserver. The default value
# of localhost will only listen to connections from the current machine. To
# listen on all interfaces use '0.0.0.0'. To listen on the default web address
# port, use port 80 (this will require running with elevated permissions).
address = "0.0.0.0:9000"
# Database.
[db]
host = "listmonk-db"
port = 5432
user = "listmonk"
password = "securepassword"
# Ensure that this database has been created in Postgres.
database = "listmonk"
ssl_mode = "disable"
max_open = 25
max_idle = 25
max_lifetime = "300s"
# Optional space separated Postgres DSN params. eg: "application_name=listmonk gssencmode=disable"
params = ""
-60
View File
@@ -1,60 +0,0 @@
services:
listmonk-db:
image: postgres:13-alpine
restart: unless-stopped
networks:
- listmonk
environment:
- POSTGRES_USER=${POSTGRES_USER:-listmonk}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-securepassword}
- POSTGRES_DB=${POSTGRES_DB:-listmonk}
volumes:
- listmonk-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
interval: 10s
timeout: 5s
retries: 6
listmonk-init:
image: listmonk/listmonk:latest
depends_on:
listmonk-db:
condition: service_healthy
networks:
- listmonk
volumes:
- ./config/config.toml:/listmonk/config.toml
command: [ "sh", "-c", "yes | ./listmonk --install --config /listmonk/config.toml" ]
listmonk:
image: listmonk/listmonk:latest
restart: unless-stopped
depends_on:
listmonk-db:
condition: service_healthy
listmonk-init:
condition: service_completed_successfully
ports:
- "9000:9000"
networks:
- listmonk
volumes:
- ./config/config.toml:/listmonk/config.toml
- ./data/listmonk:/app/data
environment:
- SECRET_KEY=${SECRET_KEY}
- DB_PROVIDER=postgres
- DB_HOST=db
- DB_PORT=5432
- DB_USER=${POSTGRES_USER:-listmonk}
- DB_PASSWORD=${POSTGRES_DB:-listmonk}
- DB_NAME=${POSTGRES_DB}
- WEB_SERVER_HOST=0.0.0.0
- WEB_SERVER_PORT=8000
networks:
listmonk:
volumes:
listmonk-data:
-4
View File
@@ -1,4 +0,0 @@
POSTGRES_USER=listmonk
POSTGRES_PASSWORD=securepassword
POSTGRES_DB=listmonk
SECRET_KEY=your_super_secret_key