วิธีรวมไฟล์นอกบริบทการสร้างของ Docker หรือไม่


462

ฉันจะรวมไฟล์จากนอกบริบทการสร้างของ Docker โดยใช้คำสั่ง "ADD" ในไฟล์ Docker ได้อย่างไร

จากเอกสารนักเทียบท่า:

เส้นทางต้องอยู่ในบริบทของการสร้าง คุณไม่สามารถเพิ่ม .. / บางสิ่ง / บางสิ่งบางอย่างได้เนื่องจากขั้นตอนแรกของบิลด์บิลเดอร์คือการส่งไดเรกทอรีบริบท (และไดเรกทอรีย่อย) ไปยัง Docker daemon

ฉันไม่ต้องการที่จะปรับโครงสร้างโครงการทั้งหมดของฉันเพียงเพื่อรองรับนักเทียบท่าในเรื่องนี้ ฉันต้องการเก็บไฟล์ Docker ของฉันไว้ในไดเรกทอรีย่อยเดียวกัน

นอกจากนี้ยังปรากฏว่า Docker ยังไม่สนับสนุนการเชื่อมโยง (และอาจไม่เคย): คำสั่ง Dockerfile ADD ไม่ปฏิบัติตาม symlinks บนโฮสต์ # 1676

สิ่งเดียวที่ฉันคิดได้ก็คือการรวมขั้นตอนก่อนสร้างเพื่อคัดลอกไฟล์ลงในบริบทของนักสร้าง Docker (และกำหนดค่าการควบคุมเวอร์ชันของฉันเพื่อละเว้นไฟล์เหล่านั้น) มีวิธีแก้ปัญหาที่ดีกว่าสำหรับที่?


94
นี่เป็นสิ่งที่แย่ที่สุดเกี่ยวกับ Docker จากมุมมองของฉันไม่มีสิ่งเช่น "โครงการนักเทียบท่า" นักเทียบท่าใช้สำหรับโครงการขนส่ง มันเป็นแค่เครื่องมือ ฉันไม่ต้องการที่จะสร้างโครงการทั้งหมดของฉันใหม่เพื่อที่จะสะดวกนักเทียบท่าเพิ่ม .ockerignore ฯลฯ ณ สิ้นวันใครจะรู้ว่านักเทียบท่าจะอยู่ได้นานแค่ไหน มันจะเป็นการดีถ้ามีการแบ่งแยกระหว่างโค้ด (เช่นโครงการเชิงมุม) และวิธีการปรับใช้ใด ๆ (เช่นนักเทียบท่า) ท้ายที่สุดมันไม่มีประโยชน์ที่จะมีไฟล์นักเทียบท่าติดกับทุกอย่าง มันเพิ่งเดินสายไปเรื่อย ๆ เพื่อสร้างภาพ: (
TigerBear

3
ใช่นี่เป็นเรื่องใหญ่ ฉันกำลังเผชิญปัญหาเดียวกันและฉันมีไฟล์ไบนารีขนาดใหญ่กว่า (บีบอัดแล้ว) ที่ฉันไม่ต้องการคัดลอกลงในบริบทการสร้างแต่ละ Docker ฉันต้องการที่จะมาจากที่ตั้งปัจจุบัน (นอกบริบทของนักสร้าง Docker) และฉันไม่ต้องการแมปไดรฟ์ข้อมูลในขณะใช้งานเนื่องจากฉันพยายามคัดลอก / เพิ่มไฟล์ในเวลาบิลด์และเปิดเครื่องรูดและทำสิ่งที่ฉันต้องการเพื่อให้ไบนารีบางอย่างถูกอบลงในภาพ วิธีนี้ทำให้ภาชนะหมุนเร็วขึ้น
jersey bean

ฉันพบโครงสร้างที่ดีและอธิบายรายละเอียดได้ที่stackoverflow.com/a/53298446/433814
Marcello de Sales

1
ปัญหาของตัวสร้างนักเทียบท่าคือแนวคิดที่สร้างขึ้นจาก "บริบท" Dockerfiles ไม่เพียงพอที่จะกำหนด build ยกเว้นว่าวางไว้ภายใต้ไดเร็กทอรีเชิงกลยุทธ์ (บริบทบริบท) คือ "/" เป็นสุดขีดดังนั้นคุณสามารถเข้าถึงเส้นทางใด ๆ (โปรดทราบว่านั่นไม่ใช่สิ่งที่ถูกต้องที่จะทำในโครงการที่มีเหตุผล ทั้ง ... และมันทำให้นักเทียบท่าสร้างช้ามากเพราะนักเทียบท่าสแกนบริบททั้งหมดตั้งแต่เริ่มต้น) คุณสามารถสร้างภาพนักเทียบท่าพร้อมไฟล์ที่จำเป็นทั้งหมดและใช้FROMเพื่อดำเนินการต่อจากที่นั่น ฉันจะไม่เปลี่ยนโครงสร้างโครงการเพื่อรองรับ Docker (หรือเครื่องมือสร้างใด ๆ )
Devis L.

คำตอบ:


411

วิธีที่ดีที่สุดในการหลีกเลี่ยงปัญหานี้คือการระบุ Dockerfile โดยไม่ขึ้นกับบริบทการสร้างโดยใช้ -f

ตัวอย่างเช่นคำสั่งนี้จะให้คำสั่ง ADD เข้าถึงสิ่งใด ๆ ในไดเรกทอรีปัจจุบันของคุณ

docker build -f docker-files/Dockerfile .

อัปเดต : ตอนนี้นักเชื่อมต่ออนุญาตให้มี Dockerfile นอกบริบทการสร้าง (แก้ไขใน 18.03.0-ce, https://github.com/docker/cli/pull/886 ) ดังนั้นคุณสามารถทำอะไรบางอย่างเช่น

docker build -f ../Dockerfile .

8
@Ro คุณใช้dockerfile:คุณสมบัติในbuild:ส่วนในการเขียนไฟล์docs.docker.com/compose/compose-file/#/compose-file-reference
Emerson Farrugia

3
ฉันได้รับ "Dockerfile จะต้องอยู่ในบริบทการสร้าง" - ฉันต้องการมีหนึ่ง Dockerfile ที่สามารถอยู่ด้านล่างบริบทการสร้างปัจจุบัน ในตัวอย่างของคุณคุณมี Dockerfile ภายใน / ด้านล่างบริบทบิลด์ปัจจุบันซึ่งแน่นอนว่าใช้ได้
Alexander Mills

3
ใช่ฉันแค่ต้องการ Dockerfile ที่ใช้ร่วมกันซึ่งสอดคล้องกับไดเรกทอรีย่อยหลายแห่งซึ่งทั้งหมดเป็น "สร้างบริบท"
Alexander Mills

51
สิ่งนี้ช่วยแก้ปัญหา OP ของการต้องการADDไฟล์ที่อยู่นอกไดเรกทอรีบริบทหรือไม่? นั่นคือสิ่งที่ฉันพยายามทำ แต่ฉันไม่คิดว่าการใช้-fทำให้สามารถเพิ่มไฟล์ภายนอกได้
Sridhar Sarnobat

18
ไม่สามารถ upvote นี้พอ .. ในนักเทียบท่า-compose.yml build: context: .., dockerfile: dir/Dockerfileของฉันฉันมี: ตอนนี้บริบทการสร้างของฉันคือไดเรกทอรีหลัก!
Mike Gleason jr Couturier

51

ฉันมักจะพบว่าตัวเองใช้--build-argตัวเลือกสำหรับวัตถุประสงค์นี้ ตัวอย่างเช่นหลังจากใส่ต่อไปนี้ใน Dockerfile:

ARG SSH_KEY
RUN echo "$SSH_KEY" > /root/.ssh/id_rsa

คุณสามารถทำได้:

docker build -t some-app --build-arg SSH_KEY="$(cat ~/file/outside/build/context/id_rsa)" .

แต่ให้สังเกตคำเตือนต่อไปนี้จากเอกสารประกอบ Docker :

คำเตือน: ไม่แนะนำให้ใช้ตัวแปรเวลา build สำหรับการส่งความลับเช่นคีย์ github หนังสือรับรองผู้ใช้ ฯลฯ ค่าตัวแปร Build-time จะปรากฏแก่ผู้ใช้ทุกภาพด้วยคำสั่งประวัตินักเทียบท่า


6
นี่เป็นคำแนะนำที่แย่โดยไม่มีการเตือนล่วงหน้า จากเอกสารของนักเทียบท่า: "คำเตือน: ไม่แนะนำให้ใช้ตัวแปรบิลด์เวลาสำหรับการส่งข้อมูลลับเช่นคีย์ github, ข้อมูลรับรองผู้ใช้ ฯลฯ ค่าตัวแปรบิลด์บิลด์จะปรากฏแก่ผู้ใช้ทุกภาพด้วยคำสั่งประวัตินักเทียบท่า" [1] ในคำอื่น ๆ ตัวอย่างที่ให้ไว้ในตัวอย่างนี้เปิดเผยคีย์ SSH ส่วนตัวในภาพนักเทียบท่า ในบริบทบางอย่างอาจไม่เป็นไร docs.docker.com/engine/reference/builder/#arg
sheldonh

3
ในที่สุดเพื่อเอาชนะปัญหาความปลอดภัยนี้คุณสามารถใช้เทคนิคต่างๆเช่นการบีบอัดหรือการบีบอัดหลายขั้นตอน: vsupalov.com/build-docker-image-clone-private-repo-ssh-key
Jojo

46

บน Linux คุณสามารถติดตั้งไดเร็กทอรีอื่นแทนที่จะเชื่อมโยงเข้ากับไดเร็กทอรีเหล่านั้น

mount --bind olddir newdir

ดู/superuser/842642สำหรับรายละเอียดเพิ่มเติม

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


2
เฉพาะ root เท่านั้นที่สามารถผูกได
เรคทอรี่ได้

28

ฉันใช้เวลาในการพยายามหารูปแบบที่ดีและวิธีการอธิบายสิ่งที่เกิดขึ้นได้ดีขึ้นด้วยการสนับสนุนคุณสมบัตินี้ ฉันรู้ว่าวิธีที่ดีที่สุดในการอธิบายมันเป็นดังนี้ ...

  • Dockerfile: จะเห็นเฉพาะไฟล์ภายใต้พา ธ ที่เกี่ยวข้องของมันเอง
  • บริบท: สถานที่ใน "พื้นที่" ที่ไฟล์ที่คุณต้องการแบ่งปันและ Dockerfile ของคุณจะถูกคัดลอกไป

นี่คือตัวอย่างของ Dockerfile ที่ต้องใช้ไฟล์ที่เรียกว่า start.sh

Dockerfile

มันALWAYSจะโหลดจากเส้นทางสัมพัทธ์โดยมี dir ปัจจุบันของตัวเองเป็นlocalข้อมูลอ้างอิงไปยังเส้นทางที่คุณระบุ

COPY start.sh /runtime/start.sh

ไฟล์

เมื่อพิจารณาจากความคิดนี้เราสามารถคิดของการมีสำเนาหลาย Dockerfiles อาคารสิ่งที่เฉพาะเจาะจง start.shแต่พวกเขาทุกคนสามารถเข้าถึงจำเป็นที่จะต้อง

./all-services/
   /start.sh
   /service-X/Dockerfile
   /service-Y/Dockerfile
   /service-Z/Dockerfile
./docker-compose.yaml

พิจารณาโครงสร้างนี้และไฟล์ด้านบนนี่คือนักเทียบท่า-compose.yml

นักเทียบท่า-compose.yaml

  • ในตัวอย่างนี้sharedบริบท dir ของคุณคือruntimedir
    • เดียวกันจิตแบบที่นี่คิดว่าไฟล์ทั้งหมดที่อยู่ภายใต้ dir contextนี้จะถูกย้ายไปยังที่เรียกว่า
    • ในทำนองเดียวกันเพียงระบุ Dockerfile ที่คุณต้องการคัดลอกไปยัง dir เดียวกัน dockerfileคุณสามารถระบุได้ว่าจะใช้
  • ไดเรกทอรีที่เนื้อหาหลักของคุณตั้งอยู่คือบริบทจริงที่จะตั้ง

docker-compose.ymlเป็นดังนี้

version: "3.3"
services:

  service-A
    build:
      context: ./all-service
      dockerfile: ./service-A/Dockerfile

  service-B
    build:
      context: ./all-service
      dockerfile: ./service-B/Dockerfile

  service-C
    build:
      context: ./all-service
      dockerfile: ./service-C/Dockerfile
  • all-serviceถูกตั้งค่าเป็นบริบทไฟล์ที่ใช้ร่วมกันstart.shจะถูกคัดลอกที่นั่นรวมถึง Dockerfile ที่ระบุโดยแต่ละdockerfileไฟล์
  • แต่ละคนจะได้รับการสร้างในแบบของตัวเองแบ่งปันไฟล์เริ่มต้น

ไชโย!


1
จุดของคุณบน Dockerfile ไม่เป็นความจริงสมบูรณ์เป็นแฉกโดยคำตอบที่ได้รับการยอมรับถ้าคุณอยู่ในลำดับชั้นโฟลเดอร์a/b/cแล้วใช่ทำงานdocker build .ในจะไม่อนุญาตให้คุณเข้าถึงc ../file-in-bแต่ฉันคิดว่าการเข้าใจผิดโดยทั่วไปในเรื่องนี้ (หรืออย่างน้อยฉันเคยเป็น) คือบริบทถูกกำหนดโดยสถานที่ที่ระบุโดยอาร์กิวเมนต์แรกของคำสั่งการสร้างไม่ใช่ตำแหน่งของ Dockerfile ดังนั้นตามที่ระบุไว้ในคำตอบที่ยอมรับ: จากa: docker build -f a/b/c/Dockerfile . หมายความว่าใน Dockerfile .ตอนนี้เป็นโฟลเดอร์a
β.εηοιτ.βε

1
การอ้างอิงจากเอกสาร Dockerfile: เส้นทางของไฟล์และไดเรกทอรีจะถูกตีความว่าสัมพันธ์กับแหล่งที่มาของบริบทของบิลด์
Nishant George Agrwal

18

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

ฉันชอบที่จะสร้างจากแหล่งที่ควบคุมเวอร์ชัน - เช่นตัวสร้างนักเทียบท่า- สิ่งที่http://my.git.org/repo - มิฉะนั้นฉันกำลังสร้างจากสถานที่สุ่มด้วยไฟล์สุ่ม

พื้นฐานไม่มี .... - SvenDowideit, Docker Inc

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

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


ทำไมต้องใช้นักเทียบท่าเลยล่ะ?
lscoughlin

11

ฉันเชื่อว่าวิธีแก้ปัญหาที่ง่ายกว่าคือการเปลี่ยน 'บริบท' เอง

ตัวอย่างเช่นแทนที่จะให้:

docker build -t hello-demo-app .

ซึ่งกำหนดไดเรกทอรีปัจจุบันเป็นบริบทสมมติว่าคุณต้องการให้ไดเรกทอรีหลักเป็นบริบทเพียงใช้:

docker build -t hello-demo-app ..

6
ฉันคิดว่าตัวแบ่งนี้. dockerignore: - \
NullVoxPopuli

ฉันเลิกใช้. dockerignore และสร้างโฟลเดอร์นักเทียบท่าที่จัดการไฟล์ Makefile ที่มีเฉพาะไฟล์ที่จำเป็นสำหรับการสร้างบริบท ... ฉันเพียงแค่ต้องโทรmake buildและมันจะดึงไฟล์ทั้งหมดที่จำเป็นถ้าพวกมันได้รับการปรับปรุงแล้วมันเรียกนักสร้าง Docker ที่เหมาะสม ... ฉันต้องทำงานพิเศษ แต่ทำงานได้อย่างไร้ที่ติเพราะฉันสามารถควบคุมได้เต็มที่
Sahsahae

5

คุณยังสามารถสร้าง tarball ในสิ่งที่ภาพต้องการก่อนและใช้มันเป็นบริบทของคุณ

https://docs.docker.com/engine/reference/commandline/build/#/tarball-contexts


สุดยอดเคล็ดลับ! ผมค้นพบคุณสามารถให้อาหารแม้กระทั่งนักเทียบท่าสร้าง tarball เป็นบริบทใน tar zc /dir1 /dir2 |docker build -stdin: สิ่งนี้มีประโยชน์มากในกรณีของฉัน
Tore Olsen

3

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

คุณไม่ต้องใช้นักแต่งเพลงเพื่อทำสิ่งนี้ แต่มันทำให้ชีวิตง่ายขึ้นเล็กน้อย

# docker-compose.yml

version: '3'
  services:
    stage:
      image: alpine
      volumes:
        - /host/machine/path:/tmp/container/path
      command: bash -c "cp -r /tmp/container/path /final/container/path"
    setup:
      image: stage
# setup.sh

# Start "stage" service
docker-compose up stage

# Commit changes to an image named "stage"
docker commit $(docker-compose ps -q stage) stage

# Start setup service off of stage image
docker-compose up setup

1

ฉันมีปัญหาเดียวกันกับโครงการและไฟล์ข้อมูลบางอย่างที่ฉันไม่สามารถย้ายภายในบริบท repo ด้วยเหตุผล HIPPA ฉันลงเอยด้วย 2 Dockerfiles หนึ่งสร้างแอปพลิเคชันหลักโดยไม่มีสิ่งที่ฉันต้องการนอกคอนเทนเนอร์และเผยแพร่ไปยัง repo ภายใน จากนั้น dockerfile ตัวที่สองจะดึงอิมเมจนั้นและเพิ่มข้อมูลและสร้างอิมเมจใหม่ซึ่งจะถูกปรับใช้และไม่เคยเก็บไว้ที่ใดเลย ไม่เหมาะ แต่ใช้เพื่อวัตถุประสงค์ในการป้องกันข้อมูลที่อ่อนไหวของ repo


1

วิธีแก้ปัญหาง่าย ๆ คือการเมานต์โวลุ่ม (โดยใช้แฟล็ก -v หรือ --mount) กับคอนเทนเนอร์เมื่อคุณรันและเข้าถึงไฟล์ด้วยวิธีนั้น

ตัวอย่าง:

docker run -v /path/to/file/on/host:/desired/path/to/file/in/container/ image_name

รับชมเพิ่มเติมได้ที่: https://docs.docker.com/storage/volumes/


โปรดทราบว่าจะใช้งานได้เฉพาะในกรณีที่ปริมาณการพึ่งพารันไทม์ สำหรับการสร้างเวลาขึ้นต่อdocker runกันสายเกินไป
3735633

1

ในฐานะที่ได้อธิบายไว้ในนี้ปัญหา GitHubสร้างจริงที่เกิดขึ้นใน/tmp/docker-12345เพื่อให้ทางญาติเหมือนจะสัมพันธ์กับ../relative-add/some-file /tmp/docker-12345มันจะทำการค้นหา/tmp/relative-add/some-fileซึ่งจะปรากฏในข้อความแสดงข้อผิดพลาด *

ไม่อนุญาตให้รวมไฟล์จากนอกไดเรกทอรีการสร้างดังนั้นผลลัพธ์นี้ในข้อความ "พา ธ ต้องห้าม"


0

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

./Code/Repo1
./Code/Repo2
...

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

สถานการณ์ตัวอย่างอาจเป็นได้ว่าทีมอื่นรักษาสกีมาฐานข้อมูลRepo1และรหัสทีมของคุณRepo2ขึ้นอยู่กับสิ่งนี้ คุณต้องการเชื่อมโยงการพึ่งพานี้กับข้อมูลเมล็ดพันธุ์บางส่วนของคุณเองโดยไม่ต้องกังวลเกี่ยวกับการเปลี่ยนแปลงสคีมาหรือสร้างความเสียหายให้กับที่เก็บของทีมอื่น (ขึ้นอยู่กับการเปลี่ยนแปลงที่คุณอาจยังต้องเปลี่ยนสคริปต์ข้อมูลเมล็ดของคุณ) ได้รับการแก้ไขปัญหาของงานสร้างที่ยาวนาน:

สร้างสคริปต์ sh (หรือ ps1) ./Code/Repo2เพื่อคัดลอกไฟล์ที่คุณต้องการและเรียกใช้คำสั่งนักเทียบท่าที่คุณต้องการเช่น:

#!/bin/bash
rm -r ./db/schema
mkdir ./db/schema

cp  -r ../Repo1/db/schema ./db/schema

docker-compose -f docker-compose.yml down
docker container prune -f
docker-compose -f docker-compose.yml up --build

ในไฟล์นักเทียบท่าให้ตั้งค่าบริบทเป็นRepo2รูทและใช้เนื้อหาของ./db/schemaไดเรกทอรีในไฟล์ dockerfile ของคุณโดยไม่ต้องกังวลเกี่ยวกับพา ธ โปรดจำไว้ว่าคุณจะเสี่ยงต่อการกระทำผิดพลาดกับไดเรกทอรีนี้เพื่อควบคุมแหล่งข้อมูล แต่การดำเนินการล้างข้อมูลสคริปต์ควรง่ายพอ


0

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

ดังนั้นฉันจึงไม่สามารถระบุไฟล์นี้ได้โดยตรง แต่จะวางลงในตัวสร้างนักเทียบท่าเช่นนี้:

sed "s/%email_address%/$EMAIL_ADDRESS/;" ./Dockerfile | docker build -t katzda/bookings:latest . -f -;

แต่เนื่องจากไปป์COPYคำสั่งไม่ทำงาน แต่วิธีดังกล่าวข้างต้นแก้ไขได้โดย-f -(ไม่ได้บอกไฟล์อย่างชัดเจน) การทำ-โดยไม่มี-fแฟล็กบริบทและ Dockerfile ไม่ได้จัดเตรียมไว้ซึ่งเป็นข้อแม้


0

เคล็ดลับคือการรับรู้ว่าคุณสามารถระบุบริบทในคำสั่งการสร้างเพื่อรวมไฟล์จากไดเรกทอรีแม่ถ้าคุณระบุเส้นทาง Docker ฉันจะเปลี่ยน Dockerfile ของฉันให้มีลักษณะดังนี้:

...
COPY ./ /dest/
...

จากนั้นคำสั่ง build ของฉันสามารถมีลักษณะเช่นนี้:

docker built -t TAG -f DOCKER_FILE_PATH CONTEXT

จากไดเรกทอรีโครงการ

docker built -t username/project[:tag] -f ./docker/Dockerfile .

จากโครงการ / นักเทียบท่า

docker built -t username/project[:tag] -f ./docker/Dockerfile ..
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.