Docker Compose - แชร์ไดรฟ์ข้อมูลที่มีชื่อระหว่างหลายคอนเทนเนอร์


118

ฉันใช้ Docker-compose และ v3.0 ฉันกำลังพยายามเพิ่มโวลุ่มในนักเทียบท่า:

./appdata:/appdata

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

services:

    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes:
            - app-volume

    php:
        build: ./php/
        expose:
            - 9000
        volumes:
            - app-volume

volumes:
     app-volume: ./appdata:/appdata

สิ่งนี้ทำให้ฉัน:

ข้อผิดพลาด: ในไฟล์ "./docker-compose.yml", volume "app-volume" ต้องเป็นการแมปที่ไม่ใช่สตริง

เห็นได้ชัดว่าฉันรู้ว่าฉันจำเป็นต้องเปลี่ยนvolumesคู่คีย์ / ค่า แต่ฉันไม่แน่ใจว่าจะเปลี่ยนอย่างไรจึงจะสามารถแชร์ระดับเสียงระหว่างบริการได้

ฉันได้ตรวจสอบแล้วvolumes_fromแต่สิ่งนี้อนุญาตให้สืบทอดจากคอนเทนเนอร์อื่นได้อย่างมีประสิทธิภาพ ฉันเคยเห็นใครบางคนใช้volumes_fromกับคอนเทนเนอร์อื่นที่มีการทำแผนที่ที่พวกเขาต้องการ แต่ด้วยการcommand: trueตั้งค่าเพื่อไม่ให้คอนเทนเนอร์ทำงานจริงซึ่งสำหรับฉันดูเหมือนว่าเป็นการแฮ็ก

ฉันจะทำเช่นนี้ได้อย่างไร?


หมายเหตุผมไม่ได้มีการทำงานต่อไปนี้:

nginx:
    volumes:
        - ./appdata:/appdata
php:
    volumes:
        - ./appdata:/appdata

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


คุณสามารถหาคำตอบได้ในคำตอบนี้: stackoverflow.com/a/49920624
Isen Ng

คำตอบ:


155

ไดรฟ์ข้อมูลที่ระบุชื่อสามารถแชร์ข้ามคอนเทนเนอร์ได้ด้วยวิธีต่อไปนี้:

services:
    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes:
            - app-volume:location_in_the_container

    php:
        build: ./php/
        expose:
            - 9000
        volumes:
            - app-volume:location_in_the_container

volumes:
     app-volume: 

นี่คือตัวอย่างการกำหนดค่าที่ฉันใช้เพื่อความเข้าใจที่ดีขึ้น ฉันกำลังเปิดเผยไฟล์คงที่ที่สร้างจากwebคอนเทนเนอร์ของฉันไปยังไดรฟ์ข้อมูลที่มีชื่อstatic-contentซึ่งเรียกว่าคอนเทนเนอร์จะอ่านและให้บริการnginx:

services:
  nginx:
    container_name: nginx
    build: ./nginx/

    volumes:
      - static-content:/usr/src/app

  web:
    container_name: web
    env_file: .env
    volumes:
      - static-content:/usr/src/app/public
    environment:
      - NODE_ENV=production

    command: npm run package

volumes:
  static-content:

83
คุณตั้งตำแหน่งของstatic_contentระบบไฟล์โฮสต์ไว้ที่ใด
Travis Bear

10
ช่องว่างในapp-volume: location_in_the_containerไม่ถูกต้อง
hasufell

6
จะเกิดอะไรขึ้นถ้า/usr/src/appในnginxคอนเทนเนอร์และ/usr/src/app/publicในwebคอนเทนเนอร์ทั้งสองมีเนื้อหาที่เป็นต้นฉบับจะใช้อันใดและเพราะเหตุใด
jallen0927

2
@TravisBear สำหรับกรณีการใช้งานนี้ (การแชร์ข้อมูลระหว่างคอนเทนเนอร์) ไม่จำเป็นต้องมีบนโฮสต์ ตัวอย่างที่มีข้อมูลแบบคงที่นั้นยอดเยี่ยม - คุณดำเนินการcollectstaticในคอนเทนเนอร์หนึ่งและต้องการให้ผลลัพธ์พร้อมใช้งานในอีกคอนเทนเนอร์หนึ่ง แต่คุณไม่สนใจโฟลเดอร์โฮสต์
The Godfather

8
คำถามของ @Kannaj TravisBear เป็นคำถามที่ระบุปัญหาที่ฉันพบว่าสับสนที่สุดอย่างถูกต้อง คุณสามารถระบุที่มาของไดรฟ์ข้อมูลที่ตั้งชื่อได้อย่างไร ฉันไม่ต้องการปล่อยให้มันขึ้นอยู่กับเครื่องมือเทียบท่าเพื่อกำหนดตำแหน่งที่จะเก็บไดรฟ์ข้อมูลที่ตั้งชื่อไว้บนโฮสต์ฉันต้องการระบุเส้นทาง
Ben Collins

35

วิธีนี้แก้ได้โดยไม่ต้องใช้ไดรฟ์ข้อมูลที่ตั้งชื่อ:

      volumes:
          - ./appdata:/appdata

ดูเหมือนว่า:

services:

  nginx:
      build: ./nginx/
      ports:
          - 80:80
      links:
          - php
      volumes:
          - ./appdata:/appdata

  php:
      build: ./php/
      expose:
          - 9000
      volumes:
          - ./appdata:/appdata

4
อ้าเวลาดี! ฉันทำสิ่งนี้ด้านบน (ดูการเปลี่ยนแปลงของฉัน) อย่างไรก็ตามดูเหมือนว่าเรากำลังทำแผนที่ซ้ำอยู่ ถ้าฉันใช้มากกว่า 3 คอนเทนเนอร์มันจะใหญ่ เราสามารถใช้คอนเทนเนอร์ที่มีชื่อเพื่อหลีกเลี่ยงการทำซ้ำนี้ได้หรือไม่?
Jimbo

สิ่งนี้ก็คือไดรฟ์ข้อมูลที่ตั้งชื่อไม่ได้เป็นเพียงสิ่งที่เกี่ยวกับไวยากรณ์และรหัสที่ชัดเจนเท่านั้น มันจะสร้างไดรฟ์ข้อมูลภายในไดเร็กทอรีการติดตั้งข้อมูลนักเทียบท่าและคุณจะไม่มีไฟล์ในเครื่องของคุณอยู่ที่นั่น (./appdata) มันมีประโยชน์สำหรับคุณหรือไม่?
Robert

2
ฉันต้องการสิ่ง./appdataนั้นอย่างแน่นอนนั่นคือสิ่งที่ฉันพยายามทำ ทิ้งคำตอบไว้ที่นี่ :) +1
Jimbo

3
จะเกิดอะไรขึ้นถ้าฉันมีสองคอนเทนเนอร์ที่มีรูปภาพเดียวกันการอัปโหลดไฟล์ (ผ่านบริการไฟล์อัปโหลด) ในคอนเทนเนอร์หนึ่งคอนเทนเนอร์นั้นจะพร้อมใช้งานในอีกคอนเทนเนอร์หนึ่ง ถ้าไม่ฉันจะทำอย่างไร
magnoz

5

ไดรฟ์ข้อมูลที่ชื่อนักเทียบท่าถูกลบออกโดยเริ่มจากเวอร์ชันนักเทียบท่าเขียน 3

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

version: '3.5'

x-services-volume:
  &services-volume
  type: bind
  source: ./appdata
  target: /appdata

services:

    nginx:
        build: ./nginx/
        ports:
            - 80:80
        links:
            - php
        volumes: *services-volume

    php:
        build: ./php/
        expose:
            - 9000
        # Use same way as for nginx if target override not needed.
        volumes:
            - <<: *services-volume
            target: /opt/target-override

หมายเหตุ:คุณสมบัตินั้นพร้อมใช้งานตั้งแต่รูปแบบไฟล์เวอร์ชัน 3.4


หาก * services-volume เป็นเพียงตัวชี้ไปยังค่าที่ตั้งไว้ด้านบนสิ่งนี้จะดูดีมาก ... ฉันจะต้องลองดู
Jimbo

@ Jimbo ใช่แล้วโปรดทราบด้วยว่าเวอร์ชันของไฟล์
docker

2
ไดรฟ์ข้อมูลที่มีชื่อหรือที่เรียกว่าvolumesฟิลด์ระดับบนสุดดูเหมือนจะยังคงเป็นสิ่งที่อยู่ในv3 ของdocker-compose .
Alex Povel

ฉันลองใช้วิธีนี้เพื่อแบ่งปันข้อมูลระหว่างคอนเทนเนอร์สามคอนเทนเนอร์และโฮสต์ ในกรณีของฉันโครงสร้างโฟลเดอร์ในคอนเทนเนอร์เท่ากัน ดูเหมือนว่าจะได้ผลตามที่คาดไว้ สิ่งที่ฉันไม่ได้รับคือคอนเทนเนอร์ใด (หรือโฮสต์) ที่มีสิทธิพิเศษเมื่อเริ่มต้นอีกครั้ง สิ่งที่ฉันหมายถึง: เมื่อทำการเขียนนักเทียบท่าระบบไฟล์ภายในของแต่ละคอนเทนเนอร์จะถูกบันทึกไว้ที่ใดที่หนึ่งภายใน เมื่อตอนนี้ฉันเปลี่ยนข้อมูลในโฟลเดอร์โฮสต์และทำการเทียบท่าอีกครั้ง: อะไรคือกฎสำหรับเนื้อหาในโฟลเดอร์ที่แชร์? ข้อมูลจากโฮสต์จะเขียนทับข้อมูลที่บันทึกไว้ภายในหรือไม่ขอบคุณ!
and0r

1
@ and0r แชร์โฟลเดอร์ลองนึกภาพ Google ไดรฟ์และผู้ใช้จริง + โฟลเดอร์ที่แชร์ถ้ามีคนลบไฟล์ในโฟลเดอร์นั้นกว่าที่จะหายไปสำหรับผู้ใช้ที่เหลือ
Andriy Ivaneyko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.