Làm cách nào tôi có thể thêm âm lượng vào bộ chứa Docker hiện tại?


297

Tôi có một bộ chứa Docker mà tôi đã tạo đơn giản bằng cách cài đặt Docker trên Ubuntu và thực hiện:

sudo docker run -i -t ubuntu /bin/bash

Tôi ngay lập tức bắt đầu cài đặt Java và một số công cụ khác, dành thời gian cho nó và dừng container bằng cách

exit

Sau đó, tôi muốn thêm một tập và nhận ra rằng điều này không đơn giản như tôi nghĩ nó sẽ xảy ra. Nếu tôi sử dụng sudo docker -v /somedir run ...thì tôi sẽ có một thùng chứa mới, vì vậy tôi đã cài đặt Java và làm những gì tôi đã làm trước đây chỉ để đến một thùng chứa có âm lượng được gắn.

Tất cả các tài liệu về việc gắn một thư mục từ máy chủ dường như ngụ ý rằng việc gắn một âm lượng là điều có thể được thực hiện khi tạo một thùng chứa. Vì vậy, lựa chọn duy nhất tôi phải tránh để cấu hình lại một container mới từ đầu là cam kết container hiện có vào một kho lưu trữ và sử dụng nó làm cơ sở của một container mới trong khi lắp âm lượng.

Đây thực sự là cách duy nhất để thêm một khối lượng vào một container hiện có?


1
Sau các Container, chúng trở thành một phần không thể thiếu của các Lập trình viên và do đó những câu hỏi như vậy được đăng thường xuyên hơn ở đây. Các câu hỏi được đăng ở đây bằng cách sử dụng dockerthẻ là 34k + , nhiều hơn so với hai trang web stackoverflow.com/questions/tagged/docker
MA Hossain Tonu 7/218

Câu trả lời:


394

Bạn có thể cam kết bộ chứa hiện tại của mình (đó là tạo một hình ảnh mới từ các thay đổi của bộ chứa) và sau đó chạy nó với các giá trị gắn kết mới của bạn.

Thí dụ:

$ docker ps  -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS                          PORTS               NAMES
    5a8f89adeead        ubuntu:14.04          "/bin/bash"              About a minute ago   Exited (0) About a minute ago                       agitated_newton

$ docker commit 5a8f89adeead newimagename

$ docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash

Nếu mọi thứ đều ổn, hãy dừng container cũ của bạn và sử dụng cái mới này.

Đó là nó :)


22
Và nếu bạn cần container mới để lấy tên cũ vì một số lý do, hãy sử dụng đổi tên docker sau khi xóa tên cũ.
Dirk

10
chỉ muốn chỉ ra rằng ở trên nơi bạn đề cập newnameofcontainerrằng cái này có lẽ nên được đặt tên new_image_name- bởi vì docker committạo ra một hình ảnh mới trên hệ thống của bạn. Sau đó, khi bạn thực hiện, docker runbạn thực sự sử dụng tên của hình ảnh mà bạn muốn chạy một container mới. Các công việc trên nhưng chỉ muốn làm rõ cho những người khác rằng trình giữ chỗ newnameofcontainer ở trên thực sự là tên cho một hình ảnh mới. cảm ơn! câu trả lời tuyệt vời. ồ, bạn có thể thấy hình ảnh mới được tạo từ lệnh cam kết docker image ls
docker

3
Thực tế, bạn không cần phải cam kết một container mới nếu bạn muốn bắt đầu từ một hình ảnh. Chỉ docker run -v /srv/a:/tmp ubuntu:14.04là tốt
YongHao Hu

Tôi đã có một container chạy với tất cả các tập tin. Nếu phương thức trên tạo ra container mới, tôi không thể xây dựng mọi thứ một lần nữa. Có cách nào tôi có thể tránh điều này và gắn kết mà không phải tạo container hoặc hình ảnh mới không?
dhinar

Điều này sẽ giữ ánh xạ khối lượng cũ từ container cũ hay tôi cũng nên khai báo lại chúng với container mới?
thebeancount

79

Chúng tôi không có cách nào để thêm âm lượng trong việc chạy container, nhưng để đạt được mục tiêu này, bạn có thể sử dụng các lệnh dưới đây:

Sao chép tệp / thư mục giữa một vùng chứa và hệ thống tệp cục bộ: -

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-

docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

Để tham khảo xem:

https://docs.docker.com/engine/reference/commandline/cp/


47
Có một sự khác biệt lớn giữa việc gắn một ổ đĩa và sao chép các tập tin vào và từ một thùng chứa ...
Jules

31
Dù sao nó đã giúp tôi. Tôi không biết lệnh 'docker cp' và đã cố gắng đạt được chính xác điều này - sao chép các tệp từ khi chạy container sang máy chủ.
Ivan

3
nó không phải là một thú cưỡi, nhưng thật tiện dụng để mang các tập tin trở lại và xáo trộn giữa container và máy chủ cục bộ.
linehrr

Mặc dù điều này không giải quyết được vấn đề sao chép nội dung của container cục bộ, nhưng điều này không tương đương với việc gắn một khối lượng và không nên được coi là một giải pháp thay thế. Cụ thể, nhân rộng phải được quản lý bởi người dùng và dữ liệu hiện tồn tại ở hai nơi.
Sebastian Gaweda

1
Tôi không hiểu tại sao rất nhiều phiếu bầu, đây là một câu trả lời rất sai cho câu hỏi được hỏi.
João Matos

33

Tôi đã gắn thành công /home/<user-name>thư mục của máy chủ lưu trữ vào /mntthư mục của thùng chứa (không chạy) hiện có. Bạn có thể làm theo cách sau:

  1. Mở tệp cấu hình tương ứng với vùng chứa bị dừng, có thể tìm thấy tại /var/lib/docker/containers/99d...1fb/config.v2.json(có thể config.jsondành cho các phiên bản cũ hơn của docker).

  2. Tìm MountPointsphần, đó là trống trong trường hợp của tôi : "MountPoints":{}. Tiếp theo thay thế nội dung bằng một cái gì đó như thế này (bạn có thể sao chép nội dung phù hợp từ một thùng chứa khác với cài đặt phù hợp):

"MountPoints":{"/mnt":{"Source":"/home/<user-name>","Destination":"/mnt","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/home/<user-name>","Target":"/mnt"},"SkipMountpointCreation":false}}

hoặc giống nhau (được định dạng):

  "MountPoints": {
    "/mnt": {
      "Source": "/home/<user-name>",
      "Destination": "/mnt",
      "RW": true,
      "Name": "",
      "Driver": "",
      "Type": "bind",
      "Propagation": "rprivate",
      "Spec": {
        "Type": "bind",
        "Source": "/home/<user-name>",
        "Target": "/mnt"
      },
      "SkipMountpointCreation": false
    }
  }
  1. Khởi động lại dịch vụ docker: service docker restart

Điều này hoạt động với tôi với Ubuntu 18.04.1 và Docker 18.09.0


3
Cảm ơn câu trả lời. Bước 3 là rất quan trọng. Tôi cũng sẽ nói thêm rằng tốt hơn hết là dừng container docker trước khi viết.
buzypi

7
Đây là câu trả lời tốt nhất vì nó hoàn toàn bảo tồn container hiện có. Đây là những gì tôi đã làm: 1. Dừng công cụ docker: systemctl stop docker.service2. Chỉnh sửa config.v2.json: vim <(jq . /var/lib/docker/containers/<container-ID>/config.v2.json)3. Lưu các bản cập nhật vào một tệp: :w config.v2.json4. Thoát vim: :q!5. Cập nhật tệp hiện có: jq -c . config.v2.json > /var/lib/docker/containers/<container-ID>/config.v2.json6. Khởi động công cụ docker: systemctl start docker.service7. Khởi động container nếu cần : docker start <container-name/ID>8. Thưởng thức :-)
Điều khiển Android

2
Một bước quan trọngservice docker restart. Tôi đã cố gắng để docker restart <container>cấu hình mới không được chọn và nó bị ghi đè bởi cấu hình cũ.
KFL

1
Cũng jqsẽ giúp in đẹp JSON để con người có thể chỉnh sửa được:cat config.v2.json | jq . > config.json
KFL

14

Jérôme Petazzoni có một bài đăng blog khá thú vị về cách Đính kèm một âm lượng vào một thùng chứa trong khi nó đang chạy . Đây không phải là thứ được tích hợp trong Docker, nhưng có thể thực hiện được.

Như ông cũng chỉ ra

Điều này sẽ không hoạt động trên các hệ thống tập tin không dựa trên các thiết bị khối.

Nó sẽ chỉ hoạt động nếu / Proc / mounts liệt kê chính xác nút thiết bị khối (mà như chúng ta đã thấy ở trên, không nhất thiết phải đúng).

Ngoài ra, tôi chỉ thử nghiệm điều này trên môi trường địa phương của tôi; Tôi thậm chí đã không thử trên một ví dụ đám mây hoặc bất cứ điều gì tương tự

YMMV


8

Thật không may, tùy chọn chuyển đổi để gắn một âm lượng chỉ được tìm thấy trong runlệnh.

docker run --help

-v, --volume list Bind mount a volume (default [])

Có một cách bạn có thể giải quyết vấn đề này mặc dù vậy bạn sẽ không phải cài đặt lại các ứng dụng bạn đã thiết lập trên thùng chứa của mình.

  1. Xuất container của bạn docker container export -o ./myimage.docker mycontainer
  2. Nhập dưới dạng hình ảnh docker import ./myimage.docker myimage
  3. Sau đó docker run -i -t -v /somedir --name mycontainer myimage /bin/bash

1
FYI - docker containerkhông phải là một lệnh hợp lệ trên 1.11.2 (đây là phiên bản mới nhất được Synology hỗ trợ khi viết bài này). Tôi không thể tìm thấy bất kỳ tài liệu nói khi nó được thêm vào. Trong trường hợp này lệnh đầu tiên là docker export -o ./myimage.docker mycontainer.
Chris R. Donnelly

2

Một lưu ý khi sử dụng Docker Windows container sau khi tôi phải tìm kiếm vấn đề này trong một thời gian dài!

Điều kiện:

  • Windows 10
  • Docker Desktop (phiên bản mới nhất)
  • sử dụng Docker Windows Container cho hình ảnh microsoft / mssql-server-windows-developer

Vấn đề:

  • Tôi muốn gắn một từ điển máy chủ vào container windows của tôi.

Giải pháp như được mô tả một phần ở đây:

  • tạo container

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer

  • đi đến lệnh shell trong container

docker exec -it <CONTAINERID> cmd.exe

  • tạo TRỰC TIẾP

mkdir DirForMount

  • dừng container

docker container stop <CONTAINERID>

  • cam kết container

docker commit <CONTAINERID> <NEWIMAGENAME>

  • xóa container cũ

docker container rm <CONTAINERID>

  • tạo container mới với hình ảnh mới và khối lượng gắn kết

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y -v C:\DirToMount:C:\DirForMount <NEWIMAGENAME>

Sau đó, tôi đã giải quyết vấn đề này trên các docker windows container.


-3

Cách tốt nhất là sao chép tất cả các tệp và thư mục trong một thư mục trên hệ thống tệp cục bộ của bạn bằng cách: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH

SRC_PATHlà trên container DEST_PATHlà trên localhost

Sau đó, docker-compose downđính kèm một ổ đĩa cho cùng DEST_PATHvà chạy các container Docker bằng cách sử dụngdocker-compose up -d

Thêm âm lượng bằng cách làm theo docker-compose.yml

volumes:
 - DEST_PATH:SRC_PATH

Có những lựa chọn khác, tốt hơn ở trên.
MrR

Thật vậy, có các tùy chọn tốt hơn ở trên và sao chép các tệp xung quanh không gắn chúng. Ngoài ra, định nghĩa "âm lượng" được đưa ra cho tùy chọn soạn thảo docker là cách khác: tập: - HOST_PATH: CONTAINER_PATH
Guillaume S.
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.