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

Jinsi ya kuweka Prowlarr, Sonarr na Radarr kwenye Docker

Jifunze kuendesha Prowlarr, Sonarr, Radarr na qBittorrent kwenye faili moja ya Docker Compose. Pata usanidi sahihi wa PUID, PGID na volume ili kuruhusu hardlinks kufanya kazi.

Unachojenga

Stack ya Docker Compose ya arr ina containers nne zinazosimamia maktaba ya media: Prowlarr kwa ajili ya mipangilio ya indexer, Sonarr kwa ajili ya mfululizo wa vipindi (series), Radarr kwa ajili ya filamu, na qBittorrent kama mteja wa kupakua. Zinawasiliana kupitia mtandao wa Compose kwa kutumia jina la huduma, na zinashiriki mti mmoja wa folda kwenye seva pangishi (host). Usakinishaji wake ni mfupi. Sehemu inayoamua kama stack hii itafanya kazi kwa miaka mingi au itakupa changamoto kila wiki ni mpangilio wa volume, kwa hivyo mwongozo huu unajikita zaidi kwenye hilo.

Stack hii haikutafutii maudhui. Prowlarr huhifadhi indexer zozote unazoongeza humo, na ni indexer zipi unazotumia ni uamuzi wako na wajibu wako wa kisheria. Mwongozo huu unashughulikia mfumo wa uendeshaji: watumiaji, njia (paths), ruhusa, mtandao wa container, na ukaguzi unaothibitisha kuwa kila kitu kinafanya kazi.

Ikiwa hujawahi kuandika faili ya Compose, soma misingi ya Docker Compose kwa VPS kwanza. Chapisho hili linachukulia kuwa docker compose version tayari inatoa matokeo kwenye seva yako.

Wakati Sonarr inapomaliza kupakua faili, huhamishia faili hiyo kwenye maktaba yako. Ikiwa folda ya vipakuliwa na folda ya maktaba zipo kwenye mfumo wa faili (filesystem) uleule, uhamishaji huo huwa ni hardlink: jina la pili linaloelekeza kwenye data ileile iliyopo kwenye diski. Hii haitumii nafasi ya ziada wala muda. Torrent huendelea kuseed kutoka kwenye jina la zamani wakati seva yako ya media ikisoma kutoka kwenye jina jipya.

Ikiwa folda hizo mbili zipo kwenye mifumo ya faili tofauti, kernel haiwezi kutengeneza link hiyo. Sonarr hulazimika kufanya nakala (copy). Msimu wa vipindi wenye ukubwa wa 40 GB sasa unachukua 80 GB ya diski na dakika kadhaa za shughuli za input na output, na logi ya uingizaji hurekodi kuwa hardlink ilishindwa na faili ilinakiliwa badala yake. Kwenye VPS yenye nafasi ndogo ya diski, hivi ndivyo watu wanavyomaliza nafasi ya diski ndani ya wiki moja.

Hapa ndipo mtego ulipo. Ndani ya container, bind mount ni mpaka wa mfumo wa faili. Ukimount /mnt/data/torrents kama /downloads na /mnt/data/media kama /tv, ingawa zote zipo kwenye diski moja ya host, Sonarr huona mount mbili tofauti na hukataa kutengeneza link kati yao. Nyaraka rasmi za image ya LinuxServer.io zinasema hivi moja kwa moja: kutumia njia tofauti za /downloads na /tv kunapoteza uwezo wa kutumia hardlink.

Suluhisho ni mount moja. Kila container inayohusika na media hupata volume moja ileile, /mnt/data:/data, na kila njia wanayotumia ni folda iliyo ndani yake. Sehemu moja ya mount, mfumo mmoja wa faili, na hardlinks hufanya kazi.

Unda mtumiaji, kikundi, na folda

Container huandika faili kama kitambulisho cha mtumiaji (numeric user id), kilichowekwa na PUID na PGID. Tumia akaunti yako mwenyewe ili uweze kusoma na kuhariri faili hizo kupitia SSH bila sudo.

id -u
id -g

Zote mbili kwa kawaida huchapisha 1000 kwenye Ubuntu VPS mpya. Sasa jenga muundo wa folda (tree). Iweke kwenye diski yoyote inayohifadhi media zako, na uhifadhi muundo mzima kwenye diski hiyo moja.

sudo mkdir -p /mnt/data/torrents/movies /mnt/data/torrents/tv
sudo mkdir -p /mnt/data/media/Movies /mnt/data/media/Shows
sudo chown -R 1000:1000 /mnt/data
sudo chmod -R 775 /mnt/data

Thibitisha kuwa kwa kweli ni mfumo mmoja wa faili (filesystem) kabla ya kuendelea:

df --output=source,target /mnt/data/torrents /mnt/data/media

Mistari yote miwili lazima ionyeshe kifaa kilekile cha chanzo (source device). Vifaa viwili tofauti vinamaanisha kuwa hardlinks hazitafanya kazi kamwe, bila kujali unachoweka kwenye usanidi wa container.

Folda za maktaba zimepewa majina ya Movies na Shows kwa makusudi. Ikiwa tayari unaendesha Jellyfin kama seva yako ya media, mount /mnt/data/media ndani ya Jellyfin kama /media na maktaba zake zitatua kwenye /media/Movies na /media/Shows, mahali hasa ambapo mwongozo huo unaziweka.

Faili la mazingira

Weka thamani zinazobadilika kulingana na seva katika .env, karibu na faili la Compose.

mkdir -p ~/arr && cd ~/arr

Andika ~/arr/.env:

PUID=1000
PGID=1000
TZ=Etc/UTC
DATA_ROOT=/mnt/data

Weka TZ kwenye eneo lako la saa, kama vile Europe/Berlin. Programu za arr hupanga kazi na kuweka alama kwenye mistari ya logi kwa kutumia eneo hilo, kwa hivyo thamani isiyo sahihi hufanya kila logi kuwa na utata baadaye.

Faili la Compose

Andika ~/arr/docker-compose.yml:

services:
  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    container_name: prowlarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ./config/prowlarr:/config
    ports:
      - 127.0.0.1:9696:9696
    restart: unless-stopped

  sonarr:
    image: lscr.io/linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ./config/sonarr:/config
      - ${DATA_ROOT}:/data
    ports:
      - 127.0.0.1:8989:8989
    restart: unless-stopped

  radarr:
    image: lscr.io/linuxserver/radarr:latest
    container_name: radarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ./config/radarr:/config
      - ${DATA_ROOT}:/data
    ports:
      - 127.0.0.1:7878:7878
    restart: unless-stopped

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - WEBUI_PORT=8080
      - TORRENTING_PORT=6881
    volumes:
      - ./config/qbittorrent:/config
      - ${DATA_ROOT}:/data
    ports:
      - 127.0.0.1:8080:8080
      - 6881:6881
      - 6881:6881/udp
    stop_grace_period: "10s"
    restart: unless-stopped

Mambo manne katika faili hilo yanafanya kazi halisi.

${DATA_ROOT}:/data inafanana katika kontena zote tatu zinazogusa media. Prowlarr haipati sehemu hii, kwa sababu Prowlarr haifungui faili la media kamwe.

Kila port ya wavuti imefungwa kwenye 127.0.0.1, kwa hivyo Docker inachapisha kwenye anwani ya loopback pekee. 8989:8989 ya kawaida ingeichapisha kwenye kila interface, na sheria za firewall za Docker zenyewe zingepitisha trafiki hiyo moja kwa moja kupita sheria ya ufw deny. Tabia hiyo huwashangaza watu kila mara, na imefafanuliwa katika kwa nini Docker huchapisha ports moja kwa moja kupitia ufw.

Port 6881 imechapishwa kwenye interfaces zote kwa makusudi. Hiyo ndiyo port ya kusikiliza torrent, na lazima iweze kufikika kwa miunganisho ya wenza (peers) inayoingia. Iruhusu kwa sudo ufw allow 6881, na usome misingi ya ufw firewall kwa VPS ikiwa amri hiyo ni ngeni kwako.

Saraka za usanidi (config directories) ni tofauti kwa kila programu, na ni volume ya media pekee inayoshirikiwa. Ziumbe kabla ya kuanza kwa mara ya kwanza ili ziwe zinamilikiwa na mtumiaji wako badala ya root:

mkdir -p ~/arr/config/prowlarr ~/arr/config/sonarr ~/arr/config/radarr ~/arr/config/qbittorrent
docker compose up -d
docker compose ps

Huduma zote nne zinapaswa kusoma running. Kufikia Julai 2026 picha hizi (images) zinachapishwa kwenye lscr.io na tag ya latest inafuata toleo la sasa la stable, kwa hivyo weka tag ya toleo maalum ikiwa unataka masasisho yawe uamuzi badala ya mshangao.

Fikia violesura vya wavuti kwa usalama

Kwa sababu port ziko kwenye loopback, hakuna kitu kinachoweza kufikiwa hadharani bado. Zipeleke kupitia SSH kutoka kwenye mashine yako:

ssh -L 9696:127.0.0.1:9696 -L 8989:127.0.0.1:8989 \
    -L 7878:127.0.0.1:7878 -L 8080:127.0.0.1:8080 you@your-server

Sasa http://127.0.0.1:8989 kwenye kivinjari chako inafikia Sonarr kwenye seva. Kwa ufikiaji wa kudumu, weka stack hii nyuma ya Traefik yenye vyeti vya TLS kwa programu nyingi, au fikia seva kupitia VPN ya WireGuard unayojiendeshea mwenyewe. Hakuna programu yoyote kati ya hizi inayopaswa kuwekwa kwenye mtandao wa umma ikiwa na ukurasa wake wa kuingia pekee. Ikiwa utachagua njia ya reverse proxy na ungependa kuwa na akaunti moja kwa violesura vyote vinne badala ya logins nne tofauti za programu za kufuatilia, Authentik inakupa mfumo wa single sign-on wa kujihostia ambao Traefik inaweza kuutekeleza kwenye kila ombi kwa kutumia forward auth.

qBittorrent hutengeneza nenosiri la nasibu la msimamizi wakati wa kuanza kwa mara ya kwanza na kulichapisha kwenye log ya container. Lisome, kisha ulibadilishe kwenye kiolesura cha wavuti:

docker compose logs qbittorrent | grep -i password

Ukikosa kulibadilisha, nenosiri jipya la nasibu litatengenezwa kila wakati wa reboot, na utalazimika kurudi kwenye logs kila mara.

Weka njia za faili ndani ya kila programu

Katika qBittorrent, fungua Options, kisha Downloads, na uweke njia ya msingi ya kuhifadhi (default save path) kuwa /data/torrents. Weka folda ya vipakuliwa visivyokamilika (incomplete-downloads) ndani ya muundo uleule, kama vile /data/torrents/incomplete. Upakuaji unaomalizikia nje ya /data hauwezi kuunganishwa kwa njia ya hardlink kwenye maktaba yako.

Katika Sonarr, fungua Settings, kisha Media Management, na uongeze folda kuu (root folder) ya /data/media/Shows. Katika Radarr, folda kuu ni /data/media/Movies. Hizi ni njia za faili zilizopo ndani ya container. Njia ya faili ya host ya /mnt/data/media/Shows itakataliwa, kwa sababu saraka hiyo haipo kwa mtazamo wa container.

Katika Sonarr na Radarr, fungua Settings, kisha Download Clients, na uongeze qBittorrent. Host ni qbittorrent na port ni 8080. Jina la huduma hufanya kazi kama hostname kwa sababu Compose huweka container zote nne kwenye mtandao mmoja wenye huduma ya ndani ya DNS (domain name system). Usitumie localhost hapa: ndani ya container ya Sonarr, localhost ni Sonarr yenyewe.

Acha sehemu ya Remote Path Mappings ikiwa wazi. Kipengele hicho kipo ili kutafsiri njia ya faili inayoripotiwa na mteja wa kupakua (download client) kuwa njia ambayo programu ya arr inaweza kuiona. Kwa kutumia mount moja ya pamoja ya /data, container zote mbili tayari zinakubaliana kuhusu kila njia ya faili, ambayo ndiyo sababu ya pili inayofanya mpangilio huu kuwa wa manufaa.

Unganisha Prowlarr na Sonarr pamoja na Radarr

Prowlarr husukuma ufafanuzi wa indexer kwenye programu nyingine, kwa hivyo unasanidi indexer mara moja badala ya mara mbili. Inahitaji API (application programming interface) key kutoka kwa kila moja.

Katika Sonarr, fungua Settings, kisha General, na unakili API key. Katika Prowlarr, fungua Settings, kisha Apps, ongeza programu ya Sonarr, na ujaze sehemu tatu. Prowlarr Server ni http://prowlarr:9696. Sonarr Server ni http://sonarr:8989. API Key ni thamani uliyoinakili. Bonyeza Test. Matokeo ya kijani yanamaanisha Prowlarr imefika Sonarr kupitia mtandao wa Compose. Rudia na Radarr kwenye http://radarr:7878.

Matokeo mekundu yanayoonyesha kuwa muunganisho umekataliwa karibu kila mara yanamaanisha jina la huduma si sahihi au kuna prefix ya http:// inayokosekana. Thibitisha kuwa jina linatatuliwa kutoka ndani ya container:

docker compose exec prowlarr curl -sS -o /dev/null -w '%{http_code}\n' http://sonarr:8989

HTTP status code inathibitisha kuwa njia ya mtandao ni sawa. Hitilafu ya utatuzi wa jina inathibitisha kuwa jina la huduma si sahihi.

Usiuamini usanidi huu hadi uone idadi ya viungo (link count). Baada ya kipengee kimoja kuingizwa (import), linganisha faili iliyopakuliwa na faili iliyo kwenye maktaba:

stat -c '%i %h %n' /mnt/data/torrents/tv/*/*.mkv
stat -c '%i %h %n' /mnt/data/media/Shows/*/*/*.mkv

Namba ya kwanza ni inode na ya pili ni idadi ya viungo. Faili iliyounganishwa kwa hardlink inaonyesha inode ileile katika maeneo yote mawili na idadi ya viungo ya 2. Inode mbili tofauti, kila moja ikiwa na idadi ya viungo ya 1, inamaanisha Sonarr imenakili faili hiyo, na logi ya kuingiza (import log) itaonyesha kuwa hardlink imeshindwa.

Fuatilia diski pia. df -h /mnt/data haipaswi kubadilika sana wakati wa import, kwa sababu hardlink huongeza jina tu na si data.

Nini hasa husababisha hitilafu

Hitilafu za ruhusa (permission errors) wakati wa kuingiza data (import) humaanisha kuwa kitambulisho cha mtumiaji (user id) cha container hakiwezi kuandika kwenye folda ya maktaba. Ujumbe huo ni Access to the path ... is denied. Hakikisha kwa kutumia ls -ln /mnt/data/media kuwa kitambulisho cha mmiliki kinalingana na PUID yako, na kumbuka kuwa saraka (directories) zinahitaji bit ya utekelezaji (execute bit) kabla ya container kuweza kuzifikia.

Faili zinazoonekana kumilikiwa na root humaanisha kuwa container ilianza kabla ya saraka ya mwenyeji (host directory) kuwepo, hivyo Docker iliitengeneza kama root. Simamisha stack, chown saraka hiyo, kisha uianzishe tena.

Kufuta torrent kutoka qBittorrent na kukuta faili ya maktaba imepotea humaanisha kuwa import ilikuwa nakala iliyofutwa baadaye, au ulifuta data badala ya kuondoa torrent yenyewe. Kwa kutumia hardlink halisi, kuondoa jina moja huliacha lingine likiwa salama, kwa sababu data huachiliwa tu wakati idadi ya viungo (link count) inapofika sifuri.

Diski kujaa haraka kuliko vyombo vya habari (media) ulivyoongeza ni tatizo la nakala katika hali yake ya gharama kubwa zaidi. Tekeleza ukaguzi wa stat hapo juu kabla ya kununua hifadhi zaidi.

Mahitaji ya stack hii kutoka kwa VPS

Programu tatu za arr ni nyepesi. Huchunguza indexers, huandika kwenye database ndogo ya SQLite, na kubadilisha majina ya faili. Seva yenye 2 GB ya RAM huendesha container zote nne bila shida. Mzigo wa kazi hutoka kwingine. Mteja wa kupakua (download client) huchosha uwezo wa kusoma na kuandika kwenye diski (I/O) wakati wa torrent kubwa, na seva ya media inayofanya transcoding ya video kwenye mashine hiyo hiyo itatumia CPU yote. Hifadhi media kwenye volume yenye throughput ya kutosha, na weka kikomo cha bandwidth kwenye mteja wa kupakua ikiwa seva inafanya kazi nyingine unayojali. Tengeneza bajeti ya vitu hivyo vingine kando badala ya kudhani kuwa kuna nafasi ya ziada: a self-hosted AFFiNE workspace ni container nyingine nne zenye database nyuma yake, na kwenye mashine ya 2 GB inataka sehemu kubwa ya kumbukumbu hiyo yenyewe. Sio kila huduma ya ziada inagharimu kiasi hicho: kitu chenye lengo moja kama a self-hosted openGym workout tracker hushiriki mashine hiyo kwa furaha, mradi tu uipe TLS yake mwenyewe na ujue faili lake la database lilipo kabla ya kuliwekea historia ya mwaka mzima ya mazoezi. Chochote kinachobeba programu ya web, database ya Postgres na foleni ya background worker kiko karibu na upande wa AFFiNE wa kipimo hicho, kwa hivyo amua kama a self-hosted Chatwoot support desk inafaa kuwa kwenye seva hii au kwenye seva yake yenyewe kabla ya kugundua kikomo katikati ya import. Mizigo ya kazi inayokuja kwa ghafla (bursty workloads) inahitaji tahadhari zaidi, kwa sababu kilele chake badala ya wastani wake ndicho kinachogongana na import: ikiwa unafikiria a self-hosted OneCLI handing each person their own sandboxed agent, angalia namba zake za ukubwa zilizochapishwa dhidi ya kile ambacho kiko wazi wakati qBittorrent inafanya kazi kwa kasi kamili, si dhidi ya kile ambacho free -h kinaonyesha kwenye mashine iliyopumzika.

FAQ

Kwa sababu chanzo na lengo viko kwenye mifumo tofauti ya faili (filesystems) kwa mtazamo wa container. Bind mounts mbili tofauti, kama vile /downloads na /tv, ni mifumo miwili tofauti ya faili hata kama yote yanatoka kwenye diski moja ya host. Mount saraka moja kuu kama /data katika kila container, weka downloads na library ndani yake, na link itakuwa inawezekana. Thibitisha matokeo kwa stat -c '%i %h %n' kwenye faili zote mbili: inode moja na link count ya 2.

Ni PUID na PGID gani ninapaswa kutumia?

Tumia namba ya kitambulisho (numeric id) ya akaunti ya host inayomiliki mti wa media, ambayo unaipata kupitia id -u na id -g. Kwenye Ubuntu VPS mpya, hiyo mara nyingi ni 1000 kwa zote mbili. Kila container kwenye stack lazima itumie jozi moja, vinginevyo programu moja itaandika faili ambazo nyingine haiwezi kuzibadilisha. Baada ya kubadilisha thamani hizo, tengeneza upya containers kwa docker compose up -d --force-recreate na urekebishe faili zilizopo kwa chown -R.

Je, ninahitaji kufungua interfaces hizi za wavuti kwenye Internet?

Hapana, na hupaswi kufanya hivyo. Bind kila port iliyochapishwa kwenye 127.0.0.1 katika faili ya Compose, kisha fikia interfaces hizo kupitia SSH tunnel, VPN, au reverse proxy inayomalizia TLS (transport layer security) na kuongeza authentication yake yenyewe. Kuzichapisha moja kwa moja ni hatari zaidi kuliko inavyoonekana, kwa sababu Docker huingiza sheria zake za firewall na sheria ya ufw deny haitazuia trafiki hiyo.

Wapi ninaweza kupata nenosiri la qBittorrent?

Image ya LinuxServer.io huchapisha nenosiri la muda kwa mtumiaji wa admin kwenye log yake ya kuanza. Endesha docker compose logs qbittorrent | grep -i password ili kulisoma, kisha weka nenosiri la kudumu chini ya Options na Web UI. Nenosiri jipya la muda hutengenezwa kila unapoanzisha upya hadi utakapoweka lako mwenyewe.

Je, Jellyfin inaweza kutumia folda zilezile?

Ndiyo, na ndilo lengo la mpangilio huu. Mount /mnt/data/media kwenye seva yako ya media kama /media, na library zake zitakaa kwenye /media/Movies na /media/Shows wakati Sonarr na Radarr wakiandika kwenye saraka zilezile kupitia /data/media. Ipe seva ya media PUID na PGID zilezile ili iweze kusoma kile ambacho stack ya arr inaandika.

#sonarr#radarr#prowlarr#docker-compose#self-hosting