The Problem
We've all been there: you run docker run, expecting your app to boot up, but it crashes instantly. Instead of your application logs, you get a wall of text from the OCI (Open Container Initiative) runtime. This happens because Docker is trying to trigger a command that simply doesn't exist within the container's search path.
The error usually looks like this:
OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"python\": executable file not found in $PATH": unknown
While this specific example flags "python," you'll see the exact same behavior with node, npm, sh, or even a custom shell script you just added to your image.
TL;DR: Quick Fixes
- Check the binary name: Modern images like Ubuntu 22.04 or Debian Bullseye use
python3. Thepythoncommand often isn't mapped. - Use absolute paths: Stop guessing. Change
CMD ["python", "app.py"]toCMD ["/usr/bin/python3", "app.py"]. - Audit your base image: Minimal images like
alpine(which is only ~5MB) lack almost everything. You have to install your tools manually. - Set the PATH: If you use custom directories, use
ENV PATH="/your/path:${PATH}"inside your Dockerfile.
Common Root Causes
1. The Python 2 vs. Python 3 Naming Conflict
This is the biggest culprit. Older Linux distros linked the python command to version 2.7. Since Python 2 hit end-of-life, modern base images have ditched it entirely. If you use python:3.11-slim, the binary is usually named python. However, if you start with a raw ubuntu:latest image and run apt install python3, the system only recognizes python3. Docker won't automatically alias this for you.
2. The "Minimal Image" Trap
Alpine Linux is a favorite for production because of its small footprint. But there's a catch. It uses musl libc and busybox instead of gnu tools. If your script starts with #!/bin/bash, an Alpine container will throw a "not found" error because it only has /bin/sh by default. You're trying to use a tool that isn't in the box.
3. Docker Doesn't Load Your Profile
When you log into a Linux server, it loads .bashrc or .profile. Docker doesn't do this. When it runs a CMD, it uses a very basic environment. If you installed a binary to /opt/my-app/bin, Docker won't look there unless you've explicitly updated the PATH variable in your Dockerfile.
Step-by-Step Fixes
Approach A: Update the Command Syntax
If the logs complain about python, try switching to python3. This is the fastest fix for Debian-based images.
# Old and broken:
CMD ["python", "main.py"]
# New and working:
CMD ["python3", "main.py"]
Approach B: Use Absolute Paths
Remove the guesswork by telling Docker exactly where the file lives. Not sure where it is? Run a temporary container to find out:
docker run --rm python:3.9-slim which python
Once you have that path (e.g., /usr/local/bin/python), update your Dockerfile:
ENTRYPOINT ["/usr/local/bin/python", "app.py"]
Approach C: Install Missing Packages (The Alpine Fix)
If you're using Alpine and need Python, you must add it during the build. Use the apk package manager. We can also create a symlink so the python command works as expected.
FROM alpine:3.19
# Install python3 and create a symlink
RUN apk add --no-cache python3 && ln -sf python3 /usr/bin/python
WORKDIR /app
COPY . .
CMD ["python", "app.py"]
Approach D: Manually Set the PATH
For custom binaries, explicitly add their location to the environment. This ensures Docker looks in your custom folders before giving up.
FROM node:20-slim
WORKDIR /app
COPY . .
# Ensure our custom scripts are discoverable
ENV PATH="/app/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
CMD ["run-custom-task"]
How to Verify the Fix
Don't waste time rebuilding your entire CI/CD pipeline. Debug the image interactively to see what's actually going on inside the file system:
docker run --rm -it --entrypoint /bin/sh your-image-name
Once you're inside, run these three commands:
echo $PATH: Does it include the folder where your app lives?which python3: Does the OS actually see the binary?ls -l /usr/bin/python*: See exactly what versions are installed.
Summary Checklist
- Is the package actually installed in your Dockerfile?
- Did you double-check for typos in your
CMDorENTRYPOINT? - Are you calling
pythonwhen the image only haspython3? - Does your script's shebang (e.g.,
#!/bin/bash) match a shell that exists in the image? - Are you using "exec form" (JSON brackets)? Remember,
["cmd"]doesn't use a shell, so it won't resolve aliases or variables like a raw string would.

