วิธีตั้งค่า arr stack ด้วย Docker Compose บน VPS
รวม Prowlarr, Sonarr, Radarr และ qBittorrent ไว้ในไฟล์เดียวบน VPS พร้อมตั้งค่า PUID, PGID และ Volume ให้รองรับการทำ Hardlink อย่างถูกต้อง เพื่อลดปัญหาไฟล์ซ้ำซ้อนในระบบ
สิ่งที่คุณกำลังสร้าง
Docker Compose arr stack คือชุดคอนเทนเนอร์ 4 ตัวที่ใช้จัดการคลังสื่อบันเทิง ประกอบด้วย Prowlarr สำหรับตั้งค่า indexer, Sonarr สำหรับซีรีส์, Radarr สำหรับภาพยนตร์ และ qBittorrent สำหรับเป็นไคลเอนต์ดาวน์โหลด บริการเหล่านี้สื่อสารกันผ่านเครือข่ายของ Compose โดยใช้ชื่อ service และใช้โครงสร้างโฟลเดอร์ร่วมกันบนโฮสต์ การติดตั้งนั้นทำได้รวดเร็ว แต่ส่วนที่จะตัดสินว่า stack นี้จะทำงานได้ยาวนานหลายปีหรือสร้างปัญหาให้คุณทุกสัปดาห์คือการจัดวาง volume ดังนั้นเนื้อหาส่วนใหญ่ในคู่มือนี้จึงเน้นไปที่เรื่องดังกล่าว
stack นี้ไม่ได้ทำหน้าที่ค้นหาเนื้อหาให้คุณ Prowlarr จะเก็บ indexer ใดก็ตามที่คุณเพิ่มเข้าไป ซึ่งการเลือกใช้ indexer ใดเป็นเรื่องที่คุณต้องตัดสินใจและรับผิดชอบตามกฎหมายด้วยตนเอง คู่มือนี้จะครอบคลุมเรื่องการวางระบบพื้นฐาน ได้แก่ ผู้ใช้งาน, path, สิทธิ์การเข้าถึง, เครือข่ายของคอนเทนเนอร์ และการตรวจสอบเพื่อให้แน่ใจว่าระบบทำงานได้อย่างถูกต้อง
หากคุณไม่เคยเขียนไฟล์ Compose มาก่อน โปรดอ่าน พื้นฐาน Docker Compose สำหรับ VPS ก่อน บทความนี้ถือว่า docker compose version แสดงผลลัพธ์บนเซิร์ฟเวอร์ของคุณเรียบร้อยแล้ว
เหตุใด hardlink จึงใช้งานไม่ได้ และทำไมเรื่องนี้ถึงสำคัญที่สุด
เมื่อ Sonarr ดาวน์โหลดไฟล์เสร็จสิ้น ระบบจะนำไฟล์เข้าสู่คลังข้อมูลของคุณ หากโฟลเดอร์ดาวน์โหลดและโฟลเดอร์คลังข้อมูลอยู่บนระบบไฟล์ (filesystem) เดียวกัน การนำเข้าไฟล์จะใช้วิธี hardlink ซึ่งเป็นการสร้างชื่อที่สองที่ชี้ไปยังข้อมูลชุดเดียวกันบนดิสก์ วิธีนี้ไม่กินพื้นที่เพิ่มและไม่ต้องใช้เวลาในการประมวลผล Torrent จะยังคงปล่อยไฟล์ (seeding) ต่อไปได้จากชื่อเดิม ในขณะที่ media server ของคุณอ่านไฟล์จากชื่อใหม่ได้พร้อมกัน
หากโฟลเดอร์ทั้งสองอยู่บนระบบไฟล์ที่ต่างกัน เคอร์เนลจะไม่สามารถสร้างลิงก์ดังกล่าวได้ Sonarr จึงต้องเปลี่ยนไปใช้วิธีคัดลอกไฟล์แทน ส่งผลให้ซีรีส์ขนาด 40 GB กลายเป็น 80 GB บนดิสก์และต้องใช้เวลาในการอ่านเขียนข้อมูลนานหลายนาที โดย log การนำเข้าไฟล์จะบันทึกว่า hardlink ล้มเหลวและเปลี่ยนไปใช้การคัดลอกแทน บน VPS ที่มีพื้นที่ดิสก์จำกัด นี่คือสาเหตุที่ทำให้พื้นที่เต็มภายในเวลาเพียงหนึ่งสัปดาห์
นี่คือกับดักที่สำคัญ ภายในคอนเทนเนอร์ การทำ bind mount ถือเป็นการแบ่งขอบเขตของระบบไฟล์ หากคุณ mount /mnt/data/torrents เป็น /downloads และ /mnt/data/media เป็น /tv แม้ว่าทั้งสองจะอยู่บนดิสก์ของโฮสต์เดียวกัน แต่ Sonarr จะมองเห็นเป็น mount ที่แยกจากกันและปฏิเสธที่จะสร้างลิงก์ข้ามกัน เอกสารประกอบของอิมเมจจาก LinuxServer.io ระบุเรื่องนี้ไว้อย่างชัดเจนว่า การใช้ path /downloads และ /tv แยกกัน จะทำให้สูญเสียความสามารถในการทำ hardlink
วิธีแก้ไขคือการใช้ mount เพียงจุดเดียว คอนเทนเนอร์ทุกตัวที่จัดการสื่อบันเทิงจะต้องใช้ volume เดียวกันคือ /mnt/data:/data และทุก path ที่ใช้งานจะต้องเป็นโฟลเดอร์ที่อยู่ภายในนั้น เมื่อมีจุด mount เดียวและระบบไฟล์เดียว hardlink จึงจะทำงานได้อย่างถูกต้อง
สร้างผู้ใช้ กลุ่ม และโฟลเดอร์
คอนเทนเนอร์จะเขียนไฟล์โดยใช้ numeric user id ซึ่งกำหนดโดย PUID และ PGID ให้ใช้บัญชีผู้ใช้ของคุณเองเพื่อให้คุณสามารถอ่านและแก้ไขไฟล์เหล่านั้นผ่าน SSH ได้โดยไม่ต้องใช้ sudo
id -u
id -gโดยปกติแล้วทั้งสองค่าจะแสดงเป็น 1000 บน Ubuntu VPS ที่ติดตั้งใหม่ จากนั้นให้สร้างโครงสร้างไดเรกทอรี โดยวางไว้บนดิสก์ลูกเดียวกับที่เก็บสื่อของคุณ และเก็บโครงสร้างทั้งหมดไว้บนดิสก์ลูกนั้น
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ตรวจสอบให้แน่ใจว่าเป็นระบบไฟล์เดียวกันก่อนดำเนินการต่อ:
df --output=source,target /mnt/data/torrents /mnt/data/mediaทั้งสองบรรทัดต้องแสดงอุปกรณ์ต้นทางเดียวกัน หากเป็นอุปกรณ์สองตัวที่ต่างกัน จะไม่สามารถใช้งาน hardlinks ได้ไม่ว่าคุณจะตั้งค่าในคอนเทนเนอร์ไว้อย่างไรก็ตาม
โฟลเดอร์คลังสื่อถูกตั้งชื่อว่า Movies และ Shows โดยมีจุดประสงค์ หากคุณใช้งาน Jellyfin ในฐานะเซิร์ฟเวอร์สื่อ อยู่แล้ว ให้ mount /mnt/data/media เข้าไปใน Jellyfin ในฐานะ /media ซึ่งคลังสื่อจะไปอยู่ที่ /media/Movies และ /media/Shows ตามที่คู่มือนั้นระบุไว้ทุกประการ
ไฟล์ environment
เก็บค่าที่เปลี่ยนแปลงตามแต่ละเซิร์ฟเวอร์ไว้ใน .env ซึ่งอยู่ถัดจากไฟล์ Compose
mkdir -p ~/arr && cd ~/arrเขียน ~/arr/.env ดังนี้:
PUID=1000
PGID=1000
TZ=Etc/UTC
DATA_ROOT=/mnt/dataตั้งค่า TZ ให้เป็นโซนเวลาของคุณ เช่น Europe/Berlin แอปพลิเคชันตระกูล arr จะกำหนดเวลาทำงานและประทับเวลาใน log ตามโซนเวลานี้ ดังนั้นหากตั้งค่าผิดพลาดจะทำให้การตรวจสอบ log ในภายหลังเกิดความสับสนได้
ไฟล์ Compose
เขียน ~/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มีสี่สิ่งที่ทำงานจริงในไฟล์นั้น
${DATA_ROOT}:/data เหมือนกันในคอนเทนเนอร์ทั้งสามตัวที่เข้าถึงสื่อ Prowlarr ไม่ได้รับส่วนนี้เพราะ Prowlarr ไม่เคยเปิดไฟล์สื่อ
พอร์ตเว็บทุกพอร์ตถูกผูกไว้กับ 127.0.0.1 ดังนั้น Docker จึงเผยแพร่พอร์ตบน loopback address เท่านั้น หากใช้ 8989:8989 เปล่าๆ จะเป็นการเผยแพร่บนทุกอินเทอร์เฟซ และกฎไฟร์วอลล์ของ Docker เองจะนำทราฟฟิกนั้นผ่านกฎ deny ของ ufw ไปโดยตรง พฤติกรรมนี้สร้างความประหลาดใจให้ผู้ใช้อยู่เสมอ และมีการอธิบายไว้ใน เหตุผลที่ Docker เผยแพร่พอร์ตโดยข้าม ufw
พอร์ต 6881 ถูกเผยแพร่บนทุกอินเทอร์เฟซโดยเจตนา นี่คือพอร์ตสำหรับฟังการเชื่อมต่อ torrent และจำเป็นต้องเข้าถึงได้สำหรับการเชื่อมต่อจาก peer ขาเข้า อนุญาตพอร์ตนี้ด้วย sudo ufw allow 6881 และอ่าน พื้นฐานไฟร์วอลล์ ufw สำหรับ VPS หากคำสั่งนี้เป็นเรื่องใหม่สำหรับคุณ
ไดเรกทอรีการตั้งค่าจะแยกกันตามแอปพลิเคชัน และมีเพียงโวลุ่มสื่อเท่านั้นที่ใช้ร่วมกัน ให้สร้างไดเรกทอรีเหล่านั้นก่อนการเริ่มทำงานครั้งแรก เพื่อให้สิทธิ์ความเป็นเจ้าของเป็นของผู้ใช้ของคุณแทนที่จะเป็น root:
mkdir -p ~/arr/config/prowlarr ~/arr/config/sonarr ~/arr/config/radarr ~/arr/config/qbittorrent
docker compose up -d
docker compose psบริการทั้งสี่ควรใช้ running ณ เดือนกรกฎาคม 2026 อิมเมจเหล่านี้ถูกเผยแพร่บน lscr.io และแท็ก latest จะติดตามเวอร์ชันเสถียรปัจจุบัน ดังนั้นหากคุณต้องการตัดสินใจเรื่องการอัปเกรดด้วยตนเองแทนที่จะให้ระบบอัปเดตโดยไม่คาดคิด ให้ระบุเวอร์ชันของแท็กไว้แทน
เข้าถึงเว็บอินเทอร์เฟซอย่างปลอดภัย
เนื่องจากพอร์ตทั้งหมดทำงานอยู่บน loopback จึงยังไม่มีบริการใดถูกเปิดเผยสู่สาธารณะ ให้ทำการ forward พอร์ตเหล่านั้นผ่าน SSH จากเครื่องของคุณเอง:
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ตอนนี้ http://127.0.0.1:8989 ในเบราว์เซอร์ของคุณจะสามารถเข้าถึง Sonarr บนเซิร์ฟเวอร์ได้ หากต้องการการเข้าถึงแบบถาวร ให้ติดตั้ง stack นี้ไว้หลัง Traefik พร้อมใบรับรอง TLS สำหรับหลายแอปพลิเคชัน หรือเข้าถึงเซิร์ฟเวอร์ผ่าน WireGuard VPN ที่คุณโฮสต์เอง แอปพลิเคชันเหล่านี้ไม่ควรถูกวางไว้บนอินเทอร์เน็ตสาธารณะโดยมีเพียงหน้าล็อกอินของตัวแอปเองเท่านั้น หากคุณเลือกใช้ reverse proxy และต้องการใช้บัญชีเดียวสำหรับทั้ง 4 อินเทอร์เฟซแทนการจำรหัสผ่านแยกกัน Authentik ช่วยให้คุณทำระบบ single sign-on แบบ self-hosted ซึ่ง Traefik สามารถบังคับใช้กับทุกคำขอผ่าน forward auth ได้
qBittorrent จะสร้างรหัสผ่านผู้ดูแลระบบแบบสุ่มในการเริ่มทำงานครั้งแรกและแสดงผลใน log ของคอนเทนเนอร์ ให้คุณอ่านรหัสผ่านนั้นแล้วเปลี่ยนในเว็บอินเทอร์เฟซ:
docker compose logs qbittorrent | grep -i passwordหากคุณข้ามขั้นตอนการเปลี่ยนรหัสผ่าน ระบบจะสร้างรหัสผ่านสุ่มใหม่ทุกครั้งที่รีสตาร์ท และคุณจะต้องกลับไปดูที่ log อีกครั้งในทุกๆ รอบ
กำหนด path ภายในแต่ละแอปพลิเคชัน
ใน qBittorrent ให้เปิด Options จากนั้นไปที่ Downloads แล้วกำหนด default save path เป็น /data/torrents ให้เก็บโฟลเดอร์ incomplete-downloads ไว้ในโครงสร้างเดียวกัน เช่น /data/torrents/incomplete การดาวน์โหลดที่เสร็จสิ้นภายนอก /data จะไม่สามารถทำ hardlink เข้าสู่คลังข้อมูลได้
ใน Sonarr ให้เปิด Settings จากนั้นไปที่ Media Management แล้วเพิ่ม root folder เป็น /data/media/Shows สำหรับ Radarr ให้ใช้ root folder เป็น /data/media/Movies ค่าเหล่านี้คือ path ภายใน container ส่วน host path /mnt/data/media/Shows จะถูกปฏิเสธ เนื่องจากไดเรกทอรีดังกล่าวไม่มีอยู่จริงในมุมมองของ container
ทั้งใน Sonarr และ Radarr ให้เปิด Settings จากนั้นไปที่ Download Clients แล้วเพิ่ม qBittorrent โดยระบุ host เป็น qbittorrent และ port เป็น 8080 ชื่อบริการสามารถใช้เป็น hostname ได้เนื่องจาก Compose นำ container ทั้ง 4 ตัวมาไว้บนเครือข่ายเดียวกันพร้อมบริการ DNS (domain name system) ภายใน ห้ามใช้ localhost ในจุดนี้ เพราะภายใน container ของ Sonarr นั้น localhost คือตัว Sonarr เอง
ให้ปล่อยช่อง Remote Path Mappings ว่างไว้ ฟีเจอร์นี้มีไว้เพื่อแปลง path ที่ download client รายงานให้เป็น path ที่แอปพลิเคชันตระกูล arr มองเห็นได้ เมื่อมีการ mount /data ร่วมกัน ทั้งสอง container จะใช้ path เดียวกันโดยสมบูรณ์ ซึ่งเป็นเหตุผลข้อที่สองที่ทำให้การจัดโครงสร้างแบบนี้คุ้มค่าต่อการดำเนินการ
การเชื่อมต่อ Prowlarr เข้ากับ Sonarr และ Radarr
Prowlarr จะส่งคำจำกัดความของ indexer ไปยังแอปพลิเคชันอื่น ทำให้คุณกำหนดค่า indexer เพียงครั้งเดียวแทนที่จะต้องทำซ้ำสองรอบ โดยจำเป็นต้องใช้ API (application programming interface) key จากแต่ละแอปพลิเคชัน
ใน Sonarr ให้เปิด Settings แล้วไปที่ General จากนั้นคัดลอก API key ใน Prowlarr ให้เปิด Settings แล้วไปที่ Apps เพิ่มแอปพลิเคชัน Sonarr และกรอกข้อมูลในสามช่อง Prowlarr Server คือ http://prowlarr:9696 ส่วน Sonarr Server คือ http://sonarr:8989 และ API Key คือค่าที่คุณคัดลอกมา กดปุ่ม Test หากผลลัพธ์เป็นสีเขียว แสดงว่า Prowlarr สามารถติดต่อ Sonarr ผ่านเครือข่าย Compose ได้สำเร็จ ให้ทำซ้ำขั้นตอนเดิมกับ Radarr ที่ http://radarr:7878
หากผลลัพธ์เป็นสีแดงและแจ้งว่าการเชื่อมต่อถูกปฏิเสธ (connection refused) มักหมายถึงการระบุชื่อ service ผิดพลาด หรือขาด prefix http:// ให้ตรวจสอบว่าชื่อดังกล่าวสามารถ resolve ได้จากภายใน container:
docker compose exec prowlarr curl -sS -o /dev/null -w '%{http_code}\n' http://sonarr:8989รหัสสถานะ HTTP เป็นเครื่องยืนยันว่าเส้นทางเครือข่ายใช้งานได้ปกติ หากเกิดข้อผิดพลาดในการระบุชื่อ (name resolution error) แสดงว่าชื่อ service ที่ระบุนั้นไม่ถูกต้อง
พิสูจน์ว่ามีการทำ hardlink เกิดขึ้นจริง
อย่าเพิ่งเชื่อมั่นในการตั้งค่าจนกว่าคุณจะได้เห็นจำนวน link หลังจากนำเข้าไฟล์รายการแรกแล้ว ให้เปรียบเทียบไฟล์ที่ดาวน์โหลดมากับไฟล์ในคลังข้อมูล:
stat -c '%i %h %n' /mnt/data/torrents/tv/*/*.mkv
stat -c '%i %h %n' /mnt/data/media/Shows/*/*/*.mkvตัวเลขแรกคือ inode และตัวเลขที่สองคือจำนวน link ไฟล์ที่ถูกทำ hardlink จะแสดง inode เดียวกันในทั้งสองตำแหน่งและมีจำนวน link เป็น 2 หากพบ inode สองค่าที่ต่างกัน โดยแต่ละค่ามีจำนวน link เป็น 1 แสดงว่า Sonarr ทำการคัดลอกไฟล์แทน และใน log การนำเข้าจะระบุว่าการทำ hardlink ล้มเหลว
ให้สังเกตการใช้งานดิสก์ด้วยเช่นกัน ค่า df -h /mnt/data ควรจะเปลี่ยนแปลงเพียงเล็กน้อยเมื่อมีการนำเข้าไฟล์ เพราะการทำ hardlink เป็นเพียงการเพิ่มชื่อไฟล์โดยไม่มีการคัดลอกข้อมูลจริง
สิ่งที่ทำให้เกิดปัญหาจริง
ข้อผิดพลาดเรื่องสิทธิ์ในการนำเข้าข้อมูล (permission errors) หมายความว่า user id ของคอนเทนเนอร์ไม่สามารถเขียนข้อมูลลงในโฟลเดอร์ library ได้ ข้อความที่ปรากฏคือ Access to the path ... is denied ให้ตรวจสอบด้วย ls -ln /mnt/data/media ว่า owner id ตรงกับ PUID ของคุณหรือไม่ และโปรดจำไว้ว่าไดเรกทอรีจำเป็นต้องมี execute bit ก่อนที่คอนเทนเนอร์จะสามารถเข้าถึงได้
ไฟล์ที่แสดงว่ามีเจ้าของเป็น root หมายความว่าคอนเทนเนอร์เริ่มทำงานก่อนที่ไดเรกทอรีบนโฮสต์จะถูกสร้างขึ้น Docker จึงสร้างไดเรกทอรีนั้นขึ้นมาโดยใช้สิทธิ์ root ให้หยุด stack, chown ไดเรกทอรีนั้นทิ้ง แล้วเริ่มการทำงานใหม่อีกครั้ง
การลบ torrent ออกจาก qBittorrent แล้วพบว่าไฟล์ใน library หายไปด้วย หมายความว่าการนำเข้าข้อมูลนั้นเป็นการคัดลอกไฟล์ (copy) ซึ่งถูกลบออกในภายหลัง หรือคุณได้ลบข้อมูลจริงแทนที่จะลบเพียงรายการ torrent หากใช้ hardlink ที่ถูกต้อง การลบชื่อไฟล์หนึ่งออกจะยังคงเหลืออีกชื่อหนึ่งไว้ เนื่องจากข้อมูลจะถูกลบออกจากดิสก์ก็ต่อเมื่อจำนวน link count ลดลงเหลือศูนย์เท่านั้น
การที่พื้นที่ดิสก์เต็มเร็วกว่าขนาดของสื่อที่คุณเพิ่มเข้าไป คือปัญหาจากการคัดลอกไฟล์ในรูปแบบที่สิ้นเปลืองที่สุด ให้รันการตรวจสอบด้วย stat ตามที่ระบุไว้ข้างต้นก่อนที่คุณจะตัดสินใจซื้อพื้นที่จัดเก็บข้อมูลเพิ่ม
สิ่งที่ stack นี้ต้องการจาก VPS
แอปพลิเคชันตระกูล arr ทั้งสามใช้ทรัพยากรน้อย โดยจะ poll indexer เขียนข้อมูลลงฐานข้อมูล SQLite ขนาดเล็ก และเปลี่ยนชื่อไฟล์ เซิร์ฟเวอร์ที่มี RAM 2 GB สามารถรัน container ทั้งสี่ได้อย่างสบาย ภาระหลักมาจากบริการอื่น download client จะใช้ความสามารถในการอ่านและเขียนดิสก์จนเต็มเมื่อจัดการ torrent ขนาดใหญ่ และ media server ที่ทำ transcoding วิดีโอบนเครื่องเดียวกันจะใช้ CPU ควรเก็บสื่อไว้บน volume ที่มี throughput จริงเพียงพอ และกำหนด bandwidth limit ให้ download client หากเซิร์ฟเวอร์ยังต้องทำงานอื่นที่สำคัญ ควรแยกงบทรัพยากรสำหรับงานเหล่านั้น แทนการสมมติว่ายังมีทรัพยากรเหลือเพียงพอ: workspace AFFiNE ที่ self-host คือ container อีกสี่รายการพร้อมฐานข้อมูลเบื้องหลัง และบนเครื่องที่มี RAM 2 GB จะใช้หน่วยความจำส่วนใหญ่ของเครื่อง หากเป็นบริการเสริมที่ทำงานเฉพาะอย่าง ค่าใช้ทรัพยากรอาจไม่สูงเท่ากัน: ตัวติดตามการออกกำลังกาย openGym ที่ self-host สามารถใช้งานร่วมกับเครื่องนี้ได้โดยไม่มีปัญหา ตราบใดที่กำหนด TLS ของบริการแยกเป็นของตนเอง และทราบว่าไฟล์ฐานข้อมูลอยู่ที่ใดก่อนมอบประวัติการฝึกตลอด 1 ปีให้บริการนี้ดูแล บริการใดก็ตามที่มี web application, ฐานข้อมูล Postgres และ background worker queue จะอยู่ใกล้ช่วงการใช้ทรัพยากรของ AFFiNE มากกว่า ดังนั้นควรตัดสินใจก่อนว่า ระบบรับแจ้งปัญหา Chatwoot ที่ self-host ควรอยู่บนเซิร์ฟเวอร์นี้หรือใช้เครื่องแยก ก่อนจะพบข้อจำกัดระหว่างการ import งานที่ใช้ทรัพยากรเป็นช่วง ๆ ต้องระมัดระวังยิ่งขึ้น เพราะสิ่งที่ชนกับการ import คือการใช้ทรัพยากรช่วงสูงสุด ไม่ใช่ค่าเฉลี่ย: หากกำลังพิจารณา การ self-host OneCLI ที่จัดเตรียม agent แบบแยก sandbox ให้แต่ละคน ให้ตรวจสอบตัวเลข sizing ที่เผยแพร่ไว้เทียบกับทรัพยากรที่ว่างจริงขณะ qBittorrent ทำงานเต็มกำลัง ไม่ใช่เทียบกับค่าที่ free -h แสดงบนเครื่องที่ไม่มีภาระงาน
FAQ
ทำไม Sonarr ถึงคัดลอกไฟล์แทนที่จะทำ hardlink?
เพราะต้นทางและปลายทางอยู่บนระบบไฟล์ที่ต่างกันในมุมมองของคอนเทนเนอร์ การทำ bind mount แยกกันสองจุด เช่น /downloads และ /tv จะถูกมองว่าเป็นคนละระบบไฟล์กัน แม้ว่าทั้งคู่จะมาจากดิสก์ลูกเดียวกันบนโฮสต์ก็ตาม ให้ mount ไดเรกทอรีหลักเพียงจุดเดียวเป็น /data ในทุกคอนเทนเนอร์ แล้ววางโฟลเดอร์ดาวน์โหลดและคลังไฟล์ไว้ข้างในนั้น การทำ link จึงจะสามารถทำได้ ตรวจสอบผลลัพธ์ด้วยคำสั่ง stat -c '%i %h %n' บนไฟล์ทั้งสอง: หากสำเร็จจะได้ inode เดียวกันและมี link count เป็น 2
ควรใช้ PUID และ PGID ค่าใด?
ให้ใช้เลข ID ของบัญชีผู้ใช้บนโฮสต์ที่เป็นเจ้าของโครงสร้างไฟล์สื่อ ซึ่งคุณสามารถตรวจสอบได้จาก id -u และ id -g สำหรับ Ubuntu VPS ที่ติดตั้งใหม่ ค่านี้มักจะเป็น 1000 สำหรับทั้งสองค่า คอนเทนเนอร์ทุกตัวใน stack ต้องใช้คู่ค่าเดียวกัน มิฉะนั้นแอปพลิเคชันหนึ่งจะเขียนไฟล์ที่อีกแอปพลิเคชันไม่สามารถแก้ไขได้ หลังจากเปลี่ยนค่าแล้ว ให้สร้างคอนเทนเนอร์ใหม่ด้วย docker compose up -d --force-recreate และแก้ไขสิทธิ์ของไฟล์ที่มีอยู่เดิมด้วย chown -R
จำเป็นต้องเปิดเผยเว็บอินเทอร์เฟซเหล่านี้สู่สาธารณะหรือไม่?
ไม่จำเป็น และไม่ควรทำ ให้ bind พอร์ตที่เปิดใช้งานแต่ละพอร์ตเข้ากับ 127.0.0.1 ในไฟล์ Compose จากนั้นจึงเข้าถึงอินเทอร์เฟซผ่าน SSH tunnel, VPN หรือ reverse proxy ที่ทำ TLS (transport layer security) termination และเพิ่มการยืนยันตัวตนของตัวเอง การเปิดพอร์ตโดยตรงนั้นอันตรายกว่าที่คิด เพราะ Docker จะแทรกกฎ firewall ของตัวเองเข้าไป ทำให้กฎ ufw deny ไม่สามารถหยุดทราฟฟิกนั้นได้
จะหารหัสผ่านของ qBittorrent ได้ที่ไหน?
อิมเมจของ LinuxServer.io จะแสดงรหัสผ่านชั่วคราวสำหรับผู้ใช้ admin ไว้ใน log ตอนเริ่มทำงาน ให้รัน docker compose logs qbittorrent | grep -i password เพื่ออ่านรหัสผ่านดังกล่าว จากนั้นจึงตั้งรหัสผ่านถาวรในเมนู Options และ Web UI ระบบจะสร้างรหัสผ่านชั่วคราวใหม่ทุกครั้งที่รีสตาร์ทจนกว่าคุณจะตั้งรหัสผ่านของคุณเอง
Jellyfin สามารถใช้โฟลเดอร์เดียวกันได้หรือไม่?
ได้ และนั่นคือจุดประสงค์ของโครงสร้างนี้ ให้ mount /mnt/data/media เข้าไปยังเซิร์ฟเวอร์สื่อของคุณในฐานะ /media ซึ่งคลังไฟล์จะอยู่ที่ /media/Movies และ /media/Shows ในขณะที่ Sonarr และ Radarr จะเขียนไฟล์ลงในไดเรกทอรีเดียวกันผ่าน /data/media กำหนดให้เซิร์ฟเวอร์สื่อใช้ PUID และ PGID เดียวกัน เพื่อให้สามารถอ่านไฟล์ที่ stack ของ arr เขียนไว้ได้