Shell tương tác sử dụng Docker Compose


271

Có cách nào để bắt đầu một vỏ tương tác trong một thùng chứa chỉ sử dụng Docker Compose không? Tôi đã thử một cái gì đó như thế này, trong docker-compose.yml của tôi:

myapp:
  image: alpine:latest
  entrypoint: /bin/sh

Khi tôi khởi động container này bằng cách sử dụng docker-compose, nó sẽ thoát ngay lập tức. Có bất kỳ cờ nào tôi có thể thêm vào lệnh entrypoint, hoặc tùy chọn bổ sung cho myapp, để bắt đầu như shell tương tác không?

Tôi biết có các tùy chọn lệnh docker riêng để đạt được điều này, chỉ tò mò nếu có thể chỉ sử dụng Docker Compose.


Đây không phải là để làm việc. Ví dụ: nếu bạn có nhiều hình ảnh với /bin/shđiểm vào trong tệp soạn thảo của mình, thì nó phải làm gì?
Xiongbing Jin

2
Hừm, tại sao không bắt đầu nhiều vỏ? Ví dụ, một shell vào một thùng chứa mysql để làm việc với mysql cli và một vỏ vào một thùng chứa dự phòng để chạy các lệnh sao lưu?
drubb

1
những gì về docker-compose run myapp?
ivoba

1
@ibova Vấn đề là docker-compose run myappnó sẽ không lộ các cổng. Vì vậy, bạn phải sử dụng docker-compose run --service-ports myappnhưng vẫn không thuận tiện.
The Fool

entrypoint: /bin/shnênentrypoint: "/bin/sh"
codentary

Câu trả lời:


342

Bạn cần bao gồm các dòng sau trong docker-compose.yml:

version: "3"
services:
  app:
    image: app:1.2.3
    stdin_open: true # docker run -i
    tty: true        # docker run -t

Cái đầu tiên tương ứng với -itrong docker runvà cái thứ hai -t.


3
đó stdin_openlà liên kết bị thiếu, chỉ đơn giản là cung cấp cho tôi hành vi dự kiến ​​khi tôi đính kèm vào một trong các thùng chứa của tôi đã chạy shell.
Charney Kaye

9
@TheFool, Ngay cả tôi cũng gặp vấn đề tương tự. Nó tốt hơn để chạydocker-compose run <service_name>
Aswath K

4
Chính xác thì nó được thêm vào ở đâu? Bên trong dịch vụ?
vấn đề

Đây dường như là câu trả lời tốt nhất cho câu hỏi của OP .. vì vấn đề là container thoát ra ngay lập tức, do đó, việc lấy vỏ bằng cách sử dụng docker execnó sẽ không hoạt động.
RoyM

Điều này mang lại cho tôi một lỗi trên Windows:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
cowlinator

210

Cách chính tắc để có được một vỏ tương tác với docker-compose là sử dụng: docker-compose run --rm myapp

Bạn có thể thiết lập stdin_open: true, tty: true, tuy nhiên, điều đó thực sự sẽ không cung cấp cho bạn một vỏ phù hợp up, bởi vì các bản ghi đang được truyền phát từ tất cả các container.

Bạn cũng có thể dùng

docker exec -ti <container name> /bin/bash

để có được một vỏ trên một container đang chạy.


16
Lưu ý bạn cần thêm --service-portsnếu bạn để lộ bất kỳ cổng nào (ví dụ: đối với máy chủ web)
epelc

9
Tôi đã cập nhật câu trả lời của mình để cung cấp thêm thông tin và thêm --rmcờ để loại bỏ container. Câu trả lời của @ lynx0123 là không chính xác. Bạn sẽ không nhận được vỏ tương tác nếu bạn chạy docker-compose up.
dnephin

2
Để làm việc này bằng Docker cho Windows, tôi cần docker-compose v. 1.9.0 (xem vấn đề Github và PR ). Kể từ ngày 19/12/2016, phiên bản này chỉ xuất xưởng với các phiên bản beta của Docker cho Windows. Sau đó docker-compose runhoạt động. Bạn cũng sẽ muốn thêm command: /bin/bashvào docker-compose.yml.
Joseph238

5
Đây phải là câu trả lời hàng đầu. Đây là những gì tôi đang tìm kiếm khi tôi đến đây.
mkasberg

8
docker-compose up -d && docker đính kèm <container_name>
Aaron McMillin

58

Trong ví dụ bắt đầu chính thức ( https://docs.docker.com/compose/gettingstarted/ ) với các điều sau docker-compose.yml:

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

Sau khi bạn bắt đầu với docker-compose up, bạn có thể dễ dàng bỏ vào redisthùng chứa hoặc webthùng chứa của mình bằng:

docker-compose exec redis sh
docker-compose exec web sh 

44

docker-compose run myapp sh nên làm thỏa thuận.

Có một số nhầm lẫn với up/ run, nhưng docker-compose runtài liệu có lời giải thích tuyệt vời: https://docs.docker.com/compose/reference/run


1
Cảm ơn bạn rất nhiều. Chỉ cần thêm một chút để làm rõ. docker-compose chạy [your-service-name-định-in-docker-compose.yml] [sh hoặc bash].
theeranitp

23

Sử dụng docker-compose, tôi thấy cách dễ nhất để làm điều này là làm một docker ps -a (sau khi khởi động các thùng chứa của tôi docker-compose up) và lấy ID của container mà tôi muốn có một vỏ tương tác (hãy gọi nó là xyz123).

Sau đó, nó là một vấn đề đơn giản để thực hiện docker exec -ti xyz123 /bin/bash

và voila, một vỏ tương tác.


1
Không chắc chắn tại sao điều này lại bị bỏ phiếu - đó là một cách tuyệt vời để gỡ lỗi trong trường hợp có sự cố xảy ra và tôi đã sử dụng phương pháp này thành công, như, trong vòng một phút sau khi đọc giải pháp này.
ericmjl

4
@ericmjl Bởi vì đó là một quá trình gồm hai bước trong đó câu hỏi được hỏi cụ thể về việc sử dụng các tính năng soạn thảo
docker

19

Nếu ai đến từ tương lai cũng lang thang lên đây:

docker-compose exec container_name sh

hoặc là

docker-compose exec container_name bash

hoặc bạn có thể chạy các dòng đơn như

docker-compose exec container_name php -v

Đó là sau khi bạn đã có container của bạn và chạy


2

Bạn có thể làm docker-compose exec SERVICE_NAME shtrên dòng lệnh. Điều SERVICE_NAMEnày được định nghĩa trong của bạn docker-compose.yml. Ví dụ,

services:
    zookeeper:
        image: wurstmeister/zookeeper
        ports:
          - "2181:2181"

Các SERVICE_NAMEsẽ là "Zookeeper".


2

Câu hỏi này rất thú vị đối với tôi vì tôi gặp vấn đề, khi tôi chạy container sau khi thực hiện xong thì thoát ngay lập tức và tôi đã sửa bằng -it:

docker run -it -p 3000:3000 -v /app/node_modules -v $(pwd):/app <your_container_id>

Và khi tôi phải tự động hóa nó với docker compose:

version: '3'
services:
    frontend:
        stdin_open: true
        tty: true
        build: 
            context: .
            dockerfile: Dockerfile.dev
        ports: 
            - "3000:3000"
        volumes: 
            - /app/node_modules
            - .:/app

Điều này tạo nên mánh khóe: stdin_open: true, tty: true

Đây là một dự án được tạo bằng ứng dụng tạo phản ứng

Dockerfile.dev có vẻ như thế này:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

CMD ["npm", "run", "start"]

Hy vọng ví dụ này sẽ giúp người khác chạy frontend (ví dụ phản ứng) vào container docker.


0

Nếu ymlđược gọi docker-compose.ymlnó có thể được khởi chạy với một đơn giản $ docker-compose up. Tệp đính kèm tương ứng của thiết bị đầu cuối có thể chỉ đơn giản (xem xét rằng ymldịch vụ đã chỉ định một dịch vụ được gọi myservice):

$ docker-compose exec myservice sh

Tuy nhiên, nếu bạn đang sử dụng một ymltên tệp khác , chẳng hạn như docker-compose-mycompose.yml, nó sẽ được khởi chạy bằng $ docker-compose -f docker-compose-mycompose.yml up. Để đính kèm một thiết bị đầu cuối tương tác, bạn cũng phải chỉ định ymltệp, giống như:

$ docker-compose -f docker-compose-mycompose.yml exec myservice sh
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.