Sign inSign up

cplieger/cert-converter

By cplieger

Updated about 16 hours ago

Automatically converts PEM certificates to PFX format whenever they renew.

Image
Security
0

10K+

cplieger/cert-converter repository overview

cert-converter

Automatically converts certificates between PEM and PFX whenever they renew. Set it and forget it.

What it does

Watches a certificate directory and keeps every enabled output format current for each certificate it finds. A PEM pair (<name>.crt plus <name>.key) becomes a PKCS#12 (.pfx) bundle; a PFX/P12 bundle becomes a PEM pair, a re-encoded bundle, or both; with both formats enabled a PEM source is also passed through verbatim, so one output tree serves every consumer whatever it accepts. RSA, ECDSA, Ed25519 and ML-DSA keys are all supported. A common use: your ACME client renews PEM certificates, but some of your apps only accept PFX (some Synology services, .NET apps, Windows-based tools). Point /input at the certificate directory and fresh PFX files appear on every renewal. The input can be any directory holding certificates, whatever wrote them. Each scan compares the artifacts already on disk against the ones the current inputs produce, so unchanged certificates are skipped; modern2023, modern2026, and legacy encoding profiles cover both current and older consumers.

Why this design
  • Distroless and rootless: runs on gcr.io/distroless/static-debian13:nonroot with no shell or package manager, minimizing the attack surface.
  • fsnotify with polling fallback: reacts to certificate changes in real time, and periodic full scans catch anything fsnotify misses (network mounts, edge cases), so renewals are never skipped.
  • Issuer-independent output paths: by default an artifact is keyed on the certificate's own directory name, not on the issuing CA's storage layout, so consumers keep working when the issuer changes (OUTPUT_LAYOUT=mirror preserves full paths instead).
  • Fail-loud on ambiguity: two inputs that would produce the same output name convert nothing and turn the container unhealthy, rather than this app guessing which certificate you meant.
  • Skip-unchanged read from the output itself: currency is decided by reading the artifact on disk rather than from a state file, so a rotated password or a changed encoder profile is picked up on the next scan while unchanged certificates cause no rewrite, keeping disk writes and output timestamps meaningful.
  • No HTTP server, no open ports: the container has zero network listeners; health is a file-based probe, so nothing is exposed to the network.

Pull

docker pull cplieger/cert-converter:latest

Also published to ghcr.io/cplieger/cert-converter with identical images and tags. Release versions are tagged vX.Y.Z alongside latest.

Quick start

# Example compose for cert-converter. See the README for all configuration options and hardening.
services:
  cert-converter:
    image: ghcr.io/cplieger/cert-converter:latest
    container_name: cert-converter
    restart: unless-stopped
    # Override with PUID/PGID in .env; defaults to 1000:1000.
    user: "${PUID:-1000}:${PGID:-1000}"  # must own the /output host dir

    environment:
      # Env is readable via `docker inspect`; PFX_PASSWORD_FILE (a mounted secret) is not.
      PFX_PASSWORD: "${PFX_PASSWORD:-}"  # set this or PFX_PASSWORD_FILE; empty is rejected
      # Orphaned output: warn (default, keeps it) | sync (deletes) | keep (silent).
      # Use sync only once /input is your single source of truth.
      OUTPUT_LIFECYCLE: "${OUTPUT_LIFECYCLE:-warn}"
      PFX_ENCODER: "modern2023"  # modern2023, modern2026, legacy, or legacyrc2

    volumes:
      - "/path/to/certificates:/input:ro"  # must be readable by the UID above; see README "Healthcheck"
      - "/path/to/converted/output:/output"

Documentation

License

GPL-3.0-or-later. See LICENSE. The image carries the license text of every bundled component under /usr/share/licenses/.

Tag summary

Content type

Image

Digest

sha256:eda5e2f3a

Size

3.3 MB

Last updated

about 16 hours ago

docker pull cplieger/cert-converter