sh: apt-get: not found is what the Alpine Linux container printed in the
test when given an Ubuntu install command. Alpine installs packages with
apk, not apt-get: replace
apt-get update && apt-get install -y curl with
apk add --no-cache curl and the install works.
Package names can differ from Ubuntu's too (Ubuntu's ping package is
iputils-ping, Alpine's is iputils), so check them with
apk search -x before you translate a whole list.
The error
docker run --rm alpine sh -c 'apt-get update'
sh: apt-get: not found
In a running Alpine container the exit code was 127:
docker exec fix10-lc-al2 sh -c 'apt-get install -y curl 2>&1; echo exit=$?'
sh: apt-get: not found
exit=127
Why it happens
The alpine image is Alpine Linux 3.24.2 here. Its sh is
BusyBox, its package tool is apk, and there is no apt-get and no
bash:
docker exec fix10-lc-al2 sh -c 'cat /etc/alpine-release; ls -l /bin/sh; command -v apk apt-get bash; echo exit=$?'
3.24.2
lrwxrwxrwx 1 root root 12 Sep 17 17:32 /bin/sh -> /bin/busybox
/sbin/apk
exit=0
command -v printed a path only for apk. An
apt-get line copied from Ubuntu instructions therefore has nothing to run in
this image.
The fix
docker exec fix10-lc-al2 sh -c 'apk add --no-cache curl 2>&1; echo apk-exit=$?; curl --version | head -1'
(1/9) Installing brotli-libs (1.2.1-r0)
...
(9/9) Installing curl (8.23.0-r0)
Executing busybox-1.37.0-r31.trigger
OK: 13.1 MiB in 25 packages
apk-exit=0
curl 8.23.0 (x86_64-alpine-linux-musl) libcurl/8.23.0 OpenSSL/3.5.8 zlib/1.3.2 brotli/1.2.1 zstd/1.5.7 c-ares/1.34.9 libidn2/2.3.8 libpsl/0.21.5 nghttp2/1.70.0
apk add --no-cache installed curl and its eight libraries without a
separate update step. apk search -x confirmed the Alpine names of two
network packages:
docker exec fix10-lc-al2 sh -c 'apk search -x net-tools; apk search -x iputils'
net-tools-2.10-r3
iputils-20250605-r2
If a script you copy into the container starts with #!/bin/bash, bash has
to be installed first, because the image has only BusyBox sh. One more
apk add did it:
docker exec fix10-lc-al2 sh -c 'apk add --no-cache bash 2>&1; echo apk-exit=$?; bash --version | head -1'
...
(4/4) Installing bash (5.3.9-r1)
...
apk-exit=0
GNU bash, version 5.3.9(1)-release (x86_64-alpine-linux-musl)
The mirror mistake
The opposite happens when an Alpine instruction meets an Ubuntu container: bash has no
apk there.
docker exec fix10-lc-u3 bash -c 'apk add curl 2>&1; echo exit=$?'
bash: line 1: apk: command not found
exit=127
Use apt-get update and apt-get install -y there. The
line 1: part appears because the command ran through bash -c.
How it was reproduced
The captures used the cached alpine image (Alpine 3.24.2) and
ubuntu:24.04 on Docker Engine 29.9.3: one
docker run --rm alpine, a container started with
docker run -d --name fix10-lc-al2 alpine sleep 3600 and one started with
docker run -d --name fix10-lc-u3 ubuntu:24.04 sleep infinity. Every command
was sent from Windows PowerShell 5.1 exactly as shown, with the sh -c and
bash -c text in single quotes so it reached the container unchanged. The
container names are the test's own.
Frequently asked
- How do I install packages in an Alpine container?
- Use apk add --no-cache followed by the package name. In the test apk add --no-cache curl returned 0 and curl --version worked.
- Why is apt-get not found in my Docker container?
- In the test the image was Alpine Linux, which has apk instead. command -v found /sbin/apk and no apt-get or bash.
- Does Alpine have bash?
- Not in the tested image; sh is BusyBox. In the test apk add --no-cache bash installed GNU bash 5.3.9.
More decoded errors in the Fixes category. For a missing tool in an Ubuntu container, see bash: ping: command not found.