Docker Compose - Chia sẻ ổ đĩa được đặt tên giữa nhiều vùng chứa


105

Tôi đang sử dụng docker -omp và v3. Tôi đang cố gắn một ổ đĩa trong docker:

./appdata:/appdata

Tôi muốn có cái này dưới dạng một tập và sau đó tham chiếu tập đó từ nhiều vùng chứa. Các tài liệu tham khảo cấu hình khối lượng chỉ chương trình data-volume:như một khối lượng được đặt tên, không có giá trị, vì vậy nó không giống như ở trên.

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

Điều này cho tôi:

LỖI: Trong tệp './docker-compose.yml', khối lượng 'app-volume' phải là một ánh xạ không phải là một chuỗi.

Rõ ràng là tôi biết mình cần thay đổi volumescặp khóa / giá trị, nhưng tôi không chắc chắn cách thay đổi điều này để tôi có thể chia sẻ một khối lượng giữa các dịch vụ.

Tôi cũng đã kiểm tra volumes_fromnhưng điều này hiệu quả chỉ cho phép kế thừa từ các vùng chứa khác. Tôi đã thấy ai đó sử dụng volumes_fromtrên một vùng chứa khác có chứa ánh xạ họ muốn, nhưng vớicommand: true thiết lập để vùng chứa không bao giờ thực sự chạy, điều này đối với tôi dường như chỉ là một vụ hack.

Tôi có thể làm cái này như thế nào?


Lưu ý, tôi làm có làm việc như sau:

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

Nhưng đó chỉ là sự trùng lặp và là điều tôi hy vọng một tập có tên có thể giúp tôi tránh :-)


Bạn có thể tìm câu trả lời trong câu trả lời này: stackoverflow.com/a/49920624
Isen Ng

Câu trả lời:


141

Các tập đã đặt tên có thể được chia sẻ trên các vùng chứa theo cách sau:

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: 

Đây là một cấu hình ví dụ mà tôi sử dụng để hiểu rõ hơn. Tôi đang hiển thị các tệp tĩnh được tạo từ vùng webchứa của mình vào một ổ đĩa đã đặt tên được gọi là ổ đĩa static-contentnày sau đó được vùng nginxchứa đọc và phân phát :

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:

79
Bạn đặt vị trí của static_contenttrên hệ thống tệp máy chủ ở đâu?
Travis Bear

10
Khoảng trắng trong app-volume: location_in_the_containerlà sai.
hasufell

4
Điều gì sẽ xảy ra nếu /usr/src/apptrong vùng nginxchứa và /usr/src/app/publictrong vùng webchứa đều có nội dung gốc, thì cái nào sẽ được sử dụng và tại sao?
jallen0927

2
@TravisBear cho trường hợp sử dụng này (chia sẻ dữ liệu giữa các vùng chứa) không thực sự cần thiết phải có nó trên máy chủ. Ví dụ với dữ liệu tĩnh là tuyệt vời - bạn thực hiện collectstatictrong một container và muốn kết quả có sẵn trong một khác, nhưng bạn không quan tâm đến thư mục máy chủ
The Godfather

7
Câu hỏi của @Kannaj TravisBear là câu hỏi xác định chính xác vấn đề mà tôi thấy khó hiểu nhất. Làm cách nào để bạn có thể chỉ định nguồn của tập đã đặt tên trong tệp soạn? Tôi không muốn để nó cho công cụ docker xác định nơi lưu trữ ổ đĩa đã đặt tên trên máy chủ lưu trữ, tôi muốn chỉ định một đường dẫn.
Ben Collins

33

Điều này giải quyết nó mà không cần sử dụng các tập có tên:

      volumes:
          - ./appdata:/appdata

Vì vậy, nó trông giống như:

services:

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

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

4
Ah, đúng lúc! Tôi đã làm điều này ở trên (xem thay đổi của tôi). Tuy nhiên, có vẻ như chúng tôi vẫn đang sao chép ánh xạ. Nếu tôi sử dụng cái này trên 3 container, nó sẽ lớn. Chúng ta có thể sử dụng các vùng chứa được đặt tên để tránh sự trùng lặp này không?
Jimbo,

Vấn đề là các tập được đặt tên không chỉ là về cú pháp và mã rõ ràng. Nó sẽ tạo một ổ đĩa bên trong thư mục cài đặt dữ liệu docker và bạn sẽ không có các tệp cục bộ của mình ở đó (./appdata). Nó có ích cho bạn không?
Robert

1
Tôi chắc chắn cần ./appdata, đó là những gì tôi đang cố gắng làm. Hãy để câu trả lời này ở đây mặc dù :) +1
Jimbo

2
Điều gì sẽ xảy ra nếu tôi có hai vùng chứa của cùng một hình ảnh, tệp đang tải lên (thông qua dịch vụ tệp tải lên) trong một vùng chứa, nó sẽ có sẵn trong vùng còn lại? nếu không, làm thế nào tôi có thể làm điều đó?
magnoz

0

Các tập có tên docker đã bị xóa bắt đầu từ phiên bản docker-comp 3.

Tuy nhiên, bạn có thể sử dụng các trường mở rộng để tránh trùng lặp nguồn khối lượng và tránh cho bạn lỗi chính tả trong tương lai:

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

LƯU Ý: Tính năng đó khả dụng bắt đầu từ định dạng tệp phiên bản 3.4.


Nếu * services-volume chỉ là một con trỏ đến giá trị được đặt ở trên, điều này trông thật tuyệt vời ... Tôi sẽ phải thử nó.
Jimbo

@Jimbo vâng, đúng vậy, cũng xin lưu ý rằng phiên bản tệp do
docker

2
Các tập được đặt tên, hay còn gọi là trường cấp cao nhất volumes, dường như vẫn là một thứ trong v3 củadocker-compose .
Alex Povel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.