SSD Nodes Learn Hosting plans →
Mwongozo Matt ConnorNa Matt Connor · Imeboreshwa 2026-08-07

Jinsi ya kusakinisha Listmonk kwenye VPS ya Ubuntu 24.04

Jifunze kusakinisha Listmonk v6.2.0 kwa kutumia PostgreSQL na systemd kwenye Ubuntu 24.04. Mwongozo huu unaeleza usanidi wa config.toml, TLS, na gharama halisi za SMTP.

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

Mahitaji ya newsletter inayojiendesha yenyewe kupitia Listmonk

Listmonk ni meneja wa newsletter na orodha ya barua pepe inayojiendesha yenyewe: ina binary moja ya Go, database moja ya PostgreSQL, faili moja ya usanidi, na unit moja ya systemd. VPS ndogo inaweza kuiendesha bila shida, kwa sababu Listmonk huhifadhi waliojisajili na kupanga foleni za kampeni lakini haipeleki barua pepe yenyewe. Hukabidhi kila ujumbe kwa seva ya SMTP (simple mail transfer protocol), kwa hivyo kiwango chako cha uwasilishaji huamuliwa na sifa ya seva hiyo na si kwa programu hii.

Mwongozo huu unasakinisha Listmonk v6.2.0, toleo la sasa kufikia Julai 2026, kwenye Ubuntu 24.04. Unahitaji VPS yenye anwani ya IP ya umma, jina la domain unalolimiliki, na PostgreSQL 12 au mpya zaidi. Usakinishaji huchukua takriban saa moja. Sifa ya utumaji barua pepe huchukua wiki kadhaa kujengeka, na sehemu hiyo imeelezwa karibu na mwisho.

Sakinisha PostgreSQL na uunde database

Ubuntu 24.04 inatoa PostgreSQL 16 katika hazina zake rasmi, toleo ambalo linazidi mahitaji ya Listmonk.

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

Unda role na database katika kipindi kimoja cha psql. -v ON_ERROR_STOP=1 inafanya psql kusitisha kazi ikikuta amri ya kwanza iliyofeli, ili kosa la kuandika (typo) lisikuachie usanidi nusu ambao unaonekana umekamilika.

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 siyo mapambo. Usakinishaji wa schema huunda majedwali, aina za data (types), indexes na functions, kwa hivyo role lazima imiliki database hiyo. Ukielekeza Listmonk kwenye database inayomilikiwa na role nyingine, usakinishaji utasitishwa kwa permission denied, hata baada ya wewe kuendesha GRANT CONNECT.

Thibitisha kuwa database ipo kabla ya kuendelea.

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

Hiyo inachapisha listmonk. Mstari mtupu unamaanisha kuwa amri ya CREATE haikuwahi kuendeshwa, kwa hivyo soma tena matokeo ya psql.

Sakinisha binary ya Listmonk

Listmonk hutoa binary tuli kwa kila usanifu wa mfumo (architecture). Hakikisha unajua usanifu wako kwanza, kwa sababu binary ya amd64 kwenye VPS ya ARM ni faili ambalo kernel itakataa kuliendesha.

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

Kwenye VPS ya ARM, badilisha amd64 na arm64 katika jina la faili. listmonk --version kuchapisha string ya toleo ni uthibitisho wako wa kwanza kwamba binary hiyo inalingana na mashine yako.

Tengeneza config.toml na uilinde

--new-config huandika config.toml kwenye saraka ya sasa ya kazi. Hii ndiyo sababu cd inakaa ndani ya sh -c, na si kabla ya sudo.

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

Faili lililotengenezwa ni fupi. Chini ya [app], address = "localhost:9000" hufunga seva ya HTTP kwenye loopback pekee, hivyo paneli ya usimamizi haipatikani kutoka kwenye Internet hadi utakapoweka reverse proxy mbele yake. Acha mstari huo kama ulivyo. Chini ya [db] utapata host = "localhost", port = 5432, user = "listmonk", database = "listmonk" na ssl_mode = "disable". Chaguo-msingi hizo tayari zinalingana na database uliyounda, kwa hivyo mstari pekee unaopaswa kubadilisha ni nenosiri.

ssl_mode = "disable" ni sahihi wakati Postgres inasikiliza kwenye loopback kwenye mashine hiyo hiyo, kwa sababu trafiki hiyo haitoki nje ya mashine. Hamisha database kwenye host nyingine na uiweke kuwa require, la sivyo nenosiri litapita kwenye mtandao likiwa wazi (cleartext).

Hariri mstari wa nenosiri chini ya [db] ili ulingane na role, kisha unda akaunti ya huduma na uondoe faili hilo kutoka kwa login nyingine yoyote.

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

Sasa akaunti ya huduma inaweza kusoma faili hilo na hakuna mwingine anayeweza.

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

Amri ya kwanza huchapisha readable. Ya pili huchapisha root:listmonk 640. Akaunti nyingine yoyote isiyo na upendeleo inayojaribu cat hiyo hiyo hupata Permission denied, ambayo ndiyo lengo: faili hili linashikilia nenosiri la database yako likiwa wazi, na seva kwa kawaida huwa na login zaidi ya moja. Sababu hiyo hiyo inatumika kwa kila huduma unayoendesha, kwa hivyo soma watumiaji wa huduma wenye upendeleo mdogo mara moja na uitumie kila mahali.

Unda schema kwa kutumia --install

--install hujenga majedwali na kuweka mipangilio ya awali. Weka login ya kwanza ya admin kwa kutumia environment variables, ili akaunti iwepo kabla ya paneli kufikiwa.

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

--yes hujibu ombi la uthibitisho. Soma ombi hilo mara moja kabla ya kulifanya kiotomatiki, kwa sababu --install ni kisakinishi cha mara ya kwanza na hufuta schema ya Listmonk iliyopo. Kukiendesha mara ya pili kwenye database inayotumika kutafuta taarifa za waliojisajili (subscribers). Katika script yoyote inayoweza kuendeshwa mara mbili, tumia --install --idempotent --yes, ambayo haifanyi kitu chochote ikiwa majedwali tayari yapo. Mabadiliko ya schema yaliyotolewa katika release mpya hutumika kwa --upgrade, kamwe usitumie --install.

Kagua matokeo kutoka upande wa database badala ya kivinjari.

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

Ya kwanza huorodhesha majedwali ya Listmonk, miongoni mwao yakiwa ni subscribers, lists, campaigns, templates na bounces. Ya pili huchapisha admin. Matokeo matupu kutoka kwa ya pili inamaanisha kuwa environment variables hazikufika kwenye mchakato, kwa hivyo paneli itakuomba uunde mtumiaji wa kwanza kwenye kivinjari badala yake.

Endesha Listmonk chini ya systemd

Andika /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 ni muhimu kwa sababu Listmonk hutatua njia za faili (relative paths), ikiwemo njia ya kupakia media kwenye mfumo wa faili, kulingana na njia hiyo. After=postgresql.service huamuru tu kuanza kwa huduma, haisubiri Postgres ikubali miunganisho, kwa hivyo Restart=on-failure hushughulikia hali ambapo Listmonk huanza mapema mno na inashindwa kuunganishwa.

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

ss inapaswa kuonyesha 127.0.0.1:9000 katika hali ya LISTEN. curl ikirejesha mstari wowote wa hali ya HTTP inamaanisha seva inajibu. curl ikifeli na Connection refused inamaanisha mchakato umekufa wakati wa kuanza, na journalctl -u listmonk -n 50 --no-pager itaeleza sababu. Kumbuka kuwa enable --now ndiyo sehemu inayobaki baada ya reboot: mchakato ulioanzishwa kwa mkono hupotea baada ya upgrade inayofuata ya kernel.

Weka nginx na TLS mbele

Listmonk hutumia HTTP ya kawaida kwenye loopback, kwa hivyo nginx hushughulikia TLS (transport layer security) na kusambaza ombi hilo.

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 lazima iongezwe kwa sababu uingizaji wa wasajili na upakiaji wa midia ni file posts, na nginx hukataa chochote kinachozidi 1 MB kwa chaguo-msingi kupitia 413 Request Entity Too Large. Toa cheti kwa kutumia certbot, ambayo pia huandika mistari ya listen 443 ssl na redirect kutoka port 80 kwa ajili yako: hatua hizi ziko katika mwongozo wa cheti cha Let's Encrypt kwa nginx. Fungua port 80 na 443, na uache 9000 ikiwa imefungwa, kwa kuwa proxy huifikia kupitia loopback. Ikiwa firewall bado haijaguswa, anza na misingi ya ufw firewall.

Kisha fungua paneli ya admin na uweke root URL chini ya Settings kuwa https://lists.example.com. Usakinishaji mpya huwa na http://localhost:9000, na Listmonk huandika thamani hiyo katika kila kiungo cha kujiondoa (unsubscribe link) na URL ya midia inayoweka kwenye barua pepe. Tuma kampeni kabla ya kuibadilisha na kila mpokeaji atapata viungo vinavyoelekeza kwenye mashine yao wenyewe. Viungo hivyo vitafeli kwa msomaji, na kwa kichujio cha spam, vitaonekana kama mtumaji asiyeweza kusanidi kikoa chake mwenyewe.

Kuunganisha SMTP, ambayo haipo kwenye config.toml

Tafuta config.toml kwa ajili ya sehemu ya SMTP na hutaipata. Mipangilio ya barua pepe inakaa kwenye database, ndani ya jedwali la settings, na unaihariri katika paneli ya admin chini ya Settings na SMTP. Hiyo ndiyo sababu faili lililozalishwa linabaki kuwa fupi, na pia ndiyo sababu mabadiliko ya SMTP hayahitaji kuanzisha upya (restart).

Kuna chaguo mbili za kweli kwa seva ya SMTP yenyewe. Endesha seva yako mwenyewe, jambo ambalo linaweka sifa (reputation) mikononi mwako na ni mradi mkubwa peke yake: kuendesha seva yako ya barua pepe kwa kutumia Mailcow inaelezea mambo yanayohusika. Au elekeza Listmonk kwenye transactional relay na umruhusu mtu mwingine ashughulikie sifa ya IP.

Vyovyote vile, tumia port 587 na STARTTLS, au port 465 na implicit TLS. Usipange kutumia port 25 kwa mawasiliano ya nje (outbound). Watoa huduma wengi wa VPS huizuia kwa chaguo-msingi kwenye akaunti mpya, na port 25 iliyozuiwa inaonekana kama muunganisho uliokwama, kwa sababu pakiti hutupwa badala ya kukataliwa, hivyo mteja husubiri hadi muda uishe (timeout) badala ya kushindwa haraka.

Ijaribu kabla ya kuiamini. Unda orodha, ongeza anwani yako kama msajili, na utume kampeni kwa mpokeaji mmoja. Fungua ujumbe uliopokelewa na usome vichwa vya habari (headers) kamili. Kichwa cha habari cha Authentication-Results kilichoongezwa na upande unaopokea kitakuambia kama SPF na DKIM zimefaulu.

Uwezo wa kufikisha barua ndio kazi nzima

Listmonk huandaa ujumbe, hufuatilia orodha, na kukabidhi barua. Uamuzi wowote kuhusu kama barua hiyo itafika kwenye kikasha (inbox) hufanywa na mtoa huduma anayepokea, kwa kutumia anwani ya IP ya kutuma na kikoa (domain) cha kutuma. IP ya VPS mpya haina historia yoyote, na kila mtoa huduma mkubwa wa barua pepe huichukulia hali ya kutokuwa na historia kama jambo la kutiliwa shaka kidogo.

Mambo manne haya si ya hiari:

  • Rekodi ya TXT ya SPF (sender policy framework) inayotaja mwenyeji (host) anayeruhusiwa kutuma kwa niaba ya kikoa chako.
  • Ufunguo wa DKIM (domainkeys identified mail) uliowekwa kama rekodi ya TXT, huku utiaji saini ukifanywa na seva ya barua pepe badala ya Listmonk.
  • Rekodi ya DMARC (domain based message authentication, reporting and conformance), inayowaambia wapokeaji nini cha kufanya wakati mawili ya kwanza yanaposhindwa.
  • Kikasha cha bounce ambacho Listmonk hukisoma, ili anwani zinazokataa barua ziondoke kwenye orodha badala ya kujaribiwa tena milele.

Kisha tuma polepole mwanzoni. Kikoa ambacho hakijawahi kutuma barua na ghafla kikafikisha ujumbe elfu kumi kwa saa moja kina umbo sawa na akaunti iliyovamiwa (compromised), kwa hivyo huchujwa kama hiyo. Anza na waliojisajili wanaoshiriki zaidi na ongeza idadi ya barua kwa siku kadhaa.

Kila kiolezo (template) pia kinahitaji kiungo cha kujiondoa (unsubscribe link) kinachofanya kazi. Katika kiolezo cha Listmonk, hicho ni {{ UnsubscribeURL }}, na mwili wa kampeni huwekwa pale {{ template "content" . }} ilipo, ambayo lazima ionekane mara moja tu kwa kila kiolezo. Kampeni isiyo na kiungo cha kujiondoa hupata malalamiko ya spam badala ya kujiondoa, na malalamiko ndiyo njia ya haraka zaidi ya kupoteza sifa ya kutuma barua uliyotumia wiki kadhaa kuijenga.

Backup, na kile ambacho urejeshaji unahitaji kihalisi

Vitu viwili lazima vitoke kwenye seva: dump ya database na config.toml. Ongeza saraka ya media ikiwa unapakia picha kwenye kampeni.

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

Dump hiyo inashikilia waliojisajili, kampeni, templeti na kila mpangilio, ikiwemo vitambulisho vya SMTP, kwa hivyo iweke kwa njia fiche (encrypt) na uiweke nje ya seva hii. Kupanga ratiba hiyo ni tatizo lililotatuliwa: tazama backup za restic zilizofichwa kwenye hifadhi ya mbali. config.toml ni mistari michache lakini inashikilia nenosiri la database, kwa hivyo itendee kwa njia hiyo hiyo.

Uboreshaji hufuata utaratibu mmoja. Simamisha huduma, chukua dump, badilisha binary katika /usr/bin, endesha listmonk --config /etc/listmonk/config.toml --upgrade, kisha anza huduma. Uhamiaji wa schema (schema migrations) huenda mbele tu, kwa hivyo dump hiyo ndiyo njia yako pekee ya kurudi nyuma.

Kwa nini Listmonk inashindwa kuanza?

Soma logi ya mfumo kwanza kwa kutumia journalctl -u listmonk -n 50 --no-pager. Karibu kila hitilafu ya kuanza huduma inaonekana kwenye mstari mmoja ndani ya block ya [db].

pq: password authentication failed for user "listmonk" inamaanisha nenosiri lililo kwenye [db] halilingani na role ya Postgres. Kiambishi cha pq ni dereva wa Postgres anayetoa taarifa ya kukataliwa na seva, kwa hivyo usanidi ulisomwa kwa usahihi lakini vitambulisho vilikuwa vibaya. Weka upya role hiyo kwa sudo -u postgres psql -c "ALTER USER listmonk WITH PASSWORD 'new-password';" na uweke mfuatano uleule wa herufi kwenye faili.

pq: database "listmonk" does not exist inamaanisha thamani ya database iliyo kwenye [db] haitaji database halisi. sudo -u postgres psql -l huorodhesha kilichopo kwenye seva, ikijumuisha tahajia uliyotumia kimakosa.

permission denied wakati wa --install inamaanisha role inaweza kuunganishwa lakini haina umiliki wa database hiyo, kwa hivyo haiwezi kutengeneza majedwali ndani yake. Rekebisha kwa sudo -u postgres psql -c "ALTER DATABASE listmonk OWNER TO listmonk;" na uendeshe usakinishaji tena.

Huduma haianzishi na logi inataja faili ya usanidi. Mchakato unaoendeshwa kama listmonk hauwezi kufungua config.toml iliyoachwa kama root:root yenye mode 600. stat -c '%U:%G %a' /etc/listmonk/config.toml inapaswa kuchapisha root:listmonk 640, na saraka iliyo juu yake inapaswa kuwa root:listmonk 750.

Paneli inafanya kazi lakini hakuna barua pepe inayofika. Hilo si tatizo la kuanza huduma. Kagua Settings na SMTP kwanza, kisha angalia logi ya kampeni yenyewe kwenye paneli ya utawala, ambayo hurekodi hitilafu iliyorejeshwa na seva ya barua pepe kwa kila jaribio.

FAQ

Je, ninahitaji seva yangu ya barua pepe ili kutumia Listmonk?

Hapana. Listmonk si seva ya barua pepe. Inahitaji vitambulisho vya SMTP vya seva inayokubali barua zako na kuzisafirisha, ambayo inaweza kuwa relay ya miamala au seva ya barua pepe unayoiendesha mwenyewe. Weka vitambulisho hivyo chini ya Settings na SMTP katika paneli ya admin, siyo ndani ya config.toml, kwa sababu mipangilio ya barua pepe huhifadhiwa kwenye database. Tumia port 587 yenye STARTTLS au port 465 yenye implicit TLS, kwa kuwa watoa huduma wengi wa VPS huzuia port 25 ya kutoka kwenye akaunti mpya.

Kwa nini viungo katika kampeni yangu vinaelekeza kwenye localhost:9000?

Mpangilio wa root URL bado uko kwenye thamani yake ya awali ya usakinishaji ya http://localhost:9000. Listmonk huandika thamani hiyo kwenye viungo vya kujiondoa (unsubscribe) na URL za midia wakati kampeni inapotumwa. Fungua Settings katika paneli ya admin, weka root URL iwe anwani yako halisi ya HTTPS, kisha uhifadhi. Ujumbe uliokwishatumwa hauwezi kurekebishwa, kwa hivyo jitumie kampeni ya majaribio na ubonyeze kiungo cha kujiondoa ndani yake kabla ya kutuma barua pepe kwa orodha halisi.

Je, kuendesha --install tena kutafuta waliojisajili wangu?

Ndiyo. --install ni kisakinishi cha mara ya kwanza na hufuta schema iliyopo ya Listmonk, na --yes huondoa kidokezo ambacho kingekuonya. Katika hati yoyote inayoweza kuendeshwa mara mbili, tumia --install --idempotent --yes, ambayo haifanyi chochote wakati meza (tables) tayari zipo. Ili kutumia mabadiliko ya schema katika toleo jipya, simamisha huduma, chukua pg_dump, kisha uendeshe --upgrade.

Kwa nini Listmonk inasema uthibitishaji wa nenosiri umeshindwa kwa mtumiaji listmonk?

Nenosiri lililo kwenye sehemu ya [db] ya /etc/listmonk/config.toml halilingani na jukumu (role) la Postgres lenye jina hilo hilo. Mstari wa journal ni pq: password authentication failed for user "listmonk", na pq ni dereva wa Postgres anayepitisha kukataliwa kwa seva, jambo linalomaanisha kuwa faili ya usanidi ilipatikana na kusomwa. Weka upya nenosiri la jukumu hilo kwa sudo -u postgres psql -c "ALTER USER listmonk WITH PASSWORD 'new-password';", andika mfuatano uleule wa herufi kwenye faili ya usanidi, kisha uendeshe sudo systemctl restart listmonk.