Aprire una shell: docker exec
docker ps
docker exec -it web sh
-i tiene aperto l'input e -t ti dà un terminale. Sostituisci web con il nome che vedi in docker ps. Usa bash se l'immagine ce l'ha. Opzioni utili:
docker exec -it -u root web sh # as another user
docker exec -it -w /app web sh # in another folder
docker exec -e DEBUG=1 web env # with an extra variable
docker compose exec web sh # with Compose: no -it needed
Con Podman gli stessi comandi funzionano scrivendo podman al posto di docker.
Su un server remoto
Entra con SSH nell'host, non nel container. Per farlo in un solo passaggio, chiedi un terminale con -t:
ssh -t user@server docker exec -it web sh
Senza -t, le versioni recenti di Docker si fermano con cannot attach stdin to a TTY-enabled container because stdin is not a terminal, quelle più vecchie con the input device is not a TTY. Se devi eseguire più di un comando, accedi prima al server.
Un nome breve per il server fa risparmiare battute: vedi esempi del file config di SSH.
Errori comuni
Nessuna shell nell'immagine:
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH
Prova sh. Le immagini Alpine hanno sh e non bash. Se anche sh dà lo stesso errore, l'immagine non ha nessuna shell, cosa comune nelle immagini minimali. Avvia un container di appoggio che condivide la vista dei processi e della rete:
docker run --rm -it --pid=container:web --network=container:web alpine sh
Da lì, ps mostra i processi dell'altro container.
Container fermo:
Error response from daemon: container 962d0cc0707e... is not running
Non puoi usare exec in un container fermo. Leggi perché si è fermato e copia fuori i file che ti servono. docker cp funziona anche su un container fermo:
docker logs web
docker cp web:/etc/hostname .
Controllare un Docker remoto dal portatile
Il client Docker può parlare con un demone remoto tramite SSH, quindi docker ps e docker exec sul tuo portatile agiscono sul server. Non viene aperta nessuna porta Docker e si usa solo SSH:
DOCKER_HOST=ssh://user@server docker ps
DOCKER_HOST=ssh://user@server docker exec -it web sh
Per rendere stabile la configurazione, crea un contesto:
docker context create --docker host=ssh://user@server remote
docker --context remote ps
Ti servono un accesso con chiave funzionante al server, un client Docker sul portatile e un utente del server autorizzato a usare il socket di Docker. Tieni presente che l'accesso al demone Docker è quasi equivalente a root su quella macchina: la documentazione di Docker dice che dovrebbero averlo solo utenti fidati.
Ogni comando apre una nuova connessione, quindi Docker consiglia di riutilizzarne una in ~/.ssh/config. Vedi il multiplexing SSH.
Quando ha senso sshd in un container
Solo quando SSH è proprio lo scopo:
- Un server di prova per client SSH, script o Ansible.
- Uno strumento che raggiunge le cose solo via SSH o SFTP e che non puoi modificare.
- Un jump host o una cartella di consegna SFTP che fai girare di proposito come container.
Per entrare a fare debug, aggiunge un servizio, una chiave e una porta aperta, e docker exec fa già quel lavoro. Se ti serve davvero, questo si avvia e accetta l'accesso con chiave:
FROM debian:13-slim
RUN apt-get update && apt-get install -y --no-install-recommends openssh-server \
&& rm -f /etc/ssh/ssh_host_* \
&& useradd -m -s /bin/bash app && mkdir -p /run/sshd \
&& install -d -m 700 -o app -g app /home/app/.ssh
COPY authorized_keys /home/app/.ssh/authorized_keys
RUN chown app:app /home/app/.ssh/authorized_keys && chmod 600 /home/app/.ssh/authorized_keys
CMD ["sh", "-c", "ssh-keygen -A && exec /usr/sbin/sshd -D -e -o PasswordAuthentication=no"]
docker build -t sshd-demo .
docker run -d --name sshd-demo -p 127.0.0.1:2222:22 sshd-demo
ssh -p 2222 app@127.0.0.1
Qui contano tre dettagli:
- Le chiavi dell'host vengono create all'avvio, non nell'immagine. Altrimenti ogni container creato dall'immagine condivide la stessa chiave privata dell'host. Lo svantaggio è una chiave nuova ogni volta che il container viene ricreato, il che fa comparire l'avviso sulla chiave dell'host. Se ti importa, tieni
/etc/sshin un volume. - La porta è legata a 127.0.0.1. Le porte pubblicate aggirano ufw. La documentazione di Docker dice che il traffico viene deviato prima di raggiungere le regole di ufw, quindi
-p 2222:22può essere aperta al mondo anche con ufw attivo. - Questa immagine non contiene segreti.
authorized_keyscontiene solo chiavi pubbliche. Non copiare mai una chiave privata in un'immagine.
Domande
docker exec richiede SSH?
No. Il comando docker parla con il demone Docker, che avvia il processo dentro il container.
Come apro una shell in un container come root?
Aggiungi -u root: docker exec -it -u root web sh. Funziona anche se l'immagine gira con un altro utente.
Come entro in un container su un server remoto?
Accedi via SSH al server che lo esegue, poi usa docker exec. In un solo passo: ssh -t user@server docker exec -it web sh.
Una shell avviata con docker exec sopravvive al riavvio del container?
No. Esiste solo finché gira il processo principale del container e non viene riavviata quando il container riparte.
Fonti
- docker container exec, Docker Docs
- Protect the Docker daemon socket, Docker Docs
- Docker security, Docker Docs
- Packet filtering and firewalls, Docker Docs