SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-07

Cara Pasang Listmonk di Ubuntu 24.04 dengan PostgreSQL

Ketahui cara memasang Listmonk v6.2.0 pada Ubuntu 24.04 menggunakan PostgreSQL 16. Panduan ini merangkumi konfigurasi fail config.toml, unit systemd, TLS, serta tips SMTP.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Keperluan surat berita layan diri (self-hosted) dengan Listmonk

Listmonk ialah pengurus surat berita dan senarai mel layan diri: satu binari Go, satu pangkalan data PostgreSQL, satu fail konfigurasi, dan satu unit systemd. VPS bersaiz kecil boleh menjalankannya tanpa masalah, kerana Listmonk menyimpan maklumat pelanggan dan baris gilir kempen tetapi tidak menghantar e-mel itu sendiri. Ia menyerahkan setiap mesej kepada pelayan SMTP (simple mail transfer protocol), jadi kadar penghantaran anda ditentukan oleh reputasi pelayan tersebut dan bukannya oleh perisian ini.

Panduan ini memasang Listmonk v6.2.0, iaitu keluaran semasa setakat Julai 2026, pada Ubuntu 24.04. Anda memerlukan VPS dengan alamat IP awam, nama domain yang anda kawal, dan PostgreSQL 12 atau lebih baharu. Pemasangan mengambil masa kira-kira satu jam. Reputasi penghantaran mengambil masa beberapa minggu, dan bahagian tersebut dibincangkan pada penghujung panduan ini.

Memasang PostgreSQL dan mencipta pangkalan data

Ubuntu 24.04 menyertakan PostgreSQL 16 dalam repositori rasminya, versi yang jauh lebih baharu daripada keperluan Listmonk.

sudo apt update
sudo apt install -y postgresql curl
sudo systemctl enable --now postgresql

Cipta peranan (role) dan pangkalan data dalam satu sesi psql. -v ON_ERROR_STOP=1 menyebabkan psql berhenti serta-merta pada pernyataan pertama yang gagal, supaya kesilapan menaip tidak meninggalkan anda dengan persediaan separa yang kelihatan lengkap.

sudo -u postgres psql -v ON_ERROR_STOP=1 <<'SQL'
CREATE USER listmonk WITH PASSWORD 'pick-a-long-random-password';
CREATE DATABASE listmonk OWNER listmonk;
SQL

OWNER listmonk bukan sekadar hiasan. Pemasangan skema mencipta jadual, jenis data, indeks dan fungsi, jadi peranan tersebut mesti menjadi pemilik pangkalan data. Jika anda menghalakan Listmonk kepada pangkalan data yang dimiliki oleh peranan lain, pemasangan akan terhenti dengan permission denied, walaupun selepas anda menjalankan GRANT CONNECT.

Sahkan pangkalan data wujud sebelum anda meneruskan langkah seterusnya.

sudo -u postgres psql -tAc "SELECT datname FROM pg_database WHERE datname='listmonk';"

Perintah tersebut akan memaparkan listmonk. Baris kosong bermakna pernyataan CREATE tidak pernah dijalankan, jadi baca semula output psql anda.

Memasang binari Listmonk

Listmonk menerbitkan binari statik mengikut seni bina. Semak seni bina anda terlebih dahulu, kerana binari amd64 pada VPS ARM ialah fail yang kernel enggan laksanakan.

dpkg --print-architecture
cd /tmp
curl -fsSLO https://github.com/knadh/listmonk/releases/download/v6.2.0/listmonk_6.2.0_linux_amd64.tar.gz
tar -xzf listmonk_6.2.0_linux_amd64.tar.gz
sudo install -m 755 listmonk /usr/bin/listmonk
listmonk --version

Pada VPS ARM, tukar amd64 kepada arm64 dalam nama fail. listmonk --version mencetak rentetan versi ialah bukti pertama anda bahawa binari tersebut sepadan dengan mesin anda.

Menjana config.toml dan mengehadkan aksesnya

--new-config menulis config.toml ke dalam direktori kerja semasa. Itulah sebabnya cd diletakkan di dalam sh -c, dan bukan sebelum sudo.

sudo install -d -m 750 /etc/listmonk
sudo sh -c 'cd /etc/listmonk && listmonk --new-config'

Fail yang dijana adalah ringkas. Di bawah [app], address = "localhost:9000" mengikat pelayan HTTP kepada loopback sahaja, supaya panel pentadbir tidak boleh dicapai dari internet sehingga anda meletakkan reverse proxy di hadapannya. Jangan ubah baris tersebut. Di bawah [db] anda akan mendapati host = "localhost", port = 5432, user = "listmonk", database = "listmonk" dan ssl_mode = "disable". Nilai lalai tersebut sudah sepadan dengan pangkalan data yang anda cipta, jadi satu-satunya baris yang perlu anda ubah ialah kata laluan.

ssl_mode = "disable" adalah tepat selagi Postgres mendengar pada loopback di mesin yang sama, kerana trafik tersebut tidak pernah keluar dari mesin itu. Pindahkan pangkalan data ke hos lain dan tetapkan kepada require, atau kata laluan tersebut akan merentasi rangkaian dalam teks jelas (cleartext).

Sunting baris kata laluan di bawah [db] supaya sepadan dengan peranan tersebut, kemudian cipta akaun servis dan sekat akses fail tersebut daripada semua log masuk lain.

sudo useradd --system --home-dir /var/lib/listmonk --create-home --shell /usr/sbin/nologin listmonk
sudo chown -R root:listmonk /etc/listmonk
sudo chmod 640 /etc/listmonk/config.toml

Kini akaun servis boleh membaca fail tersebut dan tiada akaun lain yang boleh berbuat demikian.

sudo -u listmonk cat /etc/listmonk/config.toml > /dev/null && echo readable
stat -c '%U:%G %a' /etc/listmonk/config.toml

Perintah pertama memaparkan readable. Perintah kedua memaparkan root:listmonk 640. Mana-mana akaun tanpa keistimewaan lain yang mencuba cat yang sama akan mendapat Permission denied, itulah tujuannya: fail ini menyimpan kata laluan pangkalan data anda dalam teks jelas, dan pelayan biasanya mempunyai lebih daripada satu log masuk. Penaakulan yang sama terpakai kepada setiap servis yang anda jalankan, jadi baca pengguna servis dengan keistimewaan minimum sekali dan gunakannya di mana-mana.

Cipta skema dengan --install

--install membina jadual dan memasukkan tetapan lalai. Tetapkan log masuk pentadbir pertama dengan pemboleh ubah persekitaran (environment variables), supaya akaun tersebut wujud sebelum panel boleh diakses.

sudo -u listmonk env LISTMONK_ADMIN_USER=admin \
  LISTMONK_ADMIN_PASSWORD='another-long-random-password' \
  listmonk --config /etc/listmonk/config.toml --install --yes

--yes menjawab gesaan pengesahan. Baca gesaan tersebut sekali sebelum anda mengautomasikannya, kerana --install ialah pemasang kali pertama dan ia akan memadamkan skema Listmonk yang sedia ada. Menjalankannya buat kali kedua pada pangkalan data yang sedang digunakan akan memusnahkan data pelanggan anda. Dalam mana-mana skrip yang mungkin berjalan dua kali, gunakan --install --idempotent --yes, yang tidak melakukan apa-apa apabila jadual sudah pun wujud. Perubahan skema yang disertakan dalam keluaran (release) baharu digunakan dengan --upgrade, bukan dengan --install.

Semak hasil daripada sisi pangkalan data dan bukannya daripada pelayar web.

sudo -u postgres psql -d listmonk -c '\dt'
sudo -u postgres psql -d listmonk -tAc "SELECT username FROM users;"

Perintah pertama menyenaraikan jadual Listmonk, antaranya subscribers, lists, campaigns, templates dan bounces. Perintah kedua mencetak admin. Hasil kosong daripada perintah kedua bermakna pemboleh ubah persekitaran tidak sampai kepada proses tersebut, jadi panel akan meminta anda mencipta pengguna pertama di dalam pelayar web sebagai gantinya.

Menjalankan Listmonk di bawah systemd

Tulis /etc/systemd/system/listmonk.service.

[Unit]
Description=Listmonk newsletter and mailing list manager
After=network-online.target postgresql.service
Wants=network-online.target

[Service]
Type=simple
User=listmonk
Group=listmonk
WorkingDirectory=/var/lib/listmonk
ExecStart=/usr/bin/listmonk --config /etc/listmonk/config.toml
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

WorkingDirectory adalah penting kerana Listmonk menyelesaikan laluan relatif, termasuk laluan muat naik media sistem fail, berdasarkan laluan tersebut. After=postgresql.service hanya mengarahkan permulaan, ia tidak menunggu Postgres menerima sambungan, jadi Restart=on-failure menangani situasi di mana Listmonk bermula terlalu awal dan gagal untuk menyambung.

sudo systemctl daemon-reload
sudo systemctl enable --now listmonk
ss -ltnp | grep 9000
curl -sI http://127.0.0.1:9000/

ss sepatutnya menunjukkan 127.0.0.1:9000 dalam keadaan LISTEN. curl yang mengembalikan sebarang baris status HTTP bermakna pelayan sedang menjawab. curl yang gagal dengan Connection refused bermakna proses tersebut mati semasa permulaan, dan journalctl -u listmonk -n 50 --no-pager akan menyatakan puncanya. Perhatikan bahawa enable --now adalah bahagian yang kekal selepas but semula: proses yang dimulakan secara manual akan hilang selepas naik taraf kernel yang seterusnya.

Letakkan nginx dan TLS di hadapan

Listmonk menggunakan HTTP biasa pada loopback, jadi nginx melakukan penamatan TLS (transport layer security) dan memajukan permintaan tersebut.

server {
    listen 443 ssl;
    server_name lists.example.com;

    client_max_body_size 25m;

    location / {
        proxy_pass http://127.0.0.1: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;
    }
}

client_max_body_size perlu ditingkatkan kerana import pelanggan dan muat naik media adalah hantaran fail, dan nginx menolak sebarang saiz melebihi 1 MB secara lalai dengan 413 Request Entity Too Large. Terbitkan sijil dengan certbot, yang juga akan menulis baris listen 443 ssl serta redirect daripada port 80 untuk anda: langkah-langkahnya ada dalam panduan sijil Let's Encrypt untuk nginx. Buka port 80 dan 443, dan biarkan 9000 tertutup, memandangkan proksi mencapainya melalui loopback. Jika firewall masih belum disentuh, mulakan dengan asas firewall ufw.

Kemudian, buka panel admin dan tetapkan URL root di bawah Settings kepada https://lists.example.com. Pemasangan baharu membawa http://localhost:9000, dan Listmonk menulis nilai tersebut ke dalam setiap pautan nyalanggan (unsubscribe) dan URL media yang diletakkan di dalam e-mel. Jika anda menghantar kempen sebelum menukarnya, setiap penerima akan mendapat pautan yang menghala ke mesin mereka sendiri. Pautan tersebut akan gagal untuk pembaca, dan bagi penapis spam, ia kelihatan seperti penghantar yang tidak mampu mengkonfigurasi domain sendiri.

Menyambungkan SMTP yang tiada dalam config.toml

Cari config.toml untuk bahagian SMTP dan anda tidak akan menemuinya. Tetapan e-mel disimpan di dalam pangkalan data, dalam jadual settings, dan anda perlu menyuntingnya di panel admin di bawah Settings dan SMTP. Itulah sebabnya fail yang dijana kekal pendek, dan itulah juga sebabnya perubahan SMTP tidak memerlukan but semula (restart).

Terdapat dua pilihan yang wajar untuk pelayan SMTP itu sendiri. Jalankan pelayan anda sendiri, yang meletakkan reputasi sepenuhnya di tangan anda dan merupakan satu projek yang besar: menjalankan pelayan e-mel anda sendiri dengan Mailcow merangkumi perkara yang terlibat. Atau halakan Listmonk kepada relay transaksi dan biarkan pihak lain mengurus reputasi IP.

Walau apa pun caranya, gunakan port 587 dengan STARTTLS, atau port 465 dengan TLS tersirat (implicit TLS). Jangan rancang untuk menggunakan port 25 bagi trafik keluar. Kebanyakan penyedia VPS menyekatnya secara lalai pada akaun baharu, dan port 25 yang disekat kelihatan sama seperti sambungan yang tergantung (hung connection), kerana paket digugurkan dan bukannya ditolak, jadi klien akan menunggu sehingga tamat masa (timeout) dan bukannya gagal dengan pantas.

Uji dahulu sebelum anda mempercayainya. Cipta satu senarai, tambah alamat anda sendiri sebagai pelanggan, dan hantar kempen kepada seorang penerima. Buka mesej yang diterima dan baca pengepala (header) penuh. Pengepala Authentication-Results yang ditambah oleh pihak penerima memberitahu anda sama ada SPF dan DKIM telah lulus.

Kebolehpenghantaran adalah tugas utama

Listmonk membina mesej, menjejaki senarai, dan menyerahkan e-mel tersebut. Setiap keputusan sama ada e-mel itu sampai ke peti masuk dibuat oleh penyedia penerima, menggunakan alamat IP penghantar dan domain penghantar. IP VPS baharu tidak mempunyai sejarah langsung, dan tiada sejarah dianggap sebagai sedikit mencurigakan oleh setiap penyedia peti mel yang besar.

Empat perkara ini adalah wajib:

  • Rekod TXT SPF (sender policy framework) yang menamakan hos yang dibenarkan untuk menghantar bagi pihak domain anda.
  • Kunci DKIM (domainkeys identified mail) yang diterbitkan sebagai rekod TXT, dengan penandatanganan dilakukan oleh pelayan e-mel dan bukannya oleh Listmonk.
  • Rekod DMARC (domain based message authentication, reporting and conformance), yang memberitahu penerima perkara yang perlu dilakukan apabila dua perkara pertama gagal.
  • Peti mel lantunan (bounce mailbox) yang dibaca oleh Listmonk, supaya alamat yang menolak e-mel dikeluarkan daripada senarai dan bukannya dicuba semula selama-lamanya.

Kemudian, hantar secara perlahan pada peringkat awal. Domain yang tidak pernah menghantar e-mel dan tiba-tiba menghantar sepuluh ribu mesej dalam satu jam mempunyai corak yang sama seperti akaun yang telah diceroboh, jadi ia akan ditapis sebagai akaun tersebut. Mulakan dengan pelanggan anda yang paling aktif dan tingkatkan jumlahnya sepanjang beberapa hari.

Setiap templat juga memerlukan pautan nyalanggan (unsubscribe) yang berfungsi. Dalam templat Listmonk, ia adalah {{ UnsubscribeURL }}, dan badan kempen diletakkan di tempat {{ template "content" . }} berada, yang mesti muncul tepat sekali bagi setiap templat. Kempen tanpa pautan nyalanggan akan menerima aduan spam dan bukannya nyalanggan, dan aduan adalah cara terpantas untuk kehilangan reputasi penghantaran yang anda ambil masa berminggu-minggu untuk dibina.

Sandaran, dan perkara yang diperlukan untuk pemulihan

Dua perkara mesti dikeluarkan daripada pelayan: dump pangkalan data dan config.toml. Tambahkan direktori media jika anda memuat naik imej ke dalam kempen.

sudo -u postgres pg_dump -Fc listmonk > listmonk-$(date +%F).dump

Dump tersebut menyimpan pelanggan, kempen, templat dan setiap tetapan, termasuk kelayakan SMTP, jadi enkripsikannya dan simpan di luar pelayan ini. Penjadualan untuk perkara ini sudah diselesaikan: lihat sandaran restic terenkripsi ke storan jauh. config.toml hanya mengandungi beberapa baris tetapi menyimpan kata laluan pangkalan data, jadi kendalikannya dengan cara yang sama.

Naik taraf perlu mengikut satu urutan. Hentikan servis, buat dump, gantikan binari dalam /usr/bin, jalankan listmonk --config /etc/listmonk/config.toml --upgrade, kemudian mulakan servis. Migrasi skema hanya berjalan ke hadapan, jadi dump tersebut adalah satu-satunya jalan kembali anda.

Mengapa Listmonk gagal bermula?

Baca jurnal terlebih dahulu dengan journalctl -u listmonk -n 50 --no-pager. Hampir setiap kegagalan permulaan adalah satu baris dalam blok [db].

pq: password authentication failed for user "listmonk" bermaksud kata laluan dalam [db] tidak sepadan dengan peranan Postgres. Awalan pq ialah pemacu Postgres yang melaporkan penolakan pelayan, jadi konfigurasi telah dibaca dengan betul tetapi kelayakan adalah salah. Tetapkan semula peranan dengan sudo -u postgres psql -c "ALTER USER listmonk WITH PASSWORD 'new-password';" dan masukkan rentetan yang sama ke dalam fail tersebut.

pq: database "listmonk" does not exist bermaksud nilai database dalam [db] tidak menamakan pangkalan data yang sebenar. sudo -u postgres psql -l menyenaraikan apa yang sebenarnya ada pada pelayan, termasuk ejaan yang anda gunakan secara tidak sengaja.

permission denied semasa --install bermaksud peranan tersebut boleh bersambung tetapi tidak memiliki pangkalan data, jadi ia tidak boleh mencipta jadual di dalamnya. Betulkan dengan sudo -u postgres psql -c "ALTER DATABASE listmonk OWNER TO listmonk;" dan jalankan pemasangan sekali lagi.

Servis tidak pernah bermula dan jurnal menamakan fail konfigurasi. Proses yang berjalan sebagai listmonk tidak boleh membuka config.toml yang ditinggalkan sebagai root:root dengan mod 600. stat -c '%U:%G %a' /etc/listmonk/config.toml sepatutnya mencetak root:listmonk 640, dan direktori di atasnya sepatutnya root:listmonk 750.

Panel berfungsi tetapi tiada e-mel sampai. Itu bukan masalah permulaan. Semak Tetapan dan SMTP dahulu, kemudian log kempen itu sendiri dalam panel admin, yang merekodkan ralat yang dikembalikan oleh pelayan e-mel bagi setiap percubaan.

FAQ

Adakah saya memerlukan pelayan e-mel sendiri untuk menggunakan Listmonk?

Tidak. Listmonk bukan sebuah pelayan e-mel. Ia memerlukan kelayakan SMTP bagi pelayan yang menerima dan menghantar e-mel anda, sama ada geganti transaksi (transactional relay) atau pelayan e-mel yang anda kendalikan sendiri. Tetapkan kelayakan tersebut di bawah Settings dan SMTP dalam panel pentadbir, bukan dalam config.toml, kerana tetapan e-mel disimpan di dalam pangkalan data. Gunakan port 587 dengan STARTTLS atau port 465 dengan TLS tersirat, memandangkan kebanyakan penyedia VPS menyekat port 25 keluar pada akaun baharu.

Mengapa pautan dalam kempen saya menghala ke localhost:9000?

Tetapan URL akar masih berada pada nilai lalai pemasangan iaitu http://localhost:9000. Listmonk menulis nilai tersebut ke dalam pautan nyalanggan dan URL media pada saat kempen dihantar. Buka Settings dalam panel pentadbir, tetapkan URL akar kepada alamat HTTPS sebenar anda, kemudian simpan. Mesej yang telah dihantar tidak boleh diperbetulkan, jadi hantarkan kempen ujian kepada diri sendiri dan klik pautan nyalanggan di dalamnya sebelum anda menghantar e-mel kepada senarai sebenar.

Adakah menjalankan --install sekali lagi akan memadamkan pelanggan saya?

Ya. --install ialah pemasang kali pertama dan ia akan membuang skema Listmonk yang sedia ada, manakala --yes membuang gesaan yang sepatutnya memberi amaran kepada anda. Dalam mana-mana skrip yang mungkin dijalankan dua kali, gunakan --install --idempotent --yes, yang tidak melakukan apa-apa apabila jadual sudah wujud. Untuk menggunakan perubahan skema dalam keluaran baharu, hentikan servis, buat pg_dump, kemudian jalankan --upgrade.

Mengapa Listmonk menyatakan pengesahan kata laluan gagal untuk pengguna listmonk?

Kata laluan dalam blok [db] pada /etc/listmonk/config.toml tidak sepadan dengan peranan Postgres yang mempunyai nama yang sama. Baris jurnal adalah pq: password authentication failed for user "listmonk", dan pq ialah pemacu Postgres yang menyampaikan penolakan daripada pelayan, yang bermaksud fail konfigurasi telah ditemui dan dibaca. Tetapkan semula kata laluan peranan tersebut dengan sudo -u postgres psql -c "ALTER USER listmonk WITH PASSWORD 'new-password';", tulis rentetan yang sama ke dalam fail konfigurasi, kemudian jalankan sudo systemctl restart listmonk.