From 3ed2186dcf8888774f13fb6bd65da5df68366ccf Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 4 Apr 2024 20:20:16 +0530 Subject: [PATCH 1/2] Initial cut of listmonk setup --- infra/services/listmonk/README.md | 54 ++++++++++++++++++++ infra/services/listmonk/initialize-db.sh | 15 ++++++ infra/services/listmonk/listmonk.nginx.conf | 24 +++++++++ infra/services/listmonk/listmonk.service | 16 ++++++ infra/services/status/uptime-kuma.nginx.conf | 5 +- 5 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 infra/services/listmonk/README.md create mode 100644 infra/services/listmonk/initialize-db.sh create mode 100644 infra/services/listmonk/listmonk.nginx.conf create mode 100644 infra/services/listmonk/listmonk.service diff --git a/infra/services/listmonk/README.md b/infra/services/listmonk/README.md new file mode 100644 index 000000000..d357cc672 --- /dev/null +++ b/infra/services/listmonk/README.md @@ -0,0 +1,54 @@ +# Listmonk + +We use [Listmonk](https://listmonk.app/) to manage our mailing lists. + +- Museum lets Listmonk know about new users and account deletion (this allows + Listmonk to create corresponding accounts). + +- Subsequently, Listmonk handles user subscription / unsubscription etc + (Listmonk stores its data in an external Postgres). + +## Installing + +Install [nginx](../nginx/README.md). + +Add Listmonk's configuration. + +```sh +sudo mkdir -p /root/listmonk +sudo tee /root/listmonk/config.toml +``` + +Add the service definition and nginx configuration. + +```sh +scp services/listmonk/listmonk.* : + +sudo mv listmonk.service /etc/systemd/system/ +sudo mv listmonk.nginx.conf /root/nginx/conf.d +``` + +> The very first time we ran Listmonk, at this point we also needed to get it to +> install the tables it needs in the Postgres DB. For this, we used the +> `initialize-db.sh` script. +> +> ```sh +> scp services/listmonk/initialize-db.sh : +> +> sudo ./initialize-db.sh +> rm initialize-db.sh +> ``` + +Tell systemd to pick up new service definitions, enable the unit (so that it +automatically starts on boot), and start it this time around. + +```sh +sudo systemctl daemon-reload +sudo systemctl enable --now listmonk +``` + +Tell nginx to pick up the new configuration. + +```sh +sudo systemctl reload nginx +``` diff --git a/infra/services/listmonk/initialize-db.sh b/infra/services/listmonk/initialize-db.sh new file mode 100644 index 000000000..7c94a12cf --- /dev/null +++ b/infra/services/listmonk/initialize-db.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# This script needs to be manually run the once (and only once) before starting +# Listmonk for the first time. It uses the provided credentials to initialize +# its database. + +set -o errexit +set -o xtrace + +docker pull listmonk/listmonk + +docker run --rm --name listmonk \ + -p 9000:9000 \ + -v /root/listmonk/config.toml:/listmonk/config.toml:ro \ + listmonk/listmonk ./listmonk --install diff --git a/infra/services/listmonk/listmonk.nginx.conf b/infra/services/listmonk/listmonk.nginx.conf new file mode 100644 index 000000000..fd59a2980 --- /dev/null +++ b/infra/services/listmonk/listmonk.nginx.conf @@ -0,0 +1,24 @@ +# This file gets loaded in a top level http block by the default nginx.conf +# See infra/services/nginx/README.md for more details. + +server { + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + ssl_certificate /etc/ssl/certs/cert.pem; + ssl_certificate_key /etc/ssl/private/key.pem; + + server_name lists.ente.io; + + location / { + proxy_pass http://host.docker.internal:9000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Use HTTP/1.1 when talking to upstream + proxy_http_version 1.1; + proxy_set_header Connection ""; + } +} diff --git a/infra/services/listmonk/listmonk.service b/infra/services/listmonk/listmonk.service new file mode 100644 index 000000000..95a352bdd --- /dev/null +++ b/infra/services/listmonk/listmonk.service @@ -0,0 +1,16 @@ +[Unit] +Documentation=https://listmonk.app/docs/installation/ +Requires=docker.service +After=docker.service + +[Install] +WantedBy=multi-user.target + +[Service] +ExecStartPre=docker pull listmonk/listmonk +ExecStartPre=-docker stop listmonk +ExecStartPre=-docker rm listmonk +ExecStart=docker run --name listmonk \ + -p 9000:9000 \ + -v /root/listmonk/config.toml:/listmonk/config.toml:ro \ + listmonk/listmonk diff --git a/infra/services/status/uptime-kuma.nginx.conf b/infra/services/status/uptime-kuma.nginx.conf index c45c7b660..a67f5e101 100644 --- a/infra/services/status/uptime-kuma.nginx.conf +++ b/infra/services/status/uptime-kuma.nginx.conf @@ -2,8 +2,9 @@ # See infra/services/nginx/README.md for more details. server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen 443 ssl; + listen [::]:443 ssl; + http2 on; ssl_certificate /etc/ssl/certs/cert.pem; ssl_certificate_key /etc/ssl/private/key.pem; From e170b6811db4b38218ed03aae31c64633eb4d0b9 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 4 Apr 2024 21:04:19 +0530 Subject: [PATCH 2/2] Tweaks Refs: https://github.com/knadh/listmonk/blob/master/listmonk-simple.service#L16 --- infra/services/listmonk/README.md | 2 +- infra/services/listmonk/initialize-db.sh | 3 +-- infra/services/listmonk/listmonk.nginx.conf | 4 +++- infra/services/listmonk/listmonk.service | 3 +++ 4 files changed, 8 insertions(+), 4 deletions(-) mode change 100644 => 100755 infra/services/listmonk/initialize-db.sh diff --git a/infra/services/listmonk/README.md b/infra/services/listmonk/README.md index d357cc672..e94c676cd 100644 --- a/infra/services/listmonk/README.md +++ b/infra/services/listmonk/README.md @@ -35,7 +35,7 @@ sudo mv listmonk.nginx.conf /root/nginx/conf.d > ```sh > scp services/listmonk/initialize-db.sh : > -> sudo ./initialize-db.sh +> sudo sh initialize-db.sh > rm initialize-db.sh > ``` diff --git a/infra/services/listmonk/initialize-db.sh b/infra/services/listmonk/initialize-db.sh old mode 100644 new mode 100755 index 7c94a12cf..576c607a9 --- a/infra/services/listmonk/initialize-db.sh +++ b/infra/services/listmonk/initialize-db.sh @@ -9,7 +9,6 @@ set -o xtrace docker pull listmonk/listmonk -docker run --rm --name listmonk \ - -p 9000:9000 \ +docker run -it --rm --name listmonk \ -v /root/listmonk/config.toml:/listmonk/config.toml:ro \ listmonk/listmonk ./listmonk --install diff --git a/infra/services/listmonk/listmonk.nginx.conf b/infra/services/listmonk/listmonk.nginx.conf index fd59a2980..783c28a8a 100644 --- a/infra/services/listmonk/listmonk.nginx.conf +++ b/infra/services/listmonk/listmonk.nginx.conf @@ -18,7 +18,9 @@ server { proxy_set_header X-Forwarded-Proto $scheme; # Use HTTP/1.1 when talking to upstream + # Also, while not necessary (AFAIK), also allow websockets. proxy_http_version 1.1; - proxy_set_header Connection ""; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; } } diff --git a/infra/services/listmonk/listmonk.service b/infra/services/listmonk/listmonk.service index 95a352bdd..46b1a5f41 100644 --- a/infra/services/listmonk/listmonk.service +++ b/infra/services/listmonk/listmonk.service @@ -10,6 +10,9 @@ WantedBy=multi-user.target ExecStartPre=docker pull listmonk/listmonk ExecStartPre=-docker stop listmonk ExecStartPre=-docker rm listmonk +ExecStartPre=-docker run --rm --name listmonk \ + -v /root/listmonk/config.toml:/listmonk/config.toml:ro \ + listmonk/listmonk --upgrade --yes ExecStart=docker run --name listmonk \ -p 9000:9000 \ -v /root/listmonk/config.toml:/listmonk/config.toml:ro \