devcontainers / devcontainers/features

docker-outside-of-docker: socat breaks interactive support

Aperta
#483 4 commenti 3 reazioni 1 assegnatario Rivendicata da @alexander-smolyakov Vedi su GitHub
Lingua principale
Shell
Stelle
1.5k
Fork
621
Merge medio
6g 53m
PR unite (30g)
9

Descrizione

When docker-outside-of-docker feature ends up using `socat` to create a Unix socket ready to use by user in container, you will experience the following inside your terminal:

1. `echo "uname; exit 1" | docker run --interactive ubuntu:jammy` will work as expected:
* will otuput `Linux`
* will exit with code 1
2. `echo "sleep 2; uname; exit 2" | docker run --interactive ubuntu:jammy` won't work as expected:
* won't output Linux (output lost)
* exit code will correctly be 2
3. `(echo "sleep 2; uname; exit 2"; sleep 3) | docker run --interactive ubuntu:jammy` will work as expected

This can be reproduced out of devcontainer context by starting `socat`:
```shell
# start socat
socat UNIX-LISTEN:$HOME/docker.sock,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock &

# using our new docker socket
export DOCKER_HOST=unix://$HOME/docker.sock
```

I had to dig deep but socat manual got the answer:
> -t
> When one channel has reached EOF, the write part of the other channel is shut down. Then, socat waits [timeval] seconds before terminating. De‐
> fault is 0.5 seconds. This timeout only applies to addresses where write and read part can be closed independently. When during the timeout interval the
> read part gives EOF, socat terminates without awaiting the timeout.

Without tuning `socat -t xxx`, it will close connection after 0.5s all stdin data has been sent. docker client will then wait for container to get its exit code but will never received the subsequent output. Tuning that timeout can be a nightmare since it has to be more than the longest pause in output data.

Best is to get rid of socat and rely on group membership:
* this feature mostly tries to adjust docker's group id to match the one of the docker host socket: i believe this is wrong since files in container may belong to that group and won't be adjusted accordingly
* i would instead:
* get group id of the docker host socket
* locate group using that id and if none is found create one (e.g. docker-host or devc-docker-host to ensure no name conflict can raise)
* add user to the group

I can help if needed.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.