Fixing the Docker TERM variable issue

You must manually set the TERM environment variable when using console programs with text-based UIs (top, clear, less, nano) inside docker if the container was not startet with the --tty option
created by on 2015-12-15
Fixing the Docker TERM variable issue

The Problem

Sometimes* when you are entering a docker container with docker exec -ti <container-name> bash the basic bash commands like top, less, more, clear or vim don’t work.

All you get is error messages complaining that the terminal does not work or the TERM environment variable is not set:

clear, top

TERM environment variable not set.

Screenshot: Error message - TERM environment variable not set

nano

Error opening terminal: unknown.

Screenshot: Error opening terminal: unknown error when trying to start nano

Or the programs muchstart with a warning, but don’t work properly (e.g. less):

less

WARNING: terminal is not fully functional

Screenshot: WARNING - terminal not fully function when using less

The reason for these error messages is that programs like top, less or vim use information about the terminal you are using to fill the screen and recognize which keys you hit. If this information is not correct, the screen may be messed up or keys may not be recognized.

A quick fix

The quick solution for this problem is very easy - just set the TERM environment variable to xterm after you enter the container:

docker exec -ti <a-docker-container> bash
export TERM=xterm

Animation: Setting the TERM environment variable to fix the "TERM environment variable not set" issue

Setting the TERM environment variable like this only fixes the problem for your current bash session. The next time you enter the container you’ll have to set the environment variable again.

A long-term solution

If you want to prevent setting the TERM environment variable every time you enter a docker container you should always use the -t or --tty flag when executing docker run. This will permanently set the TERM variable for you.

  1. Start the container with the tty flag (docker run -t image)
  2. Use the latest version of Docker (≥1.9)

If you follow these two rules you won’t have to set the TERM environment varibale yourself.

But you will still need the quick-fix from time to time, because not all containers are started with the tty option. Especially noIt seemed to me t if you used a tool like docker-compose to start the containers.

An explanation

Some background on the TERM environment variable and why this problem does not always ocurr.

The TERM variable

If you want to use console programs that create text-based user interfaces (e.g. clear, less, top, vim, nano, …) the TERM environment variable (↑) must be set.

These programs use the TERM variable to decide which strings to send for clearing the screen, for cursor movementsor for displaying color.

Usually the TERM variable is set or reset by a tool called getty) that manages physical or virtual terminals (TTYs). And I think that this tool is not exected if you start a container without the tty flag.

But I might be wrong. If you have an explaination please let me know (Twitter 🐦 : @andreaskoch).

When does this problem occur?

* The problem only occurs if you are entering a docker container that has been started without the tty option (-t / --tty):

docker run -d --name testcontainer ubuntu:trusty bash -c 'while true; do echo $(date); sleep 1; done'
docker exec -ti testcontainer bash
top

Animation: If a container is started without tty option the TERM environment variable is not set

From my experience I can say that if you are using Docker 1.9 and add the -t flag when starting a container you will not have to set the TERM environment variable yourself:

docker run -d -t --name testcontainer ubuntu:trusty bash -c 'while true; do echo $(date); sleep 1; done'
docker exec -ti testcontainer bash
top

Animation: Starting docker containers with the tty flag persistently sets the TERM environment variable for that container

I think there were problems with older versions of docker (≤1.9) even if you used the tty option for the docker run command (see: Docker issue #9299 - exec does not set TERM env when -t passed, Docker issue #8631 - dumb terminal when using docker exec).

But if you are using a current version of docker this solution should work 🐬

Tags: