ฉันจะเมานต์ไดเร็กทอรีโฮสต์เป็นไดรฟ์ข้อมูลใน Docker compose ได้อย่างไร


127

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

ฉันมีสองคอนเทนเนอร์ที่กำหนดไว้ในdocker-compose.yml:

node:
    build: ./node
    links:
        - redis
    ports:
        - "8080"
    env_file:
        - node-app.env

redis:
    image: redis
    ports:
        - "6379"

ฉันได้มาถึงจุดในnodeDockerfile ของแอปที่ฉันเพิ่มโวลุ่ม แต่ฉันจะเมานต์ไดเร็กทอรีของโฮสต์ในไดรฟ์ข้อมูลได้อย่างไรเพื่อให้การแก้ไขโค้ดทั้งหมดของฉันปรากฏในคอนเทนเนอร์

นี่คือ Dockerfile ปัจจุบันของฉัน:

# Set the base image to Ubuntu
FROM    node:boron

# File Author / Maintainer
MAINTAINER Amin Shah Gilani <amin@gilani.me>

# Install nodemon
RUN npm install -g nodemon

# Add a /app volume
VOLUME ["/app"]

# TODO: link the current . to /app

# Define working directory
WORKDIR /app

# Run npm install
RUN npm install

# Expose port
EXPOSE  8080

# Run app using nodemon
CMD ["nodemon", "/app/app.js"]

โครงการของฉันมีลักษณะดังนี้:

/
- docker-compose.yml
- node-app.env
- node/
  - app.js
  - Dockerfile.js

คำตอบ:


137

ตรวจสอบเอกสารของพวกเขา

จากรูปลักษณ์ของมันคุณสามารถทำสิ่งต่อไปนี้บน docker-compose.yml ของคุณ

volumes:
    - ./:/app

2
พยายามแล้วก็ไม่ได้ผล:Error: Cannot find module '/data/app.js'
Amin Shah Gilani

2
รอสักครู่ .. VOLUME และ WORKDIR /app/ของคุณชี้ว่าเหตุใด CMD ของคุณจึงชี้ไปที่/data
jkris

1
นั่นเป็นข้อผิดพลาด! ขอบคุณที่จับได้! แก้ไขแล้วและตอนนี้ฉันเข้าใจError: Cannot find module 'express'แล้วฉันจะลองทำบางอย่างในตอนนี้
Amin Shah Gilani

3
สำหรับคอนเทนเนอร์ windows คุณจะต้องการเส้นทางสไตล์ windows เช่น- .:c:/appนี้ (สิ่งนี้ทำให้ฉันสะดุด)
JohnnyFun

88

มีไม่กี่ตัวเลือก

ไวยากรณ์สั้น ๆ

host : guestคุณสามารถใช้รูปแบบดังต่อไปนี้:

volumes:
  # Just specify a path and let the Engine create a volume
  - /var/lib/mysql

  # Specify an absolute path mapping
  - /opt/data:/var/lib/mysql

  # Path on the host, relative to the Compose file
  - ./cache:/tmp/cache

  # User-relative path
  - ~/configs:/etc/configs/:ro

  # Named volume
  - datavolume:/var/lib/mysql

ไวยากรณ์แบบยาว

ในขณะที่ docker-compose v3.2 คุณสามารถใช้ไวยากรณ์แบบยาวซึ่งอนุญาตให้กำหนดค่าฟิลด์เพิ่มเติมที่สามารถแสดงในรูปแบบสั้น ๆ เช่นmount type(volume, bind หรือ tmpfs) และread_only.

version: "3.2"
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - type: volume
        source: mydata
        target: /data
        volume:
          nocopy: true
      - type: bind
        source: ./static
        target: /opt/app/static

networks:
  webnet:

volumes:
  mydata:

ตรวจสอบhttps://docs.docker.com/compose/compose-file/#long-syntax-3สำหรับข้อมูลเพิ่มเติม


22

หากคุณต้องการเมานต์ไดเร็กทอรีโฮสต์เฉพาะ ( /disk1/prometheus-dataในตัวอย่างต่อไปนี้) เป็นโวลุ่มในvolumesส่วนของไฟล์ Docker Compose YAML คุณสามารถทำได้ดังต่อไปนี้เช่น:

version: '3'

services:
  prometheus:
    image: prom/prometheus
    volumes:
      - prometheus-data:/prometheus

volumes:
  prometheus-data:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /disk1/prometheus-data

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

Dockerfile

...
VOLUME ["/prometheus"]
...

refs:


สิ่งนี้ได้ผล ขอบคุณ เอกสารสำหรับlocalประเภทไดรเวอร์อยู่ที่ไหน?
mmell

@mmell เอกสารประกอบเป็นลิงก์อ้างอิงแรก ( docs.docker.com/compose/compose-file/#driver ) อ่าน: ระบุว่าควรใช้ไดรฟ์ข้อมูลใดสำหรับไดรฟ์ข้อมูลนี้ ค่าเริ่มต้นของไดรเวอร์ใด ๆ ก็ตามที่ Docker Engine ได้รับการกำหนดค่าให้ใช้ซึ่งในกรณีส่วนใหญ่คือlocal
Yuci

1
@mmell สามารถดูรายละเอียดเพิ่มเติมได้จากคำถามนี้stackoverflow.com/questions/42195334/…
Yuci

คุณรู้ได้อย่างไรว่าการตั้งค่าในdriver_opts: o: bind type: none?
mmell

1
@mmell โดยทั่วไปตัวเลือกเหล่านี้จะขึ้นอยู่กับคนขับและในตัวlocalคนขับรถบน Linux ยอมรับตัวเลือกคล้ายกับลินุกซ์ติดคำสั่ง: man7.org/linux/man-pages/man8/mount.8.html สามารถดูการสนทนาเพิ่มเติมได้ที่github.com/moby/moby/issues/19990#issuecomment-248955005และstackoverflow.com/questions/35841241/…
Yuci

9

มันเป็นสองสิ่ง:

ฉันเพิ่มระดับเสียงในdocker-compose.yml:

node:
    volumes:
        - ./node:/app

ฉันย้ายnpm install && nodemon app.jsชิ้นส่วนเป็นCMDเพราะRUNเพิ่มสิ่งต่าง ๆ ใน Union File System และโวลุ่มของฉันไม่ได้เป็นส่วนหนึ่งของ UFS

# Set the base image to Ubuntu
FROM    node:boron

# File Author / Maintainer
MAINTAINER Amin Shah Gilani <amin@gilani.me>

# Install nodemon
RUN npm install -g nodemon

# Add a /app volume
VOLUME ["/app"]

# Define working directory
WORKDIR /app

# Expose port
EXPOSE  8080

# Run npm install
CMD npm install && nodemon app.js

2

เราต้องสร้างวอลุ่มนักเทียบท่าของคุณเองที่แมปกับไดเร็กทอรีโฮสต์ก่อนที่เราจะพูดถึงในdocker-compose.ymlเป็นภายนอก

1. สร้างไดรฟ์ข้อมูลชื่อหุ้น

docker volume create --driver local \
    --opt type=none \
    --opt device=/home/mukundhan/share \
    --opt o=bind share

2. ใช้มันในนักเทียบท่าของคุณ

version: "3"

volumes:
  share:
    external: true

services:
  workstation:
    container_name: "workstation"
    image: "ubuntu"
    stdin_open: true
    tty: true
    volumes:
      - share:/share:consistent
      - ./source:/source:consistent
    working_dir: /source
    ipc: host
    privileged: true
    shm_size: '2gb'
  db:
    container_name: "db"
    image: "ubuntu"
    stdin_open: true
    tty: true
    volumes:
      - share:/share:consistent
    working_dir: /source
    ipc: host

ด้วยวิธีนี้เราสามารถแชร์ไดเร็กทอรีเดียวกันกับบริการมากมายที่ทำงานในคอนเทนเนอร์ที่แตกต่างกัน


ทำไมต้องมี ipc: host?
Vahid Noormofidi

ที่จำเป็นก็ต่อเมื่อเราต้องการเชื่อมโยงเครือข่ายเข้ากับโฮสต์เท่านั้น
Mukundhan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.