Installing openssh-server, running sshd or exposing port 22 adds a second way into the container: a listening service with its own credentials, keys and patching needs. Containers don't need it for debugging, since docker exec and kubectl exec open a shell through the runtime with your existing access control. Remove the SSH server and use those instead.
openrouting — dockerfile explainer
$ explain Dockerfile! RUN installs an SSH server medium! EXPOSE 22 suggests an SSH server mediumline 2fix: see below$
What the free Dockerfile explainer reports on the risky example below.
Why it matters
sshd needs credentials (passwords or authorized keys) that live in the image or are added to it, and anyone who obtains them can log in to every container started from it.
It is another network service to patch and monitor, running alongside the app, often as root, and one more reason the container needs a process manager.
The explainer flags a RUN that installs or starts openssh-server or sshd, a CMD or ENTRYPOINT that runs sshd, and EXPOSE 22.
FROM debian:12-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY app /usr/local/bin/app
EXPOSE 8080
USER 10001
HEALTHCHECK CMD ["/usr/local/bin/app", "health"]
CMD ["/usr/local/bin/app"]
How to fix it
Remove openssh-server, any sshd start command and EXPOSE 22 from the Dockerfile.
Debug with docker exec -it <container> sh or kubectl exec -it <pod> -- sh.
For minimal images with no shell, use kubectl debug to attach a temporary debugging container.
When it's acceptable
Images whose purpose is to be an SSH endpoint, such as a bastion or an SFTP server. Harden them as you would any SSH host: keys only, no root login, no shared host keys baked into the image.
Check your own Dockerfile
The risky example is loaded below. Paste your own file to check it for this and every other Dockerfile rule. It runs in your browser; nothing is uploaded.
Runs apt-get update && apt-get install -y --no-install-recommends openssh-server ca-certificates && rm -rf /var/lib/apt/lists… while building the image and saves the result as a new layer.
An SSH server adds a long-lived credential and a listening service to the image.
Safer: Remove it and use docker exec or kubectl exec for debugging.
Sets the default command to /usr/local/bin/app. It runs when the container starts, and anything passed to docker run replaces it.
Questions
Should I run SSH inside a Docker container?
Usually not. docker exec and kubectl exec give you a shell without an extra service, credentials or open port.
How do I get a shell in a running container without SSH?
Use docker exec -it <container> sh (or bash), or kubectl exec -it <pod> -- sh on Kubernetes. For images without a shell, kubectl debug can attach a debugging container.
Why does the explainer flag EXPOSE 22?
Port 22 is SSH, so exposing it suggests an SSH server is running in the container even if the install happens elsewhere, such as in the base image.