moby: exec does not set TERM env when -t passed

Passing -t to docker run will set the TERM environment variable. Doing so to docker exec will not. This causes things like htop to not work.

$ docker run -d --name foo debian bash -c "while true; sleep 1; done"
2fc4a0d2fc6d
$ docker exec -ti foo env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=2fc4a0d2fc6d

Or a case that the end user is more likely to experience:

$ docker run -d --name foo debian bash -c "while true; sleep 1; done"
2fc4a0d2fc6d
$ docker exec foo "apt-get update && apt-get install -y htop"
....
$ docker exec -ti foo htop
Error opening terminal: unknown.

Versions and stuff:

$ docker version
Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa
$ uname -a 
Linux hostname 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:42 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ docker -D info
Containers: 186
Images: 2828
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 3206
Execution Driver: native-0.2
Kernel Version: 3.13.0-35-generic
Operating System: Ubuntu 14.04.1 LTS
Debug mode (server): false
Debug mode (client): true
Fds: 135
Goroutines: 224
EventsListeners: 1
Init Path: /usr/bin/docker
WARNING: illegal base64 data at input byte 4
WARNING: No swap limit support

Apologies if this has already been reported/fixed (I didn’t test against master, even though I know I should!)

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Reactions: 7
  • Comments: 28 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Workaround:

  1. Enter container with docker exec.
  2. Run command: export TERM=xterm

I’ve tested this on a OSX host with boot2docker vm.

Note, this will not survive restarts.

I find it easier to remember:

docker exec -ti test env TERM=xterm bash -l

Workaround:

docker exec -it $container /bin/bash -c "export TERM=xterm; exec bash"

Works very well.

We just merged a pull-request that automatically sets TERM if docker exec is started with a tty (-t) https://github.com/docker/docker/pull/26461

This change will go into the next release (1.13)

any chance to get this one fixed, to make using docker exec more comfortable?

FYI terminal copy + cols/rows fix

kubectl exec -it $1 -- /bin/bash -c "stty rows $(tput lines) cols $(tput cols) && export TERM=$TERM && exec bash"

https://github.com/grosser/dotfiles/commit/eca07c9c69deccdc19a5bcaf7b46b72f14577711

Works like a charm kubectl exec -it kafka-kafka-0 – bash -c “export TERM=xterm; exec bash” or kubectl exec -it kafka-kafka-0 – bash -c “export TERM=xterm; bash” docker exec -it $container /bin/bash -c “export TERM=xterm; exec bash”

@bocharsky-bw docker-compose should use the same API, but if it’s not working with the 1.13 daemon, it’s best to open an issue in the docker-compose issue tracker; https://github.com/docker/compose/issues

@vipseixas we’ve been doing this for almost two years, it’s literally “let the devs tinker with their php in production” type work (because face it, it’s easier to syntax error 30 live instances of the site in docker than it is to work offline, test, etc), the rest of everything is stable. The problem is as the exec api stands it’s not suitable for doing that at least not on a production machine. No tidy way to clean up after someone that just closes their terminal instead of exiting properly, no tidy way to pass env, probably more I’m forgetting after so little sleep. I have been trying to write a tool that lets us exec right into a shell the thing remotely (ala ssh but reverse proxied so there’s no ports exposed, with full session recording, and easier to integrate auth) but these issues make it un-appealing