รวมคำสั่ง Docker Compose ที่ใช้บ่อยบนเซิร์ฟเวอร์จริง
สรุปคำสั่ง Docker Compose V2 ที่จำเป็นสำหรับการจัดการคอนเทนเนอร์บนเซิร์ฟเวอร์ ตั้งแต่การรัน การดู Logs ไปจนถึงการล้างข้อมูลอย่างปลอดภัย พร้อมวิธีแก้ปัญหา command not found
คำสั่ง Compose ที่คุณจะได้ใช้งานจริง
Docker Compose มีคำสั่งย่อยให้ใช้งานหลายสิบคำสั่ง แต่การทำงานบนเซิร์ฟเวอร์ในแต่ละวันจะใช้เพียงประมาณหนึ่งโหลเท่านั้น หน้านี้จะจัดกลุ่มคำสั่งเหล่านั้นตามลักษณะงานที่คุณทำ พร้อมระบุเหตุผลสั้นๆ สำหรับแต่ละคำสั่ง และชี้ไปยังเนื้อหาเชิงลึกในกรณีที่คำสั่งนั้นอาจมีข้อควรระวังซ่อนอยู่
ทุกคำสั่งในที่นี้ใช้ Compose V2 หรือ V5 คือ docker compose โดยเว้นวรรค ไม่ใช่สคริปต์ docker-compose แบบเก่า ทั้งคู่เป็น Go plugin สำหรับบน Linux นั้น Compose plugin จะถูกติดตั้งแยกต่างหากจาก Docker Engine โดย Ubuntu 24.04 LTS ยังคงมีเครื่องมือ Python V1 รุ่นเก่าในชื่อ docker-compose เวอร์ชัน 1.29.2-6ubuntu1 อยู่ในคลังซอฟต์แวร์ universe ให้ตรวจสอบด้วย docker compose version หากคำสั่งดังกล่าวใช้งานไม่ได้ ให้ตั้งค่าคลังซอฟต์แวร์ของ Docker แล้วติดตั้งแพ็กเกจ docker-compose-plugin
ทุกคำสั่งด้านล่างนี้ต้องรันจากไดเรกทอรีที่มีไฟล์ compose.yaml ของคุณอยู่ โดย Compose จะใช้ชื่อไดเรกทอรีนั้นเป็นชื่อโปรเจกต์โดยปริยาย เว้นแต่คุณจะกำหนดค่าอื่นทับ หากไม่มีการใช้ -f หรือ COMPOSE_FILE ตัว Compose จะค้นหาไฟล์คอนฟิกูเรชันจากไดเรกทอรีปัจจุบันและไดเรกทอรีแม่ ดังนั้นการรันคำสั่งจากระดับที่สูงกว่าหนึ่งชั้นจะพบ stack ของคุณก็ต่อเมื่อไฟล์นั้นยังอยู่ในเส้นทางการค้นหาดังกล่าว หากรูปแบบไฟล์ยังเป็นเรื่องใหม่สำหรับคุณ ให้เริ่มต้นที่ การสร้างไฟล์ Compose ไฟล์แรกบน VPS แล้วค่อยกลับมาดูคำสั่งเหล่านี้ที่นี่
วงจรชีวิต: สี่คำสั่งที่คุณใช้ และหนึ่งคำสั่งที่ลบคอนเทนเนอร์
docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose downup -d ทำหน้าที่สร้างเครือข่าย สร้างคอนเทนเนอร์ เริ่มการทำงานของคอนเทนเนอร์ แล้วจึงจบการทำงาน คำสั่งนี้จะคืนค่าหลังจากเริ่มคอนเทนเนอร์โดยไม่รอให้แอปพลิเคชันพร้อมใช้งาน ซึ่งเป็นสาเหตุที่สคริปต์ deploy ที่ใช้ curl ตรวจสอบต่อท้ายมักจะล้มเหลวในการรันครั้งแรก up -d --wait จะรอจนกว่าบริการที่มี healthcheck จะอยู่ในสถานะ healthy และบริการที่ไม่มี healthcheck จะอยู่ในสถานะ running หากบริการอยู่ในสถานะ unhealthy หรือ --wait-timeout หมดอายุ จะส่งผลให้เกิด exit code ที่ไม่ใช่ศูนย์ ประสิทธิภาพของแฟล็กนี้ขึ้นอยู่กับความถูกต้องของการตรวจสอบ ดังนั้นควรเขียน healthcheck ที่ Compose เชื่อถือได้ ก่อนที่จะนำไปใช้ในระบบอัตโนมัติ
stop จะหยุดการทำงานของคอนเทนเนอร์แต่ยังคงเก็บคอนเทนเนอร์ไว้ ทำให้ start สามารถนำคอนเทนเนอร์เดิมกลับมาทำงานต่อได้โดยใช้ writable layer เดิม down จะหยุดการทำงานและลบทั้งคอนเทนเนอร์และเครือข่ายของโปรเจกต์ทิ้ง ข้อมูลใดก็ตามที่เขียนไว้ภายในคอนเทนเนอร์แต่ไม่ได้อยู่ใน volume จะถูกลบไปด้วย นี่คือความเข้าใจผิดที่มีราคาแพงที่สุดในการใช้งาน Compose และ ความแตกต่างทั้งหมดระหว่าง down และ stop จะอธิบายถึงผลกระทบที่อาจเกิดขึ้น
restart ไม่ใช่การโหลดค่าใหม่ (reload) คำสั่งนี้จะหยุดและเริ่มคอนเทนเนอร์เดิมด้วยการตั้งค่าที่มีอยู่แล้ว ดังนั้นการเปลี่ยนแปลง environment variable, การเปลี่ยน image tag หรือการแก้ไข port mapping จะไม่มีผลใดๆ ทั้งสิ้น หากต้องการปรับใช้การเปลี่ยนแปลงไฟล์ คุณต้องรัน up -d อีกครั้ง Compose จะเปรียบเทียบแต่ละบริการกับคอนเทนเนอร์ที่กำลังทำงานอยู่ และสร้างคอนเทนเนอร์ใหม่เฉพาะบริการที่มีการเปลี่ยนแปลงการตั้งค่าหรือ image เท่านั้น
การนำการเปลี่ยนแปลงไปใช้: การสร้างใหม่ (recreate), การดึงข้อมูล (pull) หรือการสร้างอิมเมจใหม่ (rebuild)
docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build webup -d จะนำคอนเทนเนอร์ที่กำลังทำงานอยู่กลับมาใช้ใหม่หากการตั้งค่าและอิมเมจไม่มีการเปลี่ยนแปลง ส่วนการดึงข้อมูลและการสร้างอิมเมจจะเป็นไปตามนโยบายการดึงข้อมูล (pull policy) ของบริการนั้นๆ --force-recreate จะข้ามการเปรียบเทียบดังกล่าวและแทนที่คอนเทนเนอร์ทั้งหมดแม้ว่าการตั้งค่าจะเหมือนเดิมทุกประการ จึงเป็นวิธีที่รวดเร็วที่สุดในการล้างสถานะภายในคอนเทนเนอร์ที่ผิดปกติ
ขั้นตอนการอัปเดตอิมเมจแบบระบุชัดเจนจะใช้คำสั่งสองคำสั่งเนื่องจากทำหน้าที่ต่างกัน pull จะดาวน์โหลดอิมเมจปัจจุบันสำหรับแต่ละแท็กที่ระบุไว้ในไฟล์ จากนั้น up -d จะตรวจพบว่า ID ของอิมเมจในบริการไม่ตรงกับคอนเทนเนอร์ที่กำลังทำงานอยู่ จึงทำการสร้างคอนเทนเนอร์ขึ้นใหม่ โดยปกติแล้วภายใต้นโยบายการดึงข้อมูลแบบ missing แท็กที่อยู่ในแคชจะถูกนำกลับมาใช้ใหม่ยกเว้นแท็ก latest ซึ่งจะถูกดึงข้อมูลใหม่เสมอ ความเสี่ยงที่ตรงกันข้ามจะเกิดขึ้นใน stack ที่มีหลายบริการ โดยการดึงข้อมูล latest สำหรับทุกบริการพร้อมกันอาจทำให้แอปพลิเคชันที่ทำงานได้ตามปกติเมื่อสิบวินาทีก่อนเกิดข้อผิดพลาดได้ นี่คือเหตุผลที่ การโฮสต์ AFFiNE workspace ด้วยตนเอง แนะนำให้กำหนดเวอร์ชัน (pinning) ของแอปพลิเคชันและอิมเมจสำหรับการย้ายข้อมูล (migration) ไว้ที่ digest เดียวกัน การกำหนดเวอร์ชันยังเปลี่ยนการอัปเกรดให้เป็นการแก้ไขแท็กอย่างตั้งใจตามด้วยการดึงข้อมูลและสร้างใหม่ และสำหรับ stack ที่มีการย้ายฐานข้อมูลขณะเริ่มระบบ คุณควรสำรองข้อมูล (dump) ไว้ก่อนใช้คำสั่งใดๆ ซึ่งเป็นขั้นตอนที่ การโฮสต์ Chatwoot support desk ด้วยตนเอง ปฏิบัติทุกครั้งที่มีการอัปเดตเวอร์ชัน
build ใช้กับบริการที่ประกาศส่วน build: รวมถึงบริการที่ประกาศ image: ด้วย up -d --build จะทำการสร้างและเริ่มการทำงานในขั้นตอนเดียว ซึ่งเป็นวงจรปกติในขณะที่คุณกำลังแก้ไขโค้ด ให้ใช้ --no-cache ก็ต่อเมื่อเลเยอร์ในแคชล้าสมัยอย่างชัดเจนเท่านั้น เพราะคำสั่งนี้จะสร้างทุกเลเยอร์ขึ้นใหม่ตั้งแต่ต้น บางโปรเจกต์มีทั้งสองเส้นทางจาก repo เดียวกันที่โคลนมา ซึ่งทั้งสองวงจรนี้เป็นเส้นทางการอัปเดตทางเลือก: การโฮสต์ openGym workout tracker ด้วยตนเอง ใช้ docker compose up -d --build เพื่อสร้าง checkout ที่กำหนดเวอร์ชันไว้ เพราะการดึงอิมเมจ latest อาจทำให้ได้รุ่นที่ใหม่กว่า checkout นั้นได้
การตรวจสอบสิ่งที่กำลังทำงานอยู่
docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose lsps จะแสดงเฉพาะคอนเทนเนอร์ที่กำลังทำงานอยู่เท่านั้น บริการที่ขัดข้องระหว่างการเริ่มทำงานจะไม่ปรากฏในรายการจนกว่าคุณจะเพิ่ม -a ดังนั้นการที่คอนเทนเนอร์หายไปจาก ps ในขณะที่ ps -a แสดงสถานะเป็น Exited (1) จึงเป็นลักษณะปกติของความล้มเหลวในการเริ่มทำงาน ให้ตรวจสอบ exit code แล้วจึงอ่าน log
logs -f จะติดตามทุกบริการพร้อมกันและใส่ชื่อบริการไว้หน้าแต่ละบรรทัด ซึ่งเป็นมุมมองที่คุณต้องการเมื่อบริการต่างๆ สื่อสารกันและลำดับของเหตุการณ์มีความสำคัญ คุณสามารถระบุชื่อบริการเพื่อจำกัดขอบเขตการแสดงผลได้ --tail=100 มีความสำคัญสำหรับคอนเทนเนอร์ที่ทำงานมานานเป็นเดือน เพราะค่าเริ่มต้นจะพิมพ์ประวัติทั้งหมดออกมาและทำให้ terminal ล้น --since 15m จะตอบคำถามที่คุณมักจะสงสัย ซึ่งก็คือเกิดอะไรขึ้นบ้างในช่วงการรีสตาร์ทที่คุณเพิ่งทำไป
top จะแสดงรายการกระบวนการ (process) ภายในแต่ละคอนเทนเนอร์ ซึ่งช่วยแยกแยะระหว่าง "คอนเทนเนอร์กำลังทำงาน" กับ "กระบวนการภายในคอนเทนเนอร์กำลังทำงาน" ออกจากกัน ls จะข้ามออกจากไดเรกทอรีปัจจุบันและแสดงรายการโปรเจกต์ Compose ที่กำลังทำงานอยู่บนโฮสต์พร้อมสถานะ; ให้เพิ่ม -a เพื่อรวมโปรเจกต์ที่หยุดทำงานไปแล้วด้วย
การเข้าถึง Shell ภายใน Service
docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web shexec ใช้สำหรับรันคำสั่งภายในคอนเทนเนอร์ที่กำลังทำงานอยู่ ส่วน run ใช้สำหรับเริ่มคอนเทนเนอร์ใหม่จากนิยามของ Service เดิม ซึ่งจำเป็นในกรณีที่ Service ไม่สามารถทำงานได้นานพอที่จะใช้คำสั่ง exec เข้าไปได้ ควรใช้ run คู่กับ --rm เสมอ เพราะหากไม่ใช้ ทุกครั้งที่เรียกคำสั่งจะทิ้งคอนเทนเนอร์ที่หยุดทำงานไว้เบื้องหลัง และคอนเทนเนอร์เหล่านี้จะสะสมจนทำให้ docker compose ps -a อ่านข้อมูลได้ยาก
ให้ลองใช้ sh ก่อนที่จะใช้ bash เนื่องจาก Image บางตัวที่ใช้ Alpine จะมี bash ติดมาด้วย รวมถึง Image อย่างเป็นทางการของ PostgreSQL บน Alpine แต่หากไม่มี bash จะพบข้อผิดพลาด exec: "bash": executable file not found in $PATH การเพิ่ม --no-deps เข้าไปใน run จะช่วยข้ามการตรวจสอบ Dependency ของ Service ซึ่งจะช่วยป้องกันไม่ให้การตรวจสอบ Config เพียงชั่วคราวไปสั่งเริ่มการทำงานของฐานข้อมูลทั้งหมดของคุณ
run --rm web env เป็นวิธีที่เร็วที่สุดในการดู Environment ที่ Service ได้รับจริง หลังจากที่ไฟล์ .env, บล็อก environment: และตัวแปร Shell ทั้งหมดถูกรวมเข้าด้วยกันแล้ว หากค่าที่ได้ไม่ถูกต้อง สาเหตุมักเกิดจากลำดับการรวมข้อมูล และ วิธีที่ Compose จัดการกับไฟล์ env และ secrets จะอธิบายว่าแหล่งข้อมูลใดจะมีลำดับความสำคัญสูงสุด
เครือข่าย พอร์ต และการแก้ไขชื่อโดเมน
docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networksโดยค่าเริ่มต้น Compose จะนำทุกบริการไปไว้บนเครือข่ายโปรเจกต์เดียวกัน และชื่อของแต่ละบริการจะทำหน้าที่เป็นชื่อ DNS ภายในเครือข่ายนั้น การรัน getent hosts db ภายใน web ในกรณีที่อิมเมจมี getent รวมอยู่ด้วย จะเป็นการตรวจสอบการแก้ไขชื่อโดเมนเท่านั้น ไม่ใช่การทดสอบว่า db ยอมรับการเชื่อมต่อหรือไม่ หากชื่อโดเมนแก้ไขได้แต่การเชื่อมต่อถูกปฏิเสธ ให้ตรวจสอบว่าเซิร์ฟเวอร์กำลังทำงานและเปิดพอร์ตที่ร้องขออยู่จริงหรือไม่ การผูกบริการไว้กับ 127.0.0.1 เพียงอย่างเดียวอาจเป็นสาเหตุหนึ่งของปัญหานี้ ขอบเขตเดียวกันนี้อธิบายว่าเหตุใดคอนเทนเนอร์ที่เริ่มทำงานนอกโปรเจกต์ ไม่ว่าจะโดย docker run หรือในฐานะ stack ของตนเอง จึงจำเป็นต้องใช้เครือข่ายร่วมกันเพื่อแก้ไขชื่อบริการอย่าง jellyfin ซึ่งเป็นสิ่งแรกที่ควรตรวจสอบเมื่อ Halcyon front end สำหรับคลัง Jellyfin ของคุณ ไม่สามารถเข้าถึงเซิร์ฟเวอร์ที่ระบุไว้ได้ รายละเอียดเพิ่มเติมเกี่ยวกับโมเดลนี้อยู่ใน วิธีการทำงานของเครือข่าย Compose และบริการ DNS
port web 80 จะแสดงที่อยู่โฮสต์และพอร์ตที่พอร์ตของคอนเทนเนอร์ถูกเผยแพร่ออกไป ซึ่งช่วยลดการคาดเดาในกรณีที่การแมปพอร์ตมาจากตัวแปร การเผยแพร่พอร์ตยังเป็นการเขียนกฎไฟร์วอลล์ที่ Docker จัดการเอง ซึ่งกฎนี้จะอยู่หน้ากฎที่คุณตั้งไว้ ดังนั้นบริการที่คุณเข้าใจว่าเป็นส่วนตัวอาจเปิดเผยต่ออินเทอร์เน็ตได้ กรณีนี้ครอบคลุมอยู่ใน เหตุใดพอร์ต Docker ที่เผยแพร่จึงข้าม ufw การไม่เผยแพร่พอร์ตเหล่านั้นและใช้พร็อกซีที่มีการยืนยันตัวตนบนเครือข่ายโปรเจกต์วางไว้หน้าบริการต่างๆ แทนถือเป็นรูปแบบที่ปลอดภัยกว่า ซึ่งเป็นสิ่งที่ การรัน Authentik ในฐานะเลเยอร์ single sign-on มอบให้คุณ
Volumes และข้อมูล
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vconfig --volumes จะแสดงรายการ named volumes ที่โปรเจกต์ประกาศไว้ โดยแสดงผลทีละบรรทัด รายการดังกล่าวเป็นเพียงส่วนหนึ่งของรายการสำรองข้อมูลเท่านั้น เนื่องจาก bind mounts และไฟล์ตั้งค่าต่าง ๆ ก็จำเป็นต้องได้รับการตรวจสอบเช่นกัน ในกรณีที่ volume จัดเก็บข้อมูลที่ไม่สามารถหาทดแทนได้ คำสั่งสำรองข้อมูลที่ถูกต้องมีความสำคัญพอ ๆ กับรายการที่ระบุ ซึ่งเป็นเหตุผลว่าทำไม การเปรียบเทียบระหว่าง PhotoPrism และ Immich จึงได้ระบุคำสั่ง dump และ copy ที่เซิร์ฟเวอร์รูปภาพแต่ละตัวจำเป็นต้องใช้ cp ใช้สำหรับคัดลอกไฟล์เข้าหรือออกจาก container โดยไม่ต้องเปิด shell ผ่านการใช้รูปแบบ service:path ในฝั่งที่เป็น container
down -v จะลบ named volumes ที่ประกาศไว้ทั้งหมด ยกเว้น volume ภายนอก รวมถึง anonymous volumes ที่ผูกอยู่กับ container และตัว container เอง คำสั่งนี้เหมาะสำหรับการลบ stack ที่ใช้ทดสอบ แต่เป็นคำสั่งที่ไม่ควรใช้กับข้อมูลใด ๆ ที่คุณต้องการเก็บรักษาไว้ เนื่องจากไม่มีการยืนยันก่อนลบและไม่สามารถย้อนกลับได้ ทั้งนี้ bind mounts จะไม่ถูกลบเนื่องจากไฟล์เหล่านี้จัดเก็บอยู่บนระบบไฟล์ของ host ความแตกต่างในขอบเขตความเสียหายนี้เป็นเหตุผลหนึ่งที่ทำให้คุณต้องเลือกอย่างรอบคอบระหว่าง bind mounts และ named volumes
การล้างข้อมูลเพื่อเพิ่มพื้นที่ดิสก์โดยไม่สูญเสียข้อมูล
docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune--remove-orphans จะลบ container ที่อยู่ในโปรเจกต์แต่ไม่มีระบุไว้ในไฟล์แล้ว ซึ่งเป็นสิ่งที่เกิดขึ้นหลังจากเปลี่ยนชื่อ service หากไม่ใช้คำสั่งนี้ container เหล่านั้นจะยังคงทำงานอยู่ และ docker compose ps จะรวม container ที่เป็น orphan ซึ่งยังทำงานอยู่ไว้ด้วยโดยค่าเริ่มต้น
docker system df จะแสดงรายละเอียดการใช้พื้นที่ดิสก์ก่อนที่คุณจะลบข้อมูลใดๆ โดยแยกหมวดหมู่เป็น image, container, local volume และ build cache พร้อมระบุจำนวนพื้นที่ที่สามารถกู้คืนได้ในแต่ละส่วน image prune -a จะลบ image ทุกตัวที่ไม่มี container ใดใช้งานอยู่ ไม่ว่าจะมีการติด tag หรือไม่ก็ตาม ซึ่งบนเครื่องที่เคยดึง image ขนาดใหญ่มาหลายเวอร์ชัน คำสั่งนี้มักจะช่วยเพิ่มพื้นที่ได้มากที่สุด builder prune จะลบ build cache ที่ค้างอยู่โดยค่าเริ่มต้น ให้เพิ่ม -a เพื่อลบ build cache ที่ไม่ได้ใช้งานทั้งหมด
คำสั่งทั้งหมดข้างต้นจะไม่ส่งผลกระทบต่อ named volume การใช้ docker volume prune --all, docker compose down -v และ docker volume rm จะเป็นการลบ named volume ส่วนการใช้ docker volume prune เพียงอย่างเดียวจะลบเฉพาะ anonymous volume เท่านั้น
การตรวจสอบไฟล์ก่อนที่จะเกิดความเสียหาย
docker compose config --quiet
docker compose config --services
docker compose --dry-run up -dconfig --quiet จะทำการตรวจสอบและไม่แสดงผลลัพธ์ใดๆ หากสำเร็จ ดังนั้นจึงควรใช้ในขั้นตอนก่อนการ deploy หรือใช้เป็น git hook ส่วน config จะแสดงผลไฟล์ที่รวมและแทนที่ตัวแปรทั้งหมดแล้ว ซึ่งเป็นวิธีที่คุณใช้ยืนยันว่าตัวแปรถูกแทนที่ค่าและไฟล์ override ถูกซ้อนทับตามที่คาดหวังไว้ หากตัวแปรใดไม่ได้ถูกกำหนดค่าไว้ จะปรากฏเป็นค่าว่างในส่วนนี้ พร้อมกับคำเตือน The "X" variable is not set. Defaulting to a blank string.
--dry-run เป็น global flag ไม่ใช่ subcommand flag ดังนั้นจึงต้องวางไว้หน้า up โดยคำสั่งนี้จะแสดงทุกการกระทำที่ Compose จะดำเนินการโดยไม่มีการเปลี่ยนแปลงใดๆ เกิดขึ้นจริง ซึ่งเป็นการใช้เวลา 30 วินาทีที่คุ้มค่าก่อนที่จะรัน down บน stack ที่มีความสำคัญ
การทำงานข้ามไฟล์ โปรไฟล์ และโปรเจกต์
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -dแฟล็ก -f หลายรายการจะถูกรวมเข้าด้วยกันตามลำดับ โดยไฟล์ที่ระบุภายหลังจะเขียนทับค่าเดิมในไฟล์ก่อนหน้าแบบคีย์ต่อคีย์ นี่เป็นวิธีมาตรฐานในการเก็บไฟล์ฐานไว้หนึ่งไฟล์และใช้ไฟล์ override สำหรับ production ขนาดเล็ก อย่างไรก็ตาม กฎการรวมรายการ (lists) และแผนผัง (maps) จะแตกต่างกัน โปรดอ่าน วิธีการที่ Compose รวมไฟล์หลายไฟล์ ก่อนที่คุณจะเริ่มแก้ไขปัญหาหากพบผลลัพธ์ที่ไม่คาดคิด
--profile จะเริ่มบริการที่ถูกแท็กด้วยโปรไฟล์นั้นควบคู่ไปกับบริการที่ไม่ได้แท็ก ซึ่งช่วยแยกเครื่องมือสำหรับ debug ออกจากการทำงานปกติของ up ส่วน -p ใช้สำหรับกำหนดชื่อโปรเจกต์ เพื่อให้สามารถรัน stack ชุดเดียวกันสองชุดควบคู่กันได้โดยใช้เครือข่ายและชื่อ volume ที่แยกจากกัน การนำ stack กลับมาทำงานใหม่หลังการรีบูตสามารถทำได้โดยใช้ restart policy หรือใช้ unit ที่รัน Compose ให้คุณ ซึ่งอธิบายไว้ใน การเริ่ม Compose stack ขณะบูตเครื่อง
FAQ
อะไรมาแทนที่ docker-compose ที่ใช้เครื่องหมายยัติภังค์?
Compose V2 และ V5 จะเรียกใช้งานผ่าน docker compose โดยใช้ช่องว่าง สำหรับบน Linux นั้น Compose เป็นปลั๊กอินที่ต้องติดตั้งแยกต่างหาก โดย Ubuntu 24.04 LTS ยังคงมีเครื่องมือ Python เวอร์ชัน V1 ให้บริการใน repository แบบ universe หากไม่สามารถเรียกใช้งานในรูปแบบที่มีช่องว่างได้ ให้ตั้งค่า repository ของ Docker แล้วติดตั้งแพ็กเกจ docker-compose-plugin แทน ควรปรับปรุงสคริปต์เก่าให้เป็นรูปแบบที่มีช่องว่างแทนการสร้าง alias เนื่องจาก V2 มี flag ที่ V1 ไม่มี
ทำไม docker compose restart ถึงไม่รับการเปลี่ยนแปลงค่าคอนฟิกของฉัน?
restart จะหยุดและเริ่มคอนเทนเนอร์เดิมด้วยค่าคอนฟิกที่ใช้ตอนสร้างขึ้นมาเท่านั้น และจะไม่โหลด compose.yaml ซ้ำ การเปลี่ยนแปลงใดๆ ต่อ environment variable, พอร์ต, volume หรือ image tag จำเป็นต้องใช้ docker compose up -d ซึ่งจะเปรียบเทียบแต่ละ service กับคอนเทนเนอร์ที่กำลังทำงานอยู่และสร้างใหม่เฉพาะส่วนที่แตกต่างกัน ให้เพิ่ม --force-recreate เมื่อคุณต้องการให้มีการแทนที่คอนเทนเนอร์ใหม่แม้ว่าจะไม่มีการเปลี่ยนแปลงใดๆ ในไฟล์ก็ตาม
ฉันจะอัปเดต service ให้เป็น image เวอร์ชันใหม่ได้อย่างไร?
ให้รัน docker compose pull แล้วตามด้วย docker compose up -d คำสั่ง pull จะดึง image ปัจจุบันสำหรับแต่ละ tag ในไฟล์ และ up -d จะสร้าง service ใหม่สำหรับทุกรายการที่ image ID ไม่ตรงกับคอนเทนเนอร์ที่รันอยู่ การรัน up -d เพียงอย่างเดียวจะเป็นไปตามนโยบาย pull policy: โดยค่าเริ่มต้นคือ missing ซึ่งจะใช้ image ที่อยู่ในแคช ยกเว้นกรณีที่เป็น latest ซึ่งจะถูกดึงใหม่เสมอ
คำสั่งล้างข้อมูลใดบ้างที่ปลอดภัยบนเซิร์ฟเวอร์ที่ใช้งานจริง?
docker system df จะรายงานการใช้งานดิสก์โดยไม่มีการลบข้อมูลใดๆ ส่วน docker image prune -a และ docker builder prune จะลบ image และ build cache ที่ไม่ได้ใช้งานออก ดังนั้น service ที่รันอยู่จะยังคงทำงานได้ตามปกติและ named volume จะไม่ถูกแตะต้อง คำสั่งที่อันตรายคือ docker compose down -v ซึ่งจะลบ named volume ที่ประกาศไว้ในโปรเจกต์ (ที่ไม่ใช่ external) และ anonymous volume ที่เชื่อมต่ออยู่โดยไม่มีการถามยืนยัน และ docker volume prune --all ซึ่งจะลบ local volume ที่ไม่ได้ใช้งาน รวมถึง named volume หลังจากถามยืนยัน y/N หรือลบโดยไม่ถามเลยหากใช้ -f ควรตรวจสอบด้วย docker compose config --volumes ก่อนเสมอเพื่อให้ทราบว่าข้อมูลใดมีความเสี่ยง
ฉันสามารถรันคำสั่งเดียวโดยไม่ต้องเริ่มทั้ง stack ได้หรือไม่?
ได้ docker compose run --rm --no-deps web sh จะเริ่มคอนเทนเนอร์เดียวจากนิยามของ service web โดยข้าม dependency ต่างๆ และจะลบคอนเทนเนอร์ทิ้งเมื่อคุณออกจากคำสั่ง ให้ใช้ exec แทนในกรณีที่คอนเทนเนอร์กำลังทำงานอยู่แล้ว เนื่องจาก exec จะรันคำสั่งของคุณภายในคอนเทนเนอร์ที่ทำงานอยู่จริงและแสดงสถานะที่ service นั้นเป็นอยู่จริงๆ