Deploying a Listmonk App
Introduction
Listmonk is an open-source self-hosted newsletter and mailing list manager written in Go. Deploying Listmonk with a Dockerfile on Klutch.sh gives you reproducible builds, managed secrets, and persistent storage for subscribers and campaign data—all managed from klutch.sh/app. This guide covers installation, repository prep, a production-ready Dockerfile, deployment steps, Nixpacks overrides, sample API usage, and production tips.
Prerequisites
- A Klutch.sh account (create one)
- A GitHub repository containing your Listmonk config (GitHub is the only supported git source)
- Docker familiarity and basic Go knowledge
- PostgreSQL credentials (Listmonk requires Postgres)
- Storage for data and logs
For platform onboarding, see the Quick Start.
Architecture and ports
- Listmonk serves HTTP on port
9000; set the internal container port to9000. - PostgreSQL should run as a separate Klutch.sh TCP app, exposed on port
8000, connected internally on5432. - Persistent storage is recommended for
/datato store uploads, logs, and config.
Repository layout
listmonk/├── config.toml # Listmonk configuration├── Dockerfile # Must be at repo root for auto-detection├── data/ # Optional data/logs (mount as volume)└── README.mdKeep secrets out of Git; store them in Klutch.sh environment variables.
Installation (local) and starter commands
Test Listmonk locally before pushing to GitHub:
docker run --rm -p 9000:9000 \ -e LISTMONK_DB_HOST=localhost \ -e LISTMONK_DB_USER=listmonk \ -e LISTMONK_DB_PASSWORD=secret \ -e LISTMONK_DB_NAME=listmonk \ listmonk/listmonk:latestOptional helper start.sh for portability and Nixpacks fallback:
#!/usr/bin/env bashset -euo pipefail./listmonk --config config.toml --static-dir ./static --templates-dir ./templatesMake it executable with chmod +x start.sh.
Dockerfile for Listmonk (production-ready)
Place this Dockerfile at the repo root; Klutch.sh auto-detects it (no Docker selection in the UI):
FROM listmonk/listmonk:latest
WORKDIR /app
# Copy custom config if providedCOPY config.toml /app/config.toml
EXPOSE 9000CMD ["./listmonk", "--config", "/app/config.toml", "--static-dir", "./static", "--templates-dir", "./templates"]Notes:
- Pin the image tag (e.g.,
listmonk/listmonk:v4.0.0) for reproducible builds. - If building from source, use the official build instructions and copy the binary into a minimal runtime image.
Environment variables (Klutch.sh)
Set these in the Klutch.sh app settings (Secrets tab) before deploying:
PORT=9000LISTMONK_DB_HOST=<db-host>LISTMONK_DB_PORT=5432LISTMONK_DB_USER=<db-user>LISTMONK_DB_PASSWORD=<db-password>LISTMONK_DB_NAME=<db-name>LISTMONK_APP_URL=https://example-app.klutch.shLISTMONK_ADMIN_USER=<admin-user>LISTMONK_ADMIN_PASSWORD=<admin-password>
If you deploy without the Dockerfile and need Nixpacks overrides:
NIXPACKS_BUILD_CMD="echo Listmonk uses prebuilt image"NIXPACKS_START_CMD=./listmonk --config config.toml --static-dir ./static --templates-dir ./templatesNIXPACKS_GO_VERSION=1.21
These keep Listmonk compatible with Nixpacks defaults when a Dockerfile is absent.
Attach persistent volumes
In Klutch.sh storage settings, add mount paths and sizes (no names required):
/data— optional for logs, backups, or custom assets.
Ensure this path is writable inside the container.
Deploy Listmonk on Klutch.sh (Dockerfile workflow)
- Push your repository (with the Dockerfile at the root) to GitHub.
- Open klutch.sh/app, create a project, and add an app.
- Connect the GitHub repository; Klutch.sh automatically detects the Dockerfile.
- Choose HTTP traffic for Listmonk.
- Set the internal port to
9000. - Add the environment variables above (database credentials, admin user/password, app URL, and any
NIXPACKS_*overrides if you temporarily deploy without the Dockerfile). - Attach a persistent volume for
/dataif you store logs or custom assets, selecting a size that fits your retention needs. - Deploy. Your Listmonk instance will be reachable at
https://example-app.klutch.sh; attach a custom domain if desired.
Sample API usage
Create a list via API (replace placeholders):
curl -X POST "https://example-app.klutch.sh/api/lists" \ -H "Content-Type: application/json" \ -H "Authorization: Basic <base64-encoded admin:password>" \ -d '{"name":"News","type":"public","optin":"single"}'Health checks and production tips
- Add a reverse proxy probe on
/or/api/healthto verify availability. - Enforce HTTPS at the edge; forward HTTP to port 9000 internally.
- Keep image tags pinned; upgrade intentionally.
- Monitor disk usage on
/dataand resize volumes before they fill. - Back up PostgreSQL regularly; do not rely on container filesystems for durability.
- Rotate admin credentials and store secrets only in Klutch.sh variables.
Listmonk on Klutch.sh combines reproducible Docker builds with managed secrets, optional persistent storage, and flexible HTTP/TCP routing. With the Dockerfile at the repo root and port 9000 configured, you can run a reliable newsletter platform without extra YAML or workflow overhead.