SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-28

วิธีแก้ปัญหา duplicate apt sources บน Ubuntu และ Debian

พบข้อผิดพลาด Target is configured multiple times ใช่หรือไม่ เรียนรู้วิธีตรวจสอบไฟล์ .list และ .sources แบบ deb822 เพื่อลบรายการซ้ำให้ apt update กลับมาทำงานได้ตามปกติ

ความหมายของข้อผิดพลาด duplicate apt sources

ข้อผิดพลาด duplicate apt sources หมายความว่ามีการประกาศ repository ซ้ำกันในไฟล์สองไฟล์ที่ต่างกัน และ APT (advanced package tool) ได้ตรวจพบทั้งสองรายการ บน Ubuntu 24.04 และเวอร์ชันที่ใหม่กว่า ปัญหานี้มักเกิดขึ้นเพราะสคริปต์ติดตั้งของบุคคลที่สามเขียนไฟล์ .list แบบบรรทัดเดียวแบบเก่าลงไป ในขณะที่มีไฟล์ .sources แบบ deb822 สำหรับ repository เดียวกันนั้นอยู่บนดิสก์แล้ว ระบบไม่ได้เสียหายและไม่มีแพ็กเกจใดตกอยู่ในความเสี่ยง ให้ลบการประกาศรายการใดรายการหนึ่งออก แล้วข้อความแจ้งเตือนจะหายไป

นี่คือบรรทัดที่ผู้คนมักคัดลอกไปวางในช่องค้นหา:

W: Target Packages (stable/binary-amd64/Packages) is configured multiple times in /etc/apt/sources.list.d/docker.list:1 and /etc/apt/sources.list.d/docker.sources:1

ให้อ่านจากส่วนท้ายของข้อความ จะพบไฟล์สองไฟล์ที่ระบุเลขบรรทัดไว้ ซึ่งประกาศสิ่งเดียวกัน Target Packages คือดัชนีที่ apt ดาวน์โหลดมาเพื่อเรียนรู้ว่า repository นั้นมีแพ็กเกจอะไรบ้าง และ stable/binary-amd64/Packages คือชื่อของ component (stable) และสถาปัตยกรรม (amd64) ที่ดัชนีนั้นครอบคลุม ดังนั้น apt กำลังแจ้งให้คุณทราบว่าดัชนี amd64 สำหรับ component stable ถูกกำหนดค่าไว้ใน docker.list ที่บรรทัด 1 และถูกกำหนดไว้อีกครั้งใน docker.sources ที่บรรทัด 1

บน apt 3.0 และเวอร์ชันที่ใหม่กว่า ซึ่งหมายถึง Ubuntu 25.04 ขึ้นไป และ Debian 13 ข้อความเดียวกันจะขึ้นต้นด้วย Warning: แทนที่จะเป็น W: โดยข้อความหลังจากส่วนนำหน้าจะเหมือนเดิม

คำเตือนนั้นเป็นกรณีที่ไม่รุนแรง apt จะรวมการประกาศทั้งสองเข้าด้วยกันและยังคงรันการอัปเดตได้ตามปกติ เพราะทั้งสองรายการอธิบายถึง archive เดียวกันด้วยคีย์เดียวกัน แต่กรณีที่รุนแรงจะทำให้ทุกอย่างหยุดทำงาน:

E: Conflicting values set for option Signed-By regarding source https://download.docker.com/linux/ubuntu/ noble: /usr/share/keyrings/docker-archive-keyring.gpg != /etc/apt/keyrings/docker.asc
E: The list of sources could not be read.

apt ปฏิเสธการทำงานในกรณีนี้เพราะการประกาศทั้งสองรายการระบุ signing key ที่ต่างกันสำหรับ archive เดียวกัน apt จะรวมการประกาศที่เหมือนกันเข้าด้วยกันได้ แต่จะไม่เลือกค่า Signed-By ให้เอง เพราะการเลือกค่าที่ผิดหมายถึงการตรวจสอบลายเซ็นแพ็กเกจด้วยคีย์ที่เจ้าของ archive ไม่ได้ใช้ลงนาม ดังนั้น apt จึงไม่อ่านแหล่งที่มาใดๆ เลย ทั้ง apt update และ apt install จะล้มเหลวด้วยข้อความสองบรรทัดเดียวกันนั้น จนกว่าคุณจะแก้ไขไฟล์ด้วยตนเอง

สาเหตุที่เกิดรายการซ้ำ

รูปแบบทั้งสองอยู่ในไฟล์แยกกันโดยมีนามสกุลต่างกัน ดังนั้นจึงไม่มีสิ่งใดในดิสก์ที่ขัดขวางไม่ให้ทั้งสองไฟล์มีอยู่พร้อมกัน apt จะตรวจพบความซ้ำซ้อนนี้ในภายหลัง เมื่อมันขยายไฟล์ source แต่ละไฟล์ออกเป็นรายการเป้าหมายของ index ที่วางแผนจะดึงข้อมูล จนกว่าจะถึงเวลานั้น docker.list และ docker.sources ก็เป็นเพียงไฟล์สองไฟล์ที่ไม่เกี่ยวข้องกัน

เหตุการณ์ปกติ 4 ประการที่ทำให้เกิดคู่ไฟล์นี้:

  • สคริปต์ติดตั้งของผู้จำหน่าย หรือคำสั่งที่คัดลอกมาจากโพสต์เก่า เขียนไฟล์ /etc/apt/sources.list.d/vendor.list ด้วยบรรทัด tee
  • แพ็กเกจของผู้จำหน่ายเองในภายหลังได้ปล่อย /etc/apt/sources.list.d/vendor.sources ออกมาและติดตั้งให้คุณ
  • add-apt-repository บน Ubuntu 24.04 และเวอร์ชันใหม่กว่า จะเขียนไฟล์ deb822 .sources ดังนั้น PPA (personal package archive) ที่คุณเคยเพิ่มด้วยตนเองในรูปแบบ .list จึงกลับมาในรูปแบบ .sources
  • การอัปเกรดรุ่นของระบบปฏิบัติการเขียนไฟล์ source ของตัว distribution เองใหม่เป็นรูปแบบ deb822 และทิ้งไฟล์ .list ที่คุณเขียนไว้ด้วยตนเองไว้ข้างๆ โดยไม่มีการเปลี่ยนแปลง

แต่ละเส้นทางมีความสมเหตุสมผลในตัวเอง รายการซ้ำคือสิ่งที่คุณได้รับเมื่อเหตุการณ์เหล่านี้สองอย่างเกิดขึ้นบนเครื่องเดียวกัน ซึ่งมักจะห่างกันหลายเดือน

เปรียบเทียบสองรูปแบบเคียงข้างกัน

รูปแบบเก่าคือหนึ่งบรรทัดต่อหนึ่งที่เก็บแพ็กเกจ (repository) โดยทุกส่วนของบรรทัดจะขึ้นอยู่กับตำแหน่งที่วาง

deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable

ลำดับของข้อมูลถูกกำหนดไว้ตายตัว: เริ่มจากประเภท (deb สำหรับแพ็กเกจไบนารี, deb-src สำหรับแพ็กเกจซอร์สโค้ด) ตามด้วยตัวเลือกในวงเล็บก้ามปู, URI (Uniform Resource Identifier) ของคลังเก็บ, ชุดแพ็กเกจ (suite) และส่วนประกอบ (components) อย่างน้อยหนึ่งรายการ เนื่องจากความหมายขึ้นอยู่กับตำแหน่ง การเว้นวรรคที่ผิดพลาดจะทำให้ apt อ่านค่าเปลี่ยนไป

deb822 ระบุข้อมูลชุดเดียวกันในรูปแบบของกลุ่มฟิลด์ที่มีชื่อเรียก ชื่อนี้มาจาก RFC 822 ซึ่งเป็นรูปแบบส่วนหัวของอีเมลที่ Debian ใช้งานอยู่แล้วในไฟล์ควบคุมแพ็กเกจ

Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.asc

ที่เก็บแพ็กเกจเดียวกัน กุญแจเดียวกัน ไม่มีการเพิ่มข้อมูลใดๆ การจับคู่เป็นไปโดยตรง: deb กลายเป็น Types, ที่อยู่คลังเก็บกลายเป็น URIs, ชุดแพ็กเกจกลายเป็น Suites, ส่วนประกอบกลายเป็น Components และตัวเลือกในวงเล็บแต่ละรายการจะกลายเป็นฟิลด์ของตัวเอง ดังนั้น signed-by= จึงกลายเป็น Signed-By: และ arch= กลายเป็น Architectures:

ชื่อฟิลด์ทุกชื่ออยู่ในรูปพหูพจน์เนื่องจากทุกฟิลด์รองรับรายการที่คั่นด้วยช่องว่าง Suites: noble noble-updates noble-backports ในกลุ่มเดียวสามารถแทนที่บรรทัด deb แยกกันสามบรรทัดได้ บรรทัดว่างจะเป็นตัวกำหนดจุดสิ้นสุดของกลุ่ม ดังนั้นไฟล์ .sources ไฟล์เดียวจึงสามารถเก็บที่เก็บแพ็กเกจได้หลายแห่ง นอกจากนี้ deb822 ยังรองรับการตั้งค่าที่รูปแบบบรรทัดเดียวจัดการได้ยาก เช่น Enabled: no เพื่อปิดการใช้งานที่เก็บแพ็กเกจ, Trusted, Check-Valid-Until และกุญแจแบบ inline ที่วางลงใน Signed-By โดยตรง โดยทุกบรรทัดต้องย่อหน้าหนึ่งช่องว่างและบรรทัดว่างจะเขียนแทนด้วยจุดหนึ่งจุด

ตำแหน่งที่ตั้งของไฟล์แต่ละประเภท

  • /etc/apt/sources.list: ไฟล์เดี่ยวแบบดั้งเดิม บน Ubuntu 24.04 และเวอร์ชันใหม่กว่า ไฟล์นี้มักจะว่างเปล่าหรือมีเพียงข้อความหมายเหตุที่ชี้ไปยังตำแหน่งใหม่เท่านั้น
  • /etc/apt/sources.list.d/*.list: รายการแบบบรรทัดเดียว โดยปกติจะเป็นหนึ่งไฟล์ต่อหนึ่ง repository
  • /etc/apt/sources.list.d/*.sources: รูปแบบ stanzas แบบ deb822 บน Ubuntu 24.04 และเวอร์ชันใหม่กว่าจะเก็บ repository ของตัว distribution เองไว้ที่นี่ ใน ubuntu.sources
  • /etc/apt/keyrings/: ตำแหน่งสำหรับเก็บคีย์ที่คุณเพิ่มเข้าไปเอง ส่วน /usr/share/keyrings/ จะเก็บคีย์ที่มาพร้อมกับแพ็กเกจ

apt จะอ่านเฉพาะไฟล์ที่ลงท้ายด้วย .list หรือ .sources เท่านั้น และชื่อไฟล์สามารถประกอบด้วยตัวอักษร ตัวเลข ขีดล่าง ขีดกลาง และจุด ไฟล์ที่มีนามสกุลอื่นจะถูกข้ามไปพร้อมกับแสดงข้อความแจ้งเตือน ซึ่งเป็นประเด็นสำคัญสำหรับการแก้ไขปัญหาที่ระบุไว้ด้านล่าง

ค้นหาคู่ไฟล์ที่ซ้ำกัน

เริ่มต้นด้วยการแสดงรายการไฟล์ในไดเรกทอรี:

ls -l /etc/apt/sources.list.d/
-rw-r--r-- 1 root root  195 Aug  3 09:12 docker.list
-rw-r--r-- 1 root root  254 Aug  9 14:40 docker.sources
-rw-r--r-- 1 root root 2683 Jun 11 08:02 ubuntu.sources

ไฟล์สองไฟล์ที่มีชื่อต้นเหมือนกันแต่มีนามสกุลต่างกันมักจะเป็นคู่ที่ซ้ำกัน แต่อย่าเพิ่งเชื่อชื่อไฟล์เหล่านั้น ให้ตรวจสอบเนื้อหาภายใน เพราะไฟล์ที่ซ้ำกันอาจซ่อนอยู่ในไฟล์ที่ตั้งชื่ออย่างไรก็ได้:

grep -rn -E '^(deb |deb-src |Types:|URIs:|Suites:|Signed-By:)' /etc/apt/sources.list /etc/apt/sources.list.d/
/etc/apt/sources.list.d/docker.list:1:deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu noble stable
/etc/apt/sources.list.d/docker.sources:1:Types: deb
/etc/apt/sources.list.d/docker.sources:2:URIs: https://download.docker.com/linux/ubuntu
/etc/apt/sources.list.d/docker.sources:3:Suites: noble
/etc/apt/sources.list.d/docker.sources:6:Signed-By: /etc/apt/keyrings/docker.asc

คู่ที่ซ้ำกันคือรายการสองรายการที่มี host เดียวกันและ suite เดียวกัน ทั้งสองชี้ไปที่ https://download.docker.com/linux/ubuntu และ suite noble ดังนั้นจึงเป็น repository เดียวกันที่ถูกเขียนซ้ำสองครั้ง นอกจากนี้ path ของ Signed-By ยังไม่ตรงกัน ซึ่งเป็นสาเหตุที่ทำให้เกิดข้อผิดพลาด Conflicting values ที่แสดงไว้ก่อนหน้านี้

ให้ใช้ grep แทนคำสั่ง apt สำหรับขั้นตอนนี้ เนื่องจากเมื่อ apt หยุดทำงานเพราะเกิดข้อขัดแย้ง มันจะไม่สามารถแสดงรายการ source ของคุณได้เช่นกัน ดังนั้น apt-cache policy จึงแสดงข้อผิดพลาดเดิมออกมาแทนที่จะเป็นคำตอบที่คุณต้องการ

แก้ไขปัญหา: เก็บไฟล์ deb822 ไว้และลบไฟล์รูปแบบเดิมออก

ให้เก็บไฟล์ .sources ไว้ เนื่องจากเป็นรูปแบบที่เครื่องมือ apt ใช้งานในปัจจุบัน และเป็นทิศทางที่ทั้ง Debian และ Ubuntu กำลังมุ่งไป ก่อนที่จะลบไฟล์ใดๆ ให้ตรวจสอบว่าเส้นทางของคีย์ใดในสองเส้นทางนี้มีอยู่จริงบนดิสก์:

ls -l /etc/apt/keyrings/ /usr/share/keyrings/ | grep -i docker
-rw-r--r-- 1 root root 4813 Aug  9 14:40 docker.asc

มีเพียง /etc/apt/keyrings/docker.asc เท่านั้นที่มีอยู่จริง ดังนั้นไฟล์ deb822 จึงเป็นไฟล์ที่ถูกต้อง และไฟล์ .list กำลังชี้ไปยังคีย์ที่ถูกลบออกไปแล้ว หากปรากฏว่าไฟล์ที่คุณต้องการเก็บไว้ระบุถึงคีย์ที่หายไป ให้คัดลอกเส้นทางที่ใช้งานได้ลงไปในไฟล์นั้นก่อน จากนั้นจึงลบอีกไฟล์หนึ่งทิ้ง

ให้ย้ายไฟล์รูปแบบเดิมออกจากไดเรกทอรีแทนการลบทิ้งทันที:

sudo mkdir -p /root/apt-sources-backup
sudo mv /etc/apt/sources.list.d/docker.list /root/apt-sources-backup/
sudo apt update

การเปลี่ยนชื่อไฟล์เป็น docker.list.bak และวางไว้ที่เดิมก็สามารถทำได้เช่นกัน เพราะ apt จะเพิกเฉยต่อส่วนขยายที่ไม่รู้จัก แต่การทำเช่นนั้นจะทำให้ทุกครั้งที่รัน apt จะแสดงข้อความนี้:

N: Ignoring file 'docker.list.bak' in directory '/etc/apt/sources.list.d/' as it has an invalid filename extension

การย้ายไฟล์ไปไว้ที่อื่นจะช่วยให้ข้อความแจ้งเตือนดังกล่าวไม่ปรากฏบนหน้าจอของคุณ และยังคงเก็บไฟล์สำรองไว้ได้ ไฟล์ apt update ที่สมบูรณ์หลังจากดำเนินการแล้วจะมีลักษณะดังนี้ โดยไม่มีบรรทัดที่ระบุชื่อไฟล์สองไฟล์:

Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Get:2 https://download.docker.com/linux/ubuntu noble InRelease [48.8 kB]
Get:3 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]
Fetched 175 kB in 1s (146 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

จากนั้นตรวจสอบให้แน่ใจว่า repository ยังคงใช้งานได้หลังจากการแก้ไข:

apt-cache policy | grep download.docker.com
 500 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
     origin download.docker.com

หากเอกสารของผู้ให้บริการยังคงอ้างอิงถึงไฟล์แบบบรรทัดเดียว คุณสามารถเก็บไฟล์นั้นไว้และลบไฟล์ .sources ออกแทนได้ โดยมีกฎตัดสินเพียงข้อเดียวคือ: ต้องมีไฟล์เพียงไฟล์เดียวเท่านั้นที่ประกาศ archive และ suite นั้นๆ

เหตุผลที่แหล่งซอฟต์แวร์ภายนอกที่เสียหายเพียงแหล่งเดียวทำให้ apt update ทำงานไม่ได้

ความล้มเหลวที่เกิดขึ้นในลักษณะใกล้เคียงกันมีสาเหตุมาจากรากเหง้าเดียวกัน นั่นคือแหล่งซอฟต์แวร์ภายนอกที่ apt ไม่สามารถใช้งานได้ กรณีแรกคือปัญหาคีย์สูญหาย:

Err:5 https://download.docker.com/linux/ubuntu noble InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
E: The repository 'https://download.docker.com/linux/ubuntu noble InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.

ฟิลด์ Signed-By หายไป หรือชี้ไปยังไฟล์ที่ไม่ใช่คีย์ที่ใช้งานได้ ทำให้ apt ไม่สามารถตรวจสอบลายเซ็นบนไฟล์ InRelease ของคลังซอฟต์แวร์ได้ ระบบจึงละทิ้งคลังซอฟต์แวร์นั้นทั้งหมดแทนที่จะเชื่อถือรายการแพ็กเกจที่ไม่สามารถตรวจสอบได้ ให้ตรวจสอบไฟล์คีย์ด้วยตนเอง:

ls -l /etc/apt/keyrings/docker.asc
gpg --show-keys /etc/apt/keyrings/docker.asc

คีย์ที่ใช้งานได้จะแสดงบรรทัด pub พร้อมรหัสคีย์ และบรรทัด uid ที่ระบุชื่อผู้ให้บริการ หากแสดง gpg: no valid OpenPGP data found. หมายความว่าไฟล์นั้นไม่ใช่คีย์ ซึ่งมักเกิดจากการดาวน์โหลดที่ได้หน้าเว็บแจ้งข้อผิดพลาดมาแทนเนื่องจาก URL ของคีย์มีการเปลี่ยนแปลง ให้ดาวน์โหลดคีย์ใหม่อีกครั้ง ตรวจสอบไฟล์ แล้วจึงรัน apt update

กรณีที่สองจะเกิดขึ้นหลังจากการอัปเกรดรุ่นของระบบปฏิบัติการ:

Err:6 https://ppa.launchpadcontent.net/ondrej/php/ubuntu plucky InRelease
  404  Not Found [IP: 10.0.0.80 443]
E: The repository 'https://ppa.launchpadcontent.net/ondrej/php/ubuntu plucky Release' does not have a Release file.

PPA ไม่ได้เผยแพร่ข้อมูลสำหรับชุดซอฟต์แวร์นั้น ทำให้ไม่มี path ดังกล่าวอยู่บนเซิร์ฟเวอร์และคำขอส่งกลับสถานะ 404 คลังซอฟต์แวร์อื่นของคุณยังคงอัปเดตได้ตามปกติและแพ็กเกจที่คุณมีอยู่แล้วจะไม่ได้รับผลกระทบ อย่างไรก็ตาม การทำงานจะสิ้นสุดด้วยสถานะ non-zero ทำให้สคริปต์ใดก็ตามที่ตรวจสอบสถานะการทำงานของ apt update รายงานความล้มเหลวทุกครั้งที่รัน นี่คือเหตุผลว่าทำไมแหล่งซอฟต์แวร์ที่ใช้งานไม่ได้จึงควรถูกลบออกบนเครื่องที่มีการตั้งค่า การอัปเดตความปลอดภัยอัตโนมัติ ไว้ เพราะการแจ้งเตือนที่เกิดขึ้นทุกวันอาจบดบังความล้มเหลวที่แท้จริงได้ สคริปต์ติดตั้งของผู้ให้บริการมักประสบปัญหาทั้งสองรูปแบบนี้ ซึ่งเป็นสาเหตุที่ทำให้ ข้อผิดพลาดในการติดตั้ง Tailscale บน Ubuntu ส่วนใหญ่เกิดจาก keyring ที่สคริปต์ไม่ได้เขียนลงไป หรือชื่อรหัสรุ่น (codename) ที่คลังซอฟต์แวร์ไม่มีให้บริการ

การปิดใช้งานแหล่งข้อมูลหนึ่งรายการโดยไม่กระทบส่วนที่เหลือ

สำหรับไฟล์รูปแบบ deb822 ให้เพิ่มฟิลด์หนึ่งรายการลงใน stanza แล้วบันทึกไฟล์:

Types: deb
URIs: https://ppa.launchpadcontent.net/ondrej/php/ubuntu
Suites: plucky
Components: main
Signed-By: /etc/apt/keyrings/ondrej-php.asc
Enabled: no

คู่มือของ apt แนะนำวิธีนี้มากกว่าการใส่เครื่องหมายคอมเมนต์หน้าแต่ละบรรทัดใน stanza และยังสามารถยกเลิกการตั้งค่าได้ง่ายกว่า สำหรับไฟล์แบบบรรทัดเดียว ให้ใส่ # ไว้ที่ต้นบรรทัด สำหรับทั้งสองรูปแบบ การย้ายไฟล์ออกจาก /etc/apt/sources.list.d/ ก็สามารถทำได้เช่นกัน และเป็นตัวเลือกที่ควรใช้เมื่อต้องการลบ repository นั้นออกอย่างถาวร

เรียกใช้ sudo apt update อีกครั้ง บล็อก Err: สำหรับ repository นั้นจะหายไป และสถานะการทำงานจะส่งค่ากลับเป็น 0 ซึ่งคุณสามารถตรวจสอบได้ด้วย echo $? ในบรรทัดถัดไป

ห้ามแก้ไขแหล่งข้อมูลที่เสียหายด้วย sudo rm /etc/apt/sources.list.d/* โดยเด็ดขาด บน Ubuntu 24.04 และเวอร์ชันที่ใหม่กว่า คำสั่งนี้จะลบ ubuntu.sources ซึ่งเป็นที่เก็บ repository หลักของ distribution ส่งผลให้ apt ไม่มีรายการแพ็กเกจเหลืออยู่เลย และจะรายงานข้อผิดพลาด E: Unable to locate package curl สำหรับซอฟต์แวร์ที่มีอยู่จริง หากคุณได้เรียกใช้คำสั่งดังกล่าวไปแล้ว ให้เขียนไฟล์กลับคืนดังนี้:

Types: deb
URIs: http://archive.ubuntu.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

Types: deb
URIs: http://security.ubuntu.com/ubuntu/
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

บันทึกไฟล์นั้นเป็น /etc/apt/sources.list.d/ubuntu.sources โดยแทนที่ noble ด้วยชื่อ release ของคุณจาก lsb_release -cs จากนั้นเรียกใช้ sudo apt update

การแปลงไฟล์ .list แบบเดิมเป็นรูปแบบ deb822

ตั้งแต่เดือนสิงหาคม 2026 เป็นต้นไป apt เวอร์ชัน 3.0 และใหม่กว่าได้รวมเครื่องมือแปลงไฟล์นี้มาให้ด้วย โดยมีอยู่ใน Debian 13, Ubuntu 25.04 และทุกรุ่นที่ออกหลังจากนั้น รวมถึง 26.04 ให้ตรวจสอบเวอร์ชันก่อนแล้วจึงรันคำสั่ง:

apt --version
sudo apt modernize-sources

คำสั่งนี้จะเขียนไฟล์บรรทัดเดียวที่อยู่ใน /etc/apt/sources.list.d/ ใหม่ให้เป็นไฟล์ deb822 ใน .sources ให้ตรวจสอบข้อความที่แสดงผล จากนั้นให้แสดงรายการไฟล์ในไดเรกทอรีด้วยตนเองและรัน apt update ก่อนที่จะเชื่อถือผลลัพธ์ สำหรับ Ubuntu 24.04 นั้นใช้ apt เวอร์ชันเก่าซึ่งไม่มีคำสั่งย่อยนี้ และคำสั่งจะตอบกลับมาว่า E: Invalid operation modernize-sources ในรุ่นดังกล่าว ให้ทำการแปลงด้วยตนเองโดยใช้การจับคู่ฟิลด์ตามที่ระบุไว้ข้างต้น

การแปลงไฟล์เป็นทางเลือกในปัจจุบัน เนื่องจาก apt ยังคงอ่านได้ทั้งสองรูปแบบ แต่การดำเนินการนี้คุ้มค่าสำหรับเซิร์ฟเวอร์ที่คุณวางแผนจะใช้งานในระยะยาว เนื่องจากเครื่องมือทุกตัวที่เขียนไฟล์แหล่งที่มาในปัจจุบันจะเขียนเป็นรูปแบบ deb822 ทั้งหมด และเครื่องที่มีเฉพาะไฟล์ .sources จะไม่เกิดปัญหาไฟล์ซ้ำซ้อนในลักษณะนี้อีก

การจัดการแหล่งซอฟต์แวร์ภายนอกบนเซิร์ฟเวอร์ให้เป็นระเบียบ

Repository จากภายนอกเป็นส่วนของเซิร์ฟเวอร์ที่เสื่อมสภาพเร็วที่สุด แต่ละแหล่งคือคำสัญญาจากบุคคลอื่นว่าจะคอยอัปเดตซอฟต์แวร์ให้ Ubuntu release ของคุณ ซึ่งการอัปเกรดเวอร์ชันของระบบปฏิบัติการจะเป็นการทดสอบคำสัญญาเหล่านั้นทั้งหมดในคราวเดียว

  • เพิ่ม repository ภายนอกเฉพาะเมื่อแพ็กเกจมาตรฐานของ distribution ไม่สามารถใช้งานได้เท่านั้น การติดตั้ง LAMP stack บน Ubuntu 24.04 แบบปกติไม่จำเป็นต้องใช้ repository ภายนอกเลย เนื่องจาก Ubuntu archive มีแพ็กเกจที่จำเป็นครบถ้วนพร้อมการอัปเดตความปลอดภัยตลอดอายุการใช้งานของ release นั้นๆ
  • เก็บไฟล์กุญแจไว้ใน /etc/apt/keyrings/ โดยแยกไฟล์ตามผู้ให้บริการแต่ละรายและตั้งค่า permission เป็น 644 ผู้ใช้ _apt ซึ่งไม่มีสิทธิ์ระดับสูงเป็นผู้ทำหน้าที่ดาวน์โหลดและจำเป็นต้องอ่านไฟล์กุญแจ ดังนั้นหากตั้งค่าให้เฉพาะ root อ่านได้ จะทำให้เกิดข้อผิดพลาดด้านสิทธิ์ทุกครั้งที่มีการดึงข้อมูลจาก repository นั้น
  • ระบุตำแหน่งไฟล์กุญแจให้ตรงกับไฟล์นั้นๆ ในแต่ละ stanza ของ Signed-By การวางกุญแจไว้ใน /etc/apt/trusted.gpg หรือ /etc/apt/trusted.gpg.d/ จะทำให้กุญแจนั้นได้รับความเชื่อถือสำหรับทุก repository ในเครื่อง ซึ่งหมายความว่ากุญแจของผู้ให้บริการที่เพิ่มไว้เมื่อหลายปีก่อนอาจถูกนำไปใช้ตรวจสอบความถูกต้องของแพ็กเกจจากที่ใดก็ได้
  • ก่อนการอัปเกรด release ให้ตรวจสอบรายการ sources ของคุณและยืนยันว่าผู้ให้บริการแต่ละรายได้เผยแพร่ซอฟต์แวร์สำหรับ release ปลายทางที่คุณกำลังจะย้ายไปแล้ว

กุญแจที่อยู่ใน keyring ส่วนกลางแบบเก่าจะแสดงคำเตือนทุกครั้งที่มีการอัปเดต:

W: https://download.docker.com/linux/ubuntu/dists/noble/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.

ให้ส่งออก (export) กุญแจนั้นออกมาเป็นไฟล์แยกต่างหาก แล้วระบุตำแหน่งไฟล์ใน stanza ของ repository นั้น:

gpg --no-default-keyring --keyring /etc/apt/trusted.gpg --export 7EA0A9C3F273FCD8 | sudo tee /etc/apt/keyrings/docker.gpg > /dev/null
sudo chmod 644 /etc/apt/keyrings/docker.gpg

เพิ่ม Signed-By: /etc/apt/keyrings/docker.gpg ลงใน stanza ของ repository นั้นแล้วรันคำสั่ง sudo apt update คำเตือนจะหายไปเมื่อไม่มี repository ใดใช้งาน keyring แบบเก่าอีกต่อไป จากนั้นคุณสามารถลบรายการดังกล่าวออกได้ด้วย sudo gpg --no-default-keyring --keyring /etc/apt/trusted.gpg --delete-key 7EA0A9C3F273FCD8

อีกหนึ่งนิสัยที่จะช่วยลดปัญหาได้มากที่สุดคือ การที่ do-release-upgrade จะปิดการใช้งานแหล่งซอฟต์แวร์ภายนอกระหว่างการอัปเกรดและคงสถานะปิดไว้หลังจากนั้น การเปิดใช้งานกลับทีละรายการด้วยตนเองมักเป็นสาเหตุที่ทำให้เกิดการประกาศค่าซ้ำซ้อน โปรดอ่าน คู่มือการอัปเกรด Ubuntu 24.04 ไปยัง 26.04 ก่อนเริ่มดำเนินการ และจดบันทึกว่าคุณยังจำเป็นต้องใช้ repository ใดบ้าง สำหรับเครื่องที่เพิ่งติดตั้งใหม่ ช่วงเวลาที่เหมาะสมที่สุดในการจัดการแหล่งซอฟต์แวร์ให้ถูกต้องคือระหว่าง สิบนาทีแรกบน VPS ใหม่ ในขณะที่รายการในเครื่องยังมีเพียงรายการที่ Ubuntu ติดตั้งมาให้ตั้งแต่ต้นเท่านั้น

FAQ

ทำไม apt ถึงแจ้งว่ามีการกำหนดค่าเป้าหมายซ้ำหลายครั้ง?

เพราะมีไฟล์สองไฟล์ภายใต้ /etc/apt/sources.list.d/ ประกาศ repository, suite และ component เดียวกัน ข้อความแจ้งเตือนจะระบุชื่อไฟล์ทั้งสองพร้อมเลขบรรทัด เช่น docker.list:1 และ docker.sources:1 แม้ว่า apt จะรวมค่าเหล่านั้นและทำงานต่อได้ตามปกติ แต่ควรลบรายการที่ซ้ำออก เพราะหากไฟล์ทั้งสองระบุ signing key ที่ต่างกัน apt จะหยุดทำงานด้วยข้อผิดพลาด E: Conflicting values set for option Signed-By และปฏิเสธที่จะอ่าน source ใดๆ เลย ซึ่งจะทำให้ apt install ไม่สามารถทำงานได้เช่นกัน

ควรเก็บไฟล์ .list หรือไฟล์ .sources ไว้?

ควรเก็บไฟล์ .sources ไว้ รูปแบบ deb822 คือสิ่งที่ add-apt-repository ใช้ใน Ubuntu 24.04 และเวอร์ชันที่ใหม่กว่า โดยเก็บข้อมูลแบบระบุชื่อฟิลด์ต่อการตั้งค่าหนึ่งรายการ แทนการใช้ข้อความตามตำแหน่งในวงเล็บเหลี่ยม ซึ่งเป็นทิศทางที่การแจกจ่ายซอฟต์แวร์กำลังมุ่งไป ก่อนจะลบไฟล์ .list ให้ตรวจสอบก่อนว่าเส้นทาง Signed-By ภายในไฟล์ .sources ชี้ไปยัง key ที่มีอยู่จริงด้วยคำสั่ง ls -l /etc/apt/keyrings/ และให้ย้ายไฟล์เก่าออกจาก /etc/apt/sources.list.d/ แทนการเปลี่ยนชื่อไฟล์ทิ้งไว้ในไดเรกทอรีเดิม เพราะชื่อไฟล์ที่ลงท้ายด้วย .bak จะทำให้ apt แสดงข้อความแจ้งเตือนไฟล์ที่ถูกละเว้นทุกครั้งที่รันคำสั่ง

จะปิดการใช้งาน apt repository โดยไม่ลบออกได้อย่างไร?

ในไฟล์ .sources รูปแบบ deb822 ให้เพิ่ม Enabled: no ลงใน stanza นั้น ส่วนในไฟล์รูปแบบบรรทัดเดียว .list ให้ใส่ # ไว้ที่ต้นบรรทัด ไม่ว่าจะใช้วิธีใด หลังจากนั้นให้รัน sudo apt update แล้วบล็อก Err: สำหรับ repository นั้นก็จะหายไป นี่เป็นวิธีที่เหมาะสมเมื่อ repository ของบุคคลที่สามยังไม่มีแพ็กเกจสำหรับ Ubuntu release ของคุณ และข้อผิดพลาด 404 ทำให้ apt update จบการทำงานด้วยสถานะ non-zero

รูปแบบ sources.list แบบบรรทัดเดียวจะถูกยกเลิกหรือไม่?

รูปแบบนี้ถูกประกาศว่าเลิกใช้แล้ว (deprecated) แต่ยังไม่ได้ถูกถอดออก apt ยังคงอ่านไฟล์ .list ได้และจะยังคงอ่านได้ต่อไปอีกนาน ดังนั้นเซิร์ฟเวอร์ของคุณจะไม่มีปัญหาในวันพรุ่งนี้ เครื่องมือใหม่ๆ จะเขียนไฟล์ในรูปแบบ deb822 โดย Ubuntu 24.04 และเวอร์ชันที่ใหม่กว่าจะเก็บ repository ของระบบไว้ใน /etc/apt/sources.list.d/ubuntu.sources และ add-apt-repository จะเขียนไฟล์ในรูปแบบ .sources สำหรับ apt 3.0 และเวอร์ชันที่ใหม่กว่า คุณสามารถใช้ sudo apt modernize-sources เพื่อแปลงไฟล์ที่คุณมีอยู่ให้เป็นรูปแบบใหม่ได้

#apt#ubuntu#deb822#package-management#troubleshooting