Build the image from the vendor vshell-https .deb on ubuntu:24.04 (required: GLIBC_2.38 / GLIBCXX_3.4.32). Contains the Dockerfile, the entrypoint that starts and supervises the three VShell daemons without systemd, the no-container-runtime build/validate/push tooling used to publish the image, and the vendored .deb (sha256 pinned). Published as gitea.milesward.dev/mward4/vshell:5.0.1-3985 and :latest. Manifest digest sha256:8b0ff00be981fa05f1e4a4e4ff5307b6c7e5e61b487d4fbe7e02fefb2a04659f.
VShell container image
Container image for VanDyke Software VShell for UNIX 5.0.1 (build 3985) — the
SSH2/SFTP, FTPS and HTTPS file-transfer server — built from the vendor's
vshell-https-5.0.1-3985.ubuntu24-64.x86_64.deb.
Image: gitea.milesward.dev/mward4/vshell:5.0.1-3985 (also tagged latest).
Manifest digest: sha256:8b0ff00be981fa05f1e4a4e4ff5307b6c7e5e61b487d4fbe7e02fefb2a04659f.
What is in the image
| Layer | Contents |
|---|---|
ubuntu:24.04 |
Base OS. Required: the vendor binaries link GLIBC_2.38 and GLIBCXX_3.4.32, so Ubuntu 22.04 / Debian 12 are too old. |
layer-vshell.tar.gz |
dpkg -i of the vendor .deb, plus openssl (for the runtime self-signed PKCS#12 certificate) and the container entrypoint. |
Runtime dependencies are the ones the vendor binaries actually link against:
libpam0g, libpam-modules, libpam-runtime (password/keyboard-interactive
auth), libuuid1, zlib1g, libstdc++6, libaudit1, libcap-ng0. All are
already part of ubuntu:24.04; openssl is the only added package.
Systemd units shipped by the vendor are not used — there is no init system in
the image. docker/entrypoint.sh starts the three daemons and supervises them.
Run
docker run -d --name vshell \
-p 22:22 -p 21:21 -p 990:990 -p 80:80 -p 443:443 \
-v /srv/vshell/vshelld_config:/usr/local/etc/vshelld_config \
-v /srv/vshell/vshell-https.p12:/usr/local/etc/vshell-https.p12 \
-v /srv/vshell/vshelld_hostkey:/usr/local/etc/vshelld_hostkey \
gitea.milesward.dev/mward4/vshell:5.0.1-3985
On first start the entrypoint seeds vshelld_config and vshelld_primes.txt
from the vendor defaults, generates a self-signed PKCS#12 certificate when
/usr/local/etc/vshell-https.p12 is absent, and appends the listen addresses
below unless the mounted configuration already defines HTTPSListenAddresses.
| Port | Service | Env override |
|---|---|---|
| 22/tcp | SSH2 / SFTP (vshelld) |
VSHELL_SSH_ADDR |
| 21/tcp | explicit FTPS (vshell-ftpsd) |
VSHELL_FTPS_EXPLICIT_ADDR |
| 990/tcp | implicit FTPS (vshell-ftpsd) |
VSHELL_FTPS_IMPLICIT_ADDR |
| 80/tcp | HTTP, redirects to HTTPS (vshell-httpsd) |
VSHELL_HTTP_ADDR |
| 443/tcp | HTTPS file transfer (vshell-httpsd) |
VSHELL_HTTPS_ADDR |
Other env vars: VSHELL_CONFIG (default /usr/local/etc/vshelld_config) and
VSHELL_TLS_P12 (default /usr/local/etc/vshell-https.p12).
Mount individual files rather than a whole volume at /usr/local/etc: that
directory also holds the vendor defaults, the Diffie-Hellman primes file and the
HttpsFiles/ web assets, which an empty volume would hide. Persist
vshelld_config and vshelld_hostkey to keep the server identity stable across
restarts.
VShell requires a license; the image starts on the shipped 60-day evaluation
license (valid until 2026-12-04). Check with vshelld -license, install a
license file and point LicenseFilePath at it for production.
Build
Canonical build (needs Docker or Podman):
docker build -t vshell:5.0.1-3985 .
This repository also builds without a container runtime — the path used to
produce the published image — by installing the .deb into an extracted
ubuntu:24.04 rootfs and turning the diff into an image layer:
node tools/fetch-base.mjs # ubuntu:24.04 -> /tmp/vshell-base
mkdir -p /tmp/vshell-rootfs && tar -xzf /tmp/vshell-base/layer-00.tar -C /tmp/vshell-rootfs --numeric-owner
docker/install-rootfs.sh /tmp/vshell-rootfs # dpkg -i + openssl + entrypoint (see script)
tools/validate.sh /tmp/vshell-rootfs # binaries, config, all five listeners
mkdir -p /tmp/vshell-pristine && tar -xzf /tmp/vshell-base/layer-00.tar -C /tmp/vshell-pristine --numeric-owner
node tools/build-image.mjs --rootfs /tmp/vshell-rootfs --pristine /tmp/vshell-pristine \
--base /tmp/vshell-base --out dist --tag vshell:5.0.1-3985,vshell:latest
GITEA_TOKEN=... node tools/push-image.mjs --registry https://gitea.milesward.dev \
--repo mward4/vshell --user mward4 --summary dist/image-summary.json
tools/build-image.mjs writes dist/layer-vshell.tar.gz, dist/config.json,
dist/manifest.json, dist/image-summary.json and an OCI layout under
dist/oci/. tools/push-image.mjs uploads the referenced blobs (including the
official ubuntu:24.04 layer) and the schema-2 manifest, then reads the manifest
back and compares digests.
Validation
tools/validate.sh <rootfs> starts the image's own entrypoint inside a
user-namespace chroot on high ports and probes every listener from outside:
SSH banner, FTPS banner, HTTPS/TLS handshake, implicit FTPS handshake and the
HTTP→HTTPS redirect, after checking -version, -test_config and -license.
Licensing
VShell is commercial, closed-source software distributed under the VanDyke
Software EULA (see /usr/share/doc/vshell-5.0.1/vshell_eula.pdf in the image).
The vendor .deb is vendored here only to make the image build reproducible and
the Gitea repository/package is kept private. Do not publish the image or the
.deb publicly.