Shell interattiva usando Docker Compose


271

Esiste un modo per avviare una shell interattiva in un contenitore usando solo Docker Compose? Ho provato qualcosa del genere, nel mio docker-compose.yml:

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

Quando avvio questo contenitore usando la finestra mobile componi, si esce immediatamente. Ci sono flag che posso aggiungere al comando entrypoint o come e un'opzione aggiuntiva a myapp, per iniziare come shell interattiva?

So che ci sono opzioni di comando native docker per raggiungere questo obiettivo, solo curioso di sapere se è possibile utilizzare solo Docker Compose.


Questo non dovrebbe funzionare. Ad esempio, se /bin/shnel file di composizione sono presenti più immagini con entrypoint, cosa dovrebbe fare?
Xiongbing Jin

2
Hmh, perché non avviare più shell? Ad esempio, una shell in un contenitore mysql per funzionare con mysql cli e una shell in un contenitore di backup per eseguire i comandi di backup?
Drubb

1
che dire docker-compose run myapp?
ivoba,

1
@ibova Il problema è docker-compose run myappche non esporrà le porte. Quindi devi usare docker-compose run --service-ports myappma non è ancora molto conveniente.
Il matto

entrypoint: /bin/shdovrebbe essereentrypoint: "/bin/sh"
codentario

Risposte:


342

È necessario includere le seguenti righe nel docker-compose.yml:

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

Il primo corrisponde a -iin docker rune il secondo a -t.


3
questo stdin_openè il collegamento mancante, per avermi semplicemente fornito il comportamento previsto quando mi collego a uno dei miei contenitori che sta già eseguendo una shell.
Charney Kaye,

9
@TheFool, anche io ho avuto lo stesso problema. È meglio correredocker-compose run <service_name>
Aswath K

4
Dove si aggiunge esattamente questo? All'interno del servizio?
problemofficer,

Questa sembra essere la migliore risposta alla domanda del PO ... dato che il problema è che il contenitore esce immediatamente altrimenti, quindi ottenere una shell usando docker execsu di esso non funzionerà.
RoyM

Questo mi dà un errore su Windows:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
cowlinator

210

Il modo canonico per ottenere una shell interattiva con docker-compose è usare: docker-compose run --rm myapp

È possibile impostare stdin_open: true, tty: true, tuttavia, che in realtà non ti darà una shell corretta up, poiché i log vengono trasmessi in streaming da tutti i contenitori.

Puoi anche usare

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

per ottenere una shell su un container in esecuzione.


16
Nota che è necessario aggiungere --service-portsse si espongono porte (ad esempio per un server Web)
epelc

9
Ho aggiornato la mia risposta per fornire ulteriori informazioni e aggiungere il --rmflag in modo che il contenitore venga rimosso. La risposta di @ lynx0123 non è corretta. Non otterrai una shell interattiva se esegui docker-compose up.
dnephin,

2
Per far funzionare tutto questo con Docker per Windows, avevo bisogno di docker-compose v. 1.9.0 (vedi problema Github e PR ). A partire dal 19/12/16, questo viene fornito solo con versioni beta di Docker per Windows. Quindi docker-compose runfunziona. Ti consigliamo anche di aggiungere command: /bin/basha docker-compose.yml.
Joseph238,

5
Questa dovrebbe essere la risposta migliore. Questo è quello che stavo cercando quando sono venuto qui.
mkasberg,

8
docker-compose up -d && docker attach <container_name>
Aaron McMillin

58

Nell'esempio iniziale ufficiale ( https://docs.docker.com/compose/gettingstarted/ ) con quanto segue docker-compose.yml:

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

Dopo aver iniziato con docker-compose up, puoi facilmente sgusciare nel tuo rediscontenitore o nel tuo webcontenitore con:

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

44

docker-compose run myapp sh dovrebbe fare l'affare.

C'è un po 'di confusione con up/ run, ma i docker-compose rundocumenti hanno una grande spiegazione: https://docs.docker.com/compose/reference/run


1
Grazie mille. Basta aggiungere un po 'per chiarire. docker-compose run [nome-tuo-servizio-definito-in-docker-compose.yml] [sh o bash].
theeranitp,

23

Usando docker-compose, ho trovato il modo più semplice per farlo è quello di fare un docker ps -a(dopo aver avviato i miei contenitori con docker-compose up) e ottenere l'ID del contenitore in cui voglio avere una shell interattiva (chiamiamola xyz123).

Quindi è una cosa semplice da eseguire docker exec -ti xyz123 /bin/bash

e voilà, una shell interattiva.


1
Non sono sicuro del motivo per cui questo è stato sottovalutato: è un ottimo modo per eseguire il debug nel caso in cui qualcosa vada storto, e ho usato questo metodo con successo, ad esempio, entro un minuto dalla lettura di questa soluzione.
Ericmjl,

4
@ericmjl Perché è un processo in due fasi in cui la domanda posta specificamente sull'uso delle funzionalità di composizione
docker è

19

Se qualcuno del futuro vaga anche qui:

docker-compose exec container_name sh

o

docker-compose exec container_name bash

oppure puoi eseguire linee singole come

docker-compose exec container_name php -v

Cioè dopo che i contenitori sono già attivi e funzionanti


2

Puoi farlo docker-compose exec SERVICE_NAME shdalla riga di comando. Il SERVICE_NAMEè definito nel tuo docker-compose.yml. Per esempio,

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

Il SERVICE_NAMEsarebbe "Zookeeper".


2

Questa domanda è molto interessante per me perché ho problemi, quando eseguo container dopo l'esecuzione termina immediatamente e ho risolto con -it:

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

E quando devo automatizzarlo con la finestra mobile componi:

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

Questo rende il trucco: stdin_open: true, tty: true

Questo è un progetto generato con create -eagire-app

Dockerfile.dev sembra che:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

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

Spero che questo esempio aiuti altri ad eseguire un frontend (reagire nell'esempio) nel contenitore docker.


0

Se ymlviene chiamato docker-compose.yml, può essere avviato con un semplice $ docker-compose up. Il collegamento corrispondente di un terminale può essere semplicemente (considerare che ymlha specificato un servizio chiamato myservice):

$ docker-compose exec myservice sh

Tuttavia, se si utilizza un ymlnome file diverso , ad esempio docker-compose-mycompose.yml, dovrebbe essere avviato utilizzando $ docker-compose -f docker-compose-mycompose.yml up. Per allegare un terminale interattivo devi specificare anche il ymlfile, proprio come:

$ docker-compose -f docker-compose-mycompose.yml exec myservice sh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.