bash: sudo: command not found inside a Docker container means the image does
not ship sudo at all. In the ubuntu:24.04 container tested here
the shell was already root, so the answer is to run the same command without
sudo.
Type apt-get update instead of sudo apt-get update. If a script you
cannot change calls sudo, install the package with
apt-get update and apt-get install -y sudo; after that the same
script line ran.
The error
docker exec fix10-lc-r1 bash -ic 'sudo apt-get update 2>&1'
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
bash: sudo: command not found
The first two lines come from starting an interactive shell without a terminal and are not part of the problem. Run non-interactively, the same mistake adds a line number and exits with 127:
docker exec fix10-lc-r2 bash -c 'sudo apt-get update 2>&1; echo exit=$?'
bash: line 1: sudo: command not found
exit=127
Why it happens
sudo is a separate package, and the ubuntu:24.04 image does not
include it. Bash looked for a program called sudo on the PATH,
found none, and stopped before apt-get was ever started. The same message
appeared in a container made from mcr.microsoft.com/dotnet/aspnet:10.0.
You rarely need it there: docker exec started the shell as
root in both containers (whoami printed root,
id -u printed 0), and root does not have to ask for more rights.
The fix
docker exec fix10-lc-r1 bash -ic 'cat /etc/os-release | head -1; whoami; id -u 2>&1'
...
PRETTY_NAME="Ubuntu 24.04.5 LTS"
root
0
Drop the word sudo and run the command as root. When a script needs the
program to exist, install it once the package lists are downloaded:
docker exec fix10-lc-r1 bash -ic 'apt-get install -y sudo > /dev/null; echo install-exit=$? 2>&1'
...
install-exit=0
docker exec fix10-lc-r1 bash -ic 'sudo apt-get update | tail -2 2>&1'
...
Hit:4 http://archive.ubuntu.com/ubuntu noble-backports InRelease
Reading package lists...
In this container apt-get update had already run. In a fresh one the
install failed until the update was done:
docker exec fix10-lc-r8 bash -c 'apt-get install -y sudo 2>&1; echo exit=$?'
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package sudo
exit=100
A package installed with docker exec does not outlive its container. In a
separate test with ping, the command was gone in a new container from the same image,
and an image built from a Dockerfile with
RUN apt-get update && apt-get install -y iputils-ping had it; do the
same with sudo if you need it every time.
How it was reproduced
The captures were made in containers created from ubuntu:24.04 (Ubuntu
24.04.5 LTS, bash 5.2.21, apt 2.8.3) and mcr.microsoft.com/dotnet/aspnet:10.0
with docker run -d --name ... sleep infinity on Docker Engine 29.9.3, and
commands sent with docker exec. The installed package was
sudo 1.9.15p5-3ubuntu5.24.04.4. The fix10-lc- container names
are the test's own.
Every command was sent from Windows PowerShell 5.1 exactly as shown, with the -c text in single quotes so it reached the container unchanged; a single quote inside that text is written twice, as PowerShell requires.
Frequently asked
- Why is sudo not found in my Docker container?
- The ubuntu:24.04 image does not include the sudo package. In the test the shell already ran as root, so commands work without sudo.
- How do I install sudo in an Ubuntu container?
- Run apt-get update, then apt-get install -y sudo. In the test install returned 0 and sudo apt-get update then ran.
- Do I need sudo as root in Docker?
- No. In the test whoami printed root and id -u printed 0 inside the container, so apt-get ran without sudo.
More decoded errors in the Fixes category. The next missing command in a fresh container is often ping: bash: ping: command not found.