Sign inSign up

hermsi/alpine-sshd

By hermsi

•Updated 9 days ago

Dockerize your OpenSSH-server with rsync and bash installed, upon a customizable alpine-image

Image
39

5M+

hermsi/alpine-sshd repository overview

⁠hermsi/alpine-sshd

Build and Deploy Docker Pulls Docker Stars Image Size Donate

Make your OpenSSH fly on Alpine.

A slim, highly configurable OpenSSH server (sshd) on Alpine Linux with bash, bash-completion and rsync preinstalled. Typical uses: an SSH/SFTP sidecar for exchanging files with other containers or volumes, an rsync endpoint, or a lightweight jump host. Everything is configured through environment variables at container start — no image rebuild needed.

Images are built for linux/amd64 and linux/arm64 and rebuilt weekly so they stay current with Alpine security updates.

⁠Quick start

⁠Log in as root with a password
docker run --rm \
  --publish 1337:22 \
  --env ROOT_PASSWORD=MyRootPW123 \
  hermsi/alpine-sshd
ssh [email protected] -p 1337
⁠Log in as root with an SSH key
docker run --rm \
  --publish 1337:22 \
  --env ROOT_KEYPAIR_LOGIN_ENABLED=true \
  --volume /path/to/authorized_keys:/root/.ssh/authorized_keys \
  hermsi/alpine-sshd
ssh [email protected] -p 1337 -i /path/to/private_key

In this mode password authentication for root is disabled entirely.

⁠Create additional users (key-based login)

Users are declared as comma-separated name:uid:gid triplets. Each user authenticates with the public key mounted at /conf.d/authorized_keys/<username>:

docker run --rm \
  --publish 1337:22 \
  --env SSH_USERS="hermsi:1000:1000,dennis:1001:1001" \
  --volume /path/to/hermsi.pub:/conf.d/authorized_keys/hermsi \
  --volume /path/to/dennis.pub:/conf.d/authorized_keys/dennis \
  hermsi/alpine-sshd
ssh mydomain.tld -l hermsi -p 1337 -i /path/to/hermsi_private_key

Additional users authenticate by keypair only. The root account stays locked unless you explicitly unlock it (see below).

⁠Tags

The tag set encodes the exact OpenSSH package version and the Alpine release the image was built from:

Tag patternExampleDescription
latestlatestMost recent build
<ssh-version>10.3_p1-r0Exact Alpine openssh package version
<ssh-version>-alpine10.3_p1-r0-alpineSame, with explicit distro marker
<ssh-version>-alpine<alpine-version>10.3_p1-r0-alpine3.24Fully pinned: OpenSSH version and Alpine release

Versions are detected automatically at build time from the current alpine:latest image, so new OpenSSH releases are published as soon as Alpine ships them. Independent of version changes, all tags are rebuilt and re-pushed every Monday at 02:00 UTC with a fresh package index, so even a pinned tag receives Alpine security fixes. For the full list of available tags see Docker Hub⁠.

⁠Registries

The same image is published to three registries:

docker pull hermsi/alpine-sshd:latest
docker pull quay.io/hermsi1337/alpine-sshd:latest
docker pull ghcr.io/hermsi1337/docker-sshd:latest

⁠Configuration

⁠Environment variables
VariableDefaultDescription
ROOT_LOGIN_UNLOCKEDfalseUnlock the root account for SSH login. When unlocked without ROOT_PASSWORD, a random password is generated (and not printed), so set one explicitly if you want password login.
ROOT_PASSWORD(unset)Password for root. Setting it implies ROOT_LOGIN_UNLOCKED=true.
ROOT_KEYPAIR_LOGIN_ENABLEDfalseKey-based login for root (implies ROOT_LOGIN_UNLOCKED=true, disables password authentication). Requires a public key mounted at /root/.ssh/authorized_keys.
SSH_USERS(unset)Comma-separated list of additional users as name:uid:gid (e.g. hermsi:1000:1000,dennis:1001:1001). Invalid entries are skipped; an existing GID reuses the existing group.
USER_LOGIN_SHELL/bin/bashLogin shell for additional users. If the configured shell is not executable, the fallback is used.
USER_LOGIN_SHELL_FALLBACK/bin/ashFallback shell if USER_LOGIN_SHELL cannot be used.
DEBUG(unset)Set to true to trace the entrypoint (set -x) for troubleshooting.
KEYPAIR_LOGIN(unset)Deprecated alias for ROOT_KEYPAIR_LOGIN_ENABLED, kept for backward compatibility.
⁠Ports, volumes and paths
Path / PortPurpose
22/tcpsshd listens here — publish it to any host port you like.
/etc/ssh (volume)sshd configuration and host keys. On first start with an empty volume, the stock configuration is restored and host keys are generated. Mount a volume here to keep host keys stable across container re-creations (avoids "host key changed" warnings).
/root/.ssh/authorized_keysPublic key(s) for root when ROOT_KEYPAIR_LOGIN_ENABLED=true.
/conf.d/authorized_keys/<username>Public key(s) for each user listed in SSH_USERS.
⁠Passing extra options to sshd

Arguments appended after the image name are handed straight to sshd (it runs in the foreground with -D -e):

docker run --rm --publish 1337:22 --env ROOT_PASSWORD=secret \
  hermsi/alpine-sshd -o LogLevel=VERBOSE

⁠Docker Compose example

services:
  sshd:
    image: hermsi/alpine-sshd:latest
    ports:
      - "1337:22"
    environment:
      SSH_USERS: "hermsi:1000:1000"
    volumes:
      - ./keys/hermsi.pub:/conf.d/authorized_keys/hermsi:ro
      - ssh_host_config:/etc/ssh
    restart: unless-stopped

volumes:
  ssh_host_config:

⁠Supported architectures

linux/amd64 and linux/arm64 — published as a single multi-arch manifest, so docker pull automatically selects the right variant for your platform.

⁠Extending this image

The image is intentionally slim and vanilla. If you need extra tools such as git, build your own image on top:

FROM hermsi/alpine-sshd:latest

RUN  apk add --no-cache \
        git

⁠Contributing and maintenance

Development, CI/CD internals (build pipeline, version detection, release invariants) and common maintenance tasks are documented in AGENTS.md⁠. Pull requests trigger a full multi-arch build for validation, but nothing is pushed to the registries until the change lands on master.

⁠License

MIT⁠

Tag summary

Content type

Image

Digest

sha256:8420f9f95…

Size

7.8 MB

Last updated

9 days ago

docker pull hermsi/alpine-sshd