เชลล์แบบโต้ตอบโดยใช้ Docker Compose


271

มีวิธีการเริ่มเปลือกโต้ตอบในภาชนะโดยใช้นักเขียนประกอบเท่านั้นหรือไม่ ฉันได้ลองแบบนี้ใน docker-compose.yml ของฉัน:

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

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

ฉันรู้ว่ามีตัวเลือกคำสั่ง docker ดั้งเดิมเพื่อให้บรรลุสิ่งนี้เพียงแค่อยากรู้ว่ามันเป็นไปได้โดยใช้เฉพาะ Docker Compose เช่นกัน


สิ่งนี้ไม่ควรทำงาน ตัวอย่างเช่นหากคุณมีหลายภาพที่มี/bin/shจุดเข้าใช้งานในไฟล์การเขียนของคุณจะต้องทำอย่างไร
Xiongbing Jin

2
อืมทำไมไม่เริ่มเปลือกหลาย ๆ ตัวอย่างเช่นเชลล์ลงในคอนเทนเนอร์ mysql เพื่อทำงานกับ mysql cli และเชลล์ลงในคอนเทนเนอร์สำรองเพื่อรันคำสั่งสำรองข้อมูลหรือไม่
drubb

1
แล้วdocker-compose run myappไงล่ะ
ivoba

1
@ibova ปัญหาคือdocker-compose run myappว่ามันจะไม่เปิดเผยพอร์ต ดังนั้นคุณต้องใช้docker-compose run --service-ports myappแต่ก็ยังไม่สะดวก
คนโง่

entrypoint: /bin/shควรเป็นentrypoint: "/bin/sh"
codentary

คำตอบ:


342

คุณต้องรวมบรรทัดต่อไปนี้ใน docker-compose.yml ของคุณ:

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

สอดคล้องแรกที่จะ-iในและครั้งที่สองไปdocker run-t


3
นั่นstdin_openคือการเชื่อมโยงที่ขาดหายไปเพียงแค่มอบการทำงานที่คาดหวังให้ฉันเมื่อฉันแนบกับหนึ่งในคอนเทนเนอร์ของฉันที่ใช้เชลล์อยู่แล้ว
Charney Kaye

9
@ TheFool แม้ว่าฉันจะมีปัญหาเดียวกัน มันดีกว่าที่จะวิ่งdocker-compose run <service_name>
Aswath K

4
สิ่งนี้เพิ่มตรงไหน? ภายในบริการหรือไม่
problemofficer

นี่น่าจะเป็นคำตอบที่ดีที่สุดสำหรับคำถามของ OP เนื่องจากปัญหาคือภาชนะออกจากที่อื่นทันทีดังนั้นการใช้เชลล์docker execบนมันจะไม่ทำงาน
RoyM

สิ่งนี้ทำให้ฉันมีข้อผิดพลาดใน Windows:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
ประสานงาน

210

วิธีการที่เป็นที่ยอมรับในการรับเชลล์แบบโต้ตอบที่มีองค์ประกอบของนักเทียบท่าคือการใช้: docker-compose run --rm myapp

คุณสามารถตั้งค่าstdin_open: true, tty: trueอย่างไรก็ตามที่จะไม่ให้เชลล์ที่เหมาะสมกับupคุณเนื่องจากบันทึกกำลังถูกสตรีมจากคอนเทนเนอร์ทั้งหมด

คุณยังสามารถใช้

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

เพื่อรับเชลล์บนคอนเทนเนอร์ที่กำลังรัน


16
หมายเหตุคุณต้องเพิ่ม--service-portsถ้าคุณแสดงพอร์ตใด ๆ (เช่นเว็บเซิร์ฟเวอร์)
epelc

9
ฉันได้อัปเดตคำตอบของฉันเพื่อให้ข้อมูลเพิ่มเติมและเพิ่มการ--rmตั้งค่าสถานะเพื่อให้คอนเทนเนอร์ถูกลบ คำตอบโดย @ lynx0123 ไม่ถูกต้อง docker-compose upคุณจะไม่ได้รับเปลือกโต้ตอบถ้าคุณทำงาน
dnephin

2
ในการทำให้สิ่งนี้ทำงานได้โดยใช้ Docker สำหรับ Windows ฉันจำเป็นต้องมีตัวเทียบท่า v. 1.9.0 (ดูที่ปัญหา Github และPR ) ตั้งแต่วันที่ 12/19/16 สิ่งนี้จัดส่งเฉพาะกับ Docker for Windows รุ่นเบต้าเท่านั้น จากนั้นได้docker-compose runผล คุณจะต้องเพิ่มcommand: /bin/bashไปยัง docker-compose.yml
Joseph238

5
นี่ควรเป็นคำตอบที่ดีที่สุด นี่คือสิ่งที่ฉันกำลังมองหาเมื่อฉันมาที่นี่
mkasberg

8
เขียนนักเทียบท่า -d && นักเทียบท่าแนบ <container_name>
Aaron McMillin

58

ในตัวอย่างการเริ่มต้นใช้งานอย่างเป็นทางการ ( https://docs.docker.com/compose/gettingstarted/ ) ด้วยตัวอย่างต่อไปนี้docker-compose.yml:

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

หลังจากที่คุณเริ่มต้นด้วยdocker-compose upคุณสามารถเปลือกเป็นredisภาชนะของคุณหรือของคุณwebภาชนะด้วย:

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

44

docker-compose run myapp sh ควรทำข้อตกลง

มีความสับสนกับup/ runแต่docker-compose runเอกสารมีคำอธิบายที่ดี: https://docs.docker.com/compose/reference/run


1
ขอบคุณมาก. เพียงเพิ่มเล็กน้อยเพื่อชี้แจง นักเทียบท่าเรียกใช้ [ของคุณบริการชื่อที่กำหนดไว้ในนักเทียบท่า-compose.yml] [sh หรือทุบตี]
theeranitp

23

เมื่อใช้นักเทียบท่าฉันพบวิธีที่ง่ายที่สุดในการทำสิ่งนี้คือทำdocker ps -a(หลังจากเริ่มต้นคอนเทนเนอร์ด้วยdocker-compose up) และรับ ID ของคอนเทนเนอร์ที่ฉันต้องการมีเชลล์แบบโต้ตอบใน (ลองเรียกว่า xyz123)

จากนั้นเป็นเรื่องง่ายที่จะดำเนินการ docker exec -ti xyz123 /bin/bash

และ voila เชลล์แบบโต้ตอบ


1
ไม่แน่ใจว่าทำไมสิ่งนี้ถึงได้ลงมติ - เป็นวิธีที่ดีในการแก้ไขข้อบกพร่องในกรณีที่มีอะไรผิดพลาดและฉันใช้วิธีนี้ด้วยความสำเร็จเช่นภายในไม่กี่นาทีหลังจากอ่านโซลูชันนี้
ericmjl

4
@ericmjl เพราะมันเป็นกระบวนการสองขั้นตอนที่คำถามถามโดยเฉพาะเกี่ยวกับการใช้คุณสมบัตินักเขียนและได้ระบุไว้แล้วในคำตอบอื่น ๆ
OneCricketeer

19

ถ้าใครจากอนาคตก็มาที่นี่ด้วย:

docker-compose exec container_name sh

หรือ

docker-compose exec container_name bash

หรือคุณสามารถเรียกใช้บรรทัดเดียวเช่น

docker-compose exec container_name php -v

นั่นคือหลังจากที่คุณมีคอนเทนเนอร์ของคุณแล้วและทำงาน


2

คุณสามารถทำdocker-compose exec SERVICE_NAME shในบรรทัดคำสั่ง ถูกกำหนดไว้ในของคุณSERVICE_NAME docker-compose.ymlตัวอย่างเช่น,

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

SERVICE_NAMEจะเป็น "Zookeeper"


2

คำถามนี้น่าสนใจมากสำหรับฉันเพราะฉันมีปัญหาเมื่อฉันเรียกใช้ container หลังจากการดำเนินการเสร็จสิ้นออกทันทีและฉันแก้ไขด้วย -it:

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

และเมื่อฉันต้องทำให้เป็นอัตโนมัติด้วยนักเขียน:

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

สิ่งนี้ทำให้เคล็ดลับ: stdin_open: true, tty: true

นี่คือโครงการที่สร้างขึ้นด้วย create-react-app

Dockerfile.dev ดูเหมือนว่านี่:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

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

หวังว่าตัวอย่างนี้จะช่วยให้คนอื่นใช้ส่วนหน้า (ตอบสนองในตัวอย่าง) ลงในภาชนะนักเทียบท่า


0

ถ้าymlจะเรียกว่ามันสามารถเปิดตัวด้วยง่ายdocker-compose.yml $ docker-compose upสิ่งที่แนบมาของเทอร์มินัลสามารถเป็นได้ง่าย (พิจารณาว่าymlมีการระบุบริการที่เรียกว่าmyservice):

$ docker-compose exec myservice sh

อย่างไรก็ตามหากคุณใช้ymlชื่อไฟล์อื่นเช่นdocker-compose-mycompose.ymlควรเปิดใช้งาน$ docker-compose -f docker-compose-mycompose.yml upด้วย ในการแนบเทอร์มินัลเชิงโต้ตอบคุณต้องระบุymlไฟล์ด้วยเช่น:

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