วิธีแก้ไขไฟล์ใน Docker container ที่หยุด / ไม่เริ่ม


94

พยายามแก้ไขข้อผิดพลาดและแก้ไขปัญหาเกี่ยวกับแอปพลิเคชันของฉันที่แบ่งออกเป็นหลายคอนเทนเนอร์ฉันมักแก้ไขไฟล์ในคอนเทนเนอร์:

  • ฉันขี้เกียจและติดตั้งนาโนและแก้ไขโดยตรงในคอนเทนเนอร์หรือ

  • ฉันเทียบท่า cp ไฟล์ออกจากคอนเทนเนอร์แก้ไขคัดลอกกลับและรีสตาร์ทคอนเทนเนอร์

ขั้นตอนเหล่านี้เป็นขั้นตอนกลางก่อนที่จะมาถึงเนื้อหาใหม่สำหรับการสร้างคอนเทนเนอร์ซึ่งใช้เวลานานกว่าการทำข้างต้นมาก (ซึ่งแน่นอนว่าเป็นเพียงขั้นกลาง / การเล่นซอเท่านั้น)

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

มีวิธีใดในการบันทึกภาชนะเหล่านั้นหรือไม่? เนื่องจากพวกเขาไม่เริ่มต้นฉันจึงไม่สามารถเทียบท่ากับพวกเขาได้ดังนั้นพวกเขาจึงหลงทางให้ฉัน จากนั้นฉันไปที่เส้นทาง rm / rmi / build / run หลังจากแก้ไขไฟล์ที่ละเมิดในอินพุตบิลด์

ฉันจะแก้ไขไฟล์ในคอนเทนเนอร์ที่ถูกหยุดได้อย่างไรหรือ cp ในหรือเริ่มต้นเชลล์ในคอนเทนเนอร์ที่ถูกหยุด - สิ่งใดที่ช่วยให้ฉันแก้ไขคอนเทนเนอร์นี้

(ดูเหมือนว่าจะทำงานบนคอมพิวเตอร์ระยะไกลและทำลายการกำหนดค่าเครือข่าย - การเชื่อมต่อจะขาดหายไป "ตลอดกาล" ด้วยวิธีนี้และต้องใช้ทางเลือกอื่นหากมี)

จะแก้ไขไฟล์ Docker container จากโฮสต์ได้อย่างไร? ดูเกี่ยวข้อง แต่ล้าสมัย


อันนี้อาจเป็นวิธีแก้ปัญหาstackoverflow.com/a/32353134/586754 - หวังว่าจะได้ทางออกที่ดีกว่า
Andreas Reiff

1
บางทีคุณควรพิจารณาติดตั้งโวลุ่มเพื่อให้คุณสามารถแก้ไขไฟล์บนโฮสต์ของคุณแทนที่จะอยู่ในคอนเทนเนอร์ เมื่อพอใจกับรหัสของคุณแล้วคุณมีอิสระที่จะdocker cpใช้ไฟล์ไปยังคอนเทนเนอร์ (หรือสร้างภาพใหม่)
Thomasleveil

ใช่มันจะช้าไปหน่อย แต่ถ้าฉันไม่ได้ตั้งค่าแบบนี้ตั้งแต่แรก ฉันคิดว่าสิ่งนี้ไม่ได้ผลสำหรับการกู้คืน
Andreas Reiff

ผู้อ่านจำนวนมากต้องการดูไฟล์เท่านั้นแทนที่จะแก้ไข ในกรณีเหล่านี้คุณสามารถใช้docker commitคำสั่งเพื่อแบ่งรูปภาพใหม่ name=$(docker commit); docker run -it $name /bin/shจะทำในสิ่งที่คุณต้องการ
Att Righ

ดังนั้นดูเหมือนว่าระบบไฟล์ของคอนเทนเนอร์ที่หยุดทำงานจะค่อนข้างถาวรในตอนท้าย?
Webwoman

คำตอบ:


140

ฉันมีปัญหากับคอนเทนเนอร์ที่ไม่เริ่มทำงานเนื่องจากการเปลี่ยนแปลงการกำหนดค่าที่ไม่ดีที่ฉันทำ ฉันสามารถคัดลอกไฟล์ออกจากคอนเทนเนอร์ที่หยุดและแก้ไขได้ สิ่งที่ต้องการ:

docker cp docker_web_1:/etc/apache2/sites-enabled/apache2.conf .

(แก้ไขไฟล์)

docker cp apache.conf docker_web_1:/etc/apache2/sites-enabled/apache2.conf

22
คำตอบนี้เป็นคำตอบที่ยอมรับ ด้วยเหตุผลบางอย่างฉันไม่คิดว่า CP ทำงานกับคอนเทนเนอร์ที่หยุดได้ ดี!
Proximo

สมบูรณ์แบบ. ฉันคัดลอกไฟล์จากคอนเทนเนอร์ (ฉันรู้เส้นทางของมัน) แล้วแก้ไขแล้วคัดลอกกลับไปที่คอนเทนเนอร์ไปยังตำแหน่งเดิม ทำงานให้ฉัน! ขอบคุณ!
Nawaz

มีวิธีลบไฟล์หรือไม่?
kodlan

1
@kodlan เฉพาะในกรณีที่ปรากฏเฉพาะในสิ่งที่UpperDirคุณได้รับdocker container inspect- คุณต้องทดลองเพื่อดูว่าระบบซ้อนทับแสดงถึงไฟล์ในโครงสร้างพื้นฐานที่ถูกลบไปในชั้นบนอย่างไร
Tim Baverstock

ขอบคุณสิ่งนี้ช่วยฉันแก้ไขคอนเทนเนอร์ MySQL ที่ทำงานใน Docker บน macOS
mazedlx

60

ตอบคำถามของตัวเอง.. ยังหวังคำตอบที่ดีกว่าจากผู้รู้มากกว่า !!

มีความเป็นไปได้ 2 ประการ

1) ระบบการแก้ไขไฟล์บนโฮสต์โดยตรง สิ่งนี้ค่อนข้างอันตรายและมีโอกาสที่จะทำให้คอนเทนเนอร์แตกทั้งหมดอาจเป็นข้อมูลอื่น ๆ ขึ้นอยู่กับสิ่งที่ผิดพลาด

2) การเปลี่ยนสคริปต์เริ่มต้นเป็นสิ่งที่ไม่เคยล้มเหลวเช่นการเริ่มต้นทุบตีทำการแก้ไข / แก้ไขจากนั้นเปลี่ยนโปรแกรมเริ่มต้นอีกครั้งเป็นรายการที่ต้องการ (เช่นโหนดหรืออะไรก็ตามที่เคยเป็นมาก่อน)

รายละเอียดเพิ่มเติม:

1) การใช้

docker ps

เพื่อค้นหาคอนเทนเนอร์ที่กำลังทำงานอยู่หรือ

docker ps -a

เพื่อค้นหาคอนเทนเนอร์ทั้งหมด (รวมถึงคอนเทนเนอร์ที่หยุด) และ

docker inspect (containername)

มองหา "Id" ซึ่งเป็นหนึ่งในค่าแรก

นี่คือส่วนที่มีรายละเอียดการใช้งานและอาจมีการเปลี่ยนแปลงโปรดทราบว่าคอนเทนเนอร์ของคุณอาจสูญหายด้วยวิธีนี้

ไปที่

/var/lib/docker/aufs/diff/9bc343a9..(long container id)/

และคุณจะพบไฟล์ทั้งหมดที่มีการเปลี่ยนแปลงไปยังรูปภาพที่คอนเทนเนอร์ขึ้นอยู่ คุณสามารถเขียนทับไฟล์เพิ่มหรือแก้ไขไฟล์

อีกครั้งฉันจะไม่แนะนำสิ่งนี้

2) ตามที่อธิบายไว้ที่https://stackoverflow.com/a/32353134/586754คุณสามารถค้นหาการกำหนดค่า json config.json ที่เส้นทางเช่น

/var/lib/docker/containers/9bc343a99..(long container id)/config.json

คุณสามารถเปลี่ยน args จากเช่น "nodejs app.js" เป็น "/ bin / bash" ได้ ตอนนี้รีสตาร์ทบริการนักเทียบท่าและเริ่มคอนเทนเนอร์ (คุณจะเห็นว่าตอนนี้เริ่มต้นอย่างถูกต้องแล้ว) คุณควรใช้

docker start -i (containername)

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

docker exec -ti (containername) /bin/bash

นอกจากนี้ docker cp ค่อนข้างมีประโยชน์สำหรับการคัดลอกไฟล์ที่แก้ไขภายนอกคอนเทนเนอร์

นอกจากนี้เราควรถอยกลับไปใช้มาตรการเหล่านั้นก็ต่อเมื่อคอนเทนเนอร์นั้น "สูญหาย" มากหรือน้อยเท่านั้นดังนั้นการเปลี่ยนแปลงใด ๆ จะเป็นการปรับปรุง


ยังคงหวังว่าจะได้คำตอบที่ดีกว่า - ดังนั้นอย่าลังเลที่จะตอบฉันจะย้ายแท็ก "ansered" ด้วย
Andreas Reiff

ฉันใช้วิธีที่สองและต้องรีสตาร์ทบริการนักเทียบท่าเพื่อบังคับให้เขียนทับconfig.jsonไฟล์ทุกครั้งที่แก้ไข
Vitaly Isaev

2
ฉันมี config.v2.json และทุกครั้งที่ฉันเริ่มคอนเทนเนอร์ซอมบี้มันจะย้อนกลับการอัปเดต Path / EntryPoint ของฉันและตายอีกครั้ง ใช้ "docker cp" เพื่ออัปเดตสคริปต์ entrypoint.sh เพื่อเรียกใช้ bash แก้ไข
Curtis Yallop

@CurtisYallop ฉันกำลังประสบสิ่งเดียวกัน คุณแก้ปัญหาอย่างไร
Brett McLain

1
@BrettMcLain ฉันใช้ docker cp แทนที่จะแก้ไขบนโฮสต์ ดังนี้ค้นหาตำแหน่งสคริปต์จุดเข้า: "นักเทียบท่าตรวจสอบ container_name | grep Entry" รับสคริปต์: "docker cp container_name: /entrypoint.sh ./" (แก้ไข) ใส่สคริปต์กลับในคอนเทนเนอร์: "docker cp entrypoint.sh container_name: /entrypoint.sh" คุณสามารถทำให้จุดเข้าใช้งาน bash หรือเรียกใช้ sleep loop เช่น "while:; do sleep 10; done" บรรทัดแรกของสคริปต์ต้องเป็น "#! / bin / bash"
Curtis Yallop

9

คุณสามารถแก้ไขระบบไฟล์คอนเทนเนอร์ได้โดยตรง แต่ฉันไม่รู้ว่าเป็นความคิดที่ดีหรือไม่ ก่อนอื่นคุณต้องหาเส้นทางของไดเร็กทอรีที่ใช้เป็นรูทรันไทม์สำหรับคอนเทนเนอร์ docker container inspect id/nameวิ่ง มองหาคีย์UpperDirในเอาต์พุต JSON

นั่นคือไดเร็กทอรีของคุณ


พบไดเร็กทอรี แต่ไม่มีไฟล์ทั้งหมด
aioobe

เป็น OverlayFS ดังนั้นไฟล์ของคุณต้องอยู่ในไดเร็กทอรีเหล่านั้น
Tejas Sarade

ชื่อไดเรกทอรีอาจแตกต่างจาก "UpperDir" เช่นในกรณีของฉันคือ Source แต่มันได้ผล!
Rajni Kewlani

0

หากคุณกำลังพยายามรีสตาร์ทคอนเทนเนอร์ที่หยุดทำงานและต้องการแก้ไขคอนเทนเนอร์เนื่องจากการกำหนดค่าผิด แต่คอนเทนเนอร์ไม่เริ่มทำงานคุณสามารถดำเนินการต่อไปนี้ได้โดยใช้คำสั่ง "docker cp" (คล้ายกับคำแนะนำก่อนหน้านี้) ขั้นตอนนี้ช่วยให้คุณลบไฟล์และทำการเปลี่ยนแปลงอื่น ๆ ที่จำเป็น ด้วยความโชคดีคุณสามารถข้ามขั้นตอนต่างๆด้านล่างนี้ได้

  1. ใช้นักเทียบท่าตรวจสอบเพื่อค้นหาจุดเข้าใช้งาน (ชื่อ Path ในบางเวอร์ชัน)
  2. สร้างโคลนของการวิ่งโดยใช้นักเทียบท่า
  3. ป้อนโคลนโดยใช้ docker exec -ti bash (if * nix container)
  4. ค้นหาตำแหน่งไฟล์ entrypoint โดยดูว่าโคลนที่จะค้นหา
  5. คัดลอกสคริปต์จุดเข้าใช้งานเก่าโดยใช้ docker cp: ./
  6. แก้ไขหรือสร้างสคริปต์จุดเข้าใหม่เช่น

    #!/bin/bash tail -f /etc/hosts

  7. ตรวจสอบให้แน่ใจว่าสคริปต์มีสิทธิ์ในการดำเนินการ
  8. แทนที่จุดเข้าใช้งานเก่าโดยใช้ docker cp ./:
  9. เริ่มคอนเทนเนอร์เก่าโดยใช้ start
  10. ทำซ้ำขั้นตอนที่ 6-9 จนกระทั่งเริ่ม
  11. แก้ไขปัญหาในคอนเทนเนอร์
  12. คืนค่าจุดเข้าหากจำเป็นและทำซ้ำขั้นตอนที่ 6-9 ตามต้องการ
  13. ลบโคลนออกหากจำเป็น
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.