content/manuals/dhi/how-to/debug.md
Docker Hardened Images (DHI) prioritize minimalism and security, which means they intentionally leave out many common debugging tools (like shells or package managers). This makes direct troubleshooting difficult without introducing risk. To address this, you can use Docker Debug, a secure workflow that temporarily attaches an ephemeral debug container to a running service or image without modifying the original image.
This guide shows how to debug Docker Hardened Images locally during development.
With Docker Debug, you can also debug containers remotely using the --host
option.
Start with a DHI-based container that simulates an issue:
$ docker run -d --name myapp dhi.io/python:3.13 python -c "import time; time.sleep(300)"
This container doesn't include a shell or tools like ps, top, or cat.
If you try:
$ docker exec -it myapp sh
You'll see:
exec: "sh": executable file not found in $PATH
Use the docker debug command to attach a temporary, tool-rich debug container to the running instance.
$ docker debug myapp
From here, you can inspect running processes, network status, or mounted files.
For example, to check running processes:
$ ps aux
Type exit to leave the container when done.
In addition to using Docker Debug, you can also use the following approaches for debugging DHI containers.
Docker Hardened Images offer a -dev variant that includes a shell
and a package manager to install debugging tools. Simply replace the image tag
with -dev:
$ docker run -it --rm dhi.io/python:3.13-dev sh
Type exit to leave the container when done. Note that using the -dev variant
increases the attack surface and it is not recommended as a runtime for
production environments.
You can use the image mount feature to mount debugging tools into your container without modifying the base image.
Start with a DHI-based container that simulates an issue:
$ docker run -d --name myapp dhi.io/python:3.13 python -c "import time; time.sleep(300)"
Run a new container that mounts a tool-rich image (like busybox) into
the running container's namespace:
$ docker run --rm -it --pid container:myapp \
--mount type=image,source=busybox,destination=/dbg,ro \
dhi.io/python:3.13 /dbg/bin/sh
This mounts the BusyBox image at /dbg, giving you access to its tools while
keeping your original container image unchanged. Since the hardened Python image
doesn't include standard utilities, you need to use the full path to the mounted
tools:
$ /dbg/bin/ls /
$ /dbg/bin/ps aux
$ /dbg/bin/cat /etc/os-release
Type exit to leave the container when done.
This guide covered three approaches for debugging Docker Hardened Images:
-dev variants: Use development images that include debugging toolsEach method helps you troubleshoot hardened containers while maintaining
security. Docker Debug and image mounts avoid modifying your production images,
while -dev variants provide convenience during development.
If you encounter issues related to permissions, ports, missing shells, or package managers, see Troubleshoot Docker Hardened Images for recommended solutions and workarounds.