Terms of useLicensing

FExec is distributed under a proprietary license (© TBSS Ltd):

  • Free for personal, non-commercial use — research, learning, testing, hobby projects.
  • Commercial use requires a separate written agreement with TBSS Ltd, obtained prior to any commercial use.
  • No source code is provided by default; source may be disclosed at TBSS Ltd's discretion for independent security review.

Read the full text in LICENSE on GitHub, or contact TBSS Ltd to discuss a commercial agreement.

Python packagePyPI

Package name: fexec — pypi.org/project/fexec

pip install fexec

Installs the fexecd command. See the Overview and Configuration pages, or README.md on GitHub, to get it running.

PyPI has no mechanism for hosting a signature alongside a wheel — to verify one, download its matching signature bundle from the GitHub Release instead.

Container imagesDocker Hub

Repository: hub.docker.com/r/jnitecki/fexec

Minimal setup

alias.d and auth.d are mounted writable, not read-only — FExec watches both for live changes and reloads them without a restart, so the mount needs to stay writable for that to be useful. The Docker socket is mounted so FExec (itself running in a container here) can start sibling containers for container-type aliases — skip it only if every alias is process-type, which would be unusual in a Docker deployment. SharedDir is mounted and set explicitly via FEXEC_SHARED_DIR; FEXEC_EXTERNAL_DIR gives FExec the host-side path of that same mount, since it's the host's Docker daemon — not this container — that resolves volume mounts for the sibling containers FExec starts.

docker run -d \
  -p 8080:80 \
  -v $(pwd)/alias.d:/etc/fexec/alias.d \
  -v $(pwd)/auth.d:/etc/fexec/auth.d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(pwd)/shared:/tmp/fexec \
  -e FEXEC_SHARED_DIR=/tmp/fexec \
  -e FEXEC_EXTERNAL_DIR=$(pwd)/shared \
  jnitecki/fexec:latest

Production setup — TLS and persistent logs

Builds on the minimal setup: SSL enabled with the certificate/key mounted read-only (unlike alias.d/auth.d, TLS settings aren't live-reloaded — see Configuration), and LogDir mounted so AuditLog/AppLog, and anything using Volume or Stream Preserve, survive past the container's own lifetime.

docker run -d \
  -p 8443:443 \
  -v $(pwd)/alias.d:/etc/fexec/alias.d \
  -v $(pwd)/auth.d:/etc/fexec/auth.d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(pwd)/shared:/tmp/fexec \
  -v $(pwd)/ssl:/etc/fexec/ssl:ro \
  -v $(pwd)/logs:/var/log/fexec \
  -e FEXEC_SHARED_DIR=/tmp/fexec \
  -e FEXEC_EXTERNAL_DIR=$(pwd)/shared \
  -e FEXEC_SSL_ENABLED=true \
  -e FEXEC_SSL_CERT=/etc/fexec/ssl/server.crt \
  -e FEXEC_SSL_KEY=/etc/fexec/ssl/server.key \
  jnitecki/fexec:latest

Config-file-driven setup

Same deployment as above, but with fexec.conf itself mounted read-only instead of setting each option via -e. Read-only is appropriate here — unlike alias.d/auth.d, fexec.conf is only ever read at startup and needs a container restart to pick up changes either way.

docker run -d \
  -p 8443:443 \
  -v $(pwd)/fexec.conf:/etc/fexec/fexec.conf:ro \
  -v $(pwd)/alias.d:/etc/fexec/alias.d \
  -v $(pwd)/auth.d:/etc/fexec/auth.d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(pwd)/shared:/tmp/fexec \
  -v $(pwd)/ssl:/etc/fexec/ssl:ro \
  -v $(pwd)/logs:/var/log/fexec \
  jnitecki/fexec:latest
# ListenPort, SharedDir, ExternalDir, SslEnabled, SslCert, SslKey, and
# LogDir/AuditLog/AppLog are all set inside fexec.conf instead of via -e —
# see the Configuration page for the file format.

Alpine is the default OS variant — latest and X.Y.Z are Alpine-based, identical to their -alpine-suffixed equivalents:

TagBaseNotes
latest, alpinepython:3.13-alpinerolling, tracks the newest release
X.Y.Z, X.Y.Z-alpinepython:3.13-alpinepinned release
ubuntupython:3.13-slimrolling
X.Y.Z-ubuntupython:3.13-slimpinned release

All tags are published as multi-arch manifests (linux/amd64 + linux/arm64).

Verifying an image

Every published image is signed with cosign. cosign.pub is published in the GitHub repository's root.

cosign verify --key cosign.pub docker.io/jnitecki/fexec:<tag>

Secondary — source & wheel verificationGitHub

The public repository mirrors README, CONFIGURATION.md, HOWTO.md, SECURITY.md, LICENSE, and the cosign verification key, and hosts tagged releases — used less for installing FExec directly and more as the place source-adjacent docs and signature material live, including for anyone who wants to verify a published wheel.

Verifying a wheel

PyPI has no mechanism for hosting a signature alongside a wheel, so wheels are signed as blobs instead: each release wheel and its matching <wheel>.sigstore.json bundle are both published as assets on the corresponding tagged GitHub Release. Download both, then:

cosign verify-blob --key cosign.pub --bundle <wheel>.sigstore.json <wheel>

See SECURITY.md for full details and vulnerability reporting.