Problem: I can manage my entire Docker Compose stack with Git, except secrets.
Solution: Encrypt your secrets using Ojster and safely store them in Git — even inside a public repository. Values can only be decrypted by the server holding the private key.
Docker Compose workflows commonly rely on environment variables. Even when encrypted with tools like Ansible Vault, Dotenvx, or env-vault, decrypted values often end up embedded in container specs, visible in management UIs (Docker Desktop, Portainer), or leaked via docker inspect, logs, or image metadata.
Ojster closes this gap. It is a companion to Dotenvx that enables zero-trust, ephemeral secrets for Docker Compose, ideal for self-hosting prebuilt images in a GitOps workflow. Decryption happens just in time during container startup and remains exclusively in memory under strict least-privilege constraints.
Get ready to BYOB and safely store encrypted secrets in Git.
Ojster is in an early-stage, pre-release phase. Expect breaking changes as the design evolves, security hardening improves, and real-world feedback shapes the API and integration model. The core concepts are stable, but details may change between versions. Review release notes before upgrading.
On the server that hosts your Docker containers:
git clone https://github.com/ojster/ojster
cd ojster
# Add some env vars
echo EXAMPLE1=1234 > .env
echo EXAMPLE2=HelloWorld >> .env
# Encrypt env vars with the dotenvx CLI in a locked-down container
docker run -it --rm -v $(pwd):/app --workdir=/app --pull=always \
-u=64646:64646 --cap-drop=ALL --network=none \
--security-opt=no-new-privileges=true dotenv/dotenvx encrypt
# Verify encrypted and safe to store in Git
cat .env
# Build Your Own Binary
docker bake
# Bring up example stack
docker compose up -d
# See that the app has access to decrypted env vars
docker logs -f ojster_example_client
# Cleanup
docker compose down
Add the 4-line snippet (marked OJSTER INTEGRATION in compose.yaml) to any service you want to integrate. Ojster acts as a lightweight docker-init replacement and injects decrypted values at process start — no need to modify entrypoints, commands, or rebuild images.
If you’re familiar with Kubernetes, Ojster is the closest conceptual match to Bitnami Sealed Secrets — but for Docker Compose.
Shared principles:
Sealed Secrets uses a Kubernetes controller. Ojster applies the same pattern to Docker Compose using a lightweight client and a hardened decryption server.
Ojster encryption is currently “powered by” Dotenvx, but the projects are not officially affiliated. See Dotenvx docs for usage instructions. The table below compares Ojster to plain Dotenvx and Docker secrets.
| Feature | Ojster | dotenvx runoutside container |
dotenvx runinside container |
Docker secrets |
|---|---|---|---|---|
| Secure secrets in Git | ✅ | ✅ | ✅ | ❌ |
| Encrypted env vars in container spec |
✅ | ❌ | ⚠️ | ❌ |
| Unmodified container image |
✅ | ✅ | ❌ | ✅ |
| Native Docker Compose | ✅ | ❌ | ✅ | ✅ |
| Air-gapped private key access |
✅ | ❌ | ❌ | N/A |
| 0 third-party runtime dependencies (client side) |
✅ | ✅ | ❌ | ✅ |
| Image size increase | N/A | N/A | ~50 MB | N/A |
Interpretation
dotenvx run outside container calling docker compose up still places decrypted values into container specs (visible to orchestration tooling), requires wrapping around Compose commands, and is not air-gapped (e.g. to prevent a malicious dependency from data exfiltration).dotenvx run inside container requires shipping decryption tooling in each image (823 third-party dependencies) and exposes keys to all containers, increasing attack surface and image size. The official walkthrough sets the private key as plaintext env var in the container spec.Ojster does not provide the feature set of a full secrets platform. If that’s what you need, consider:
OJSTER_REGEX (configurable).key → encrypted value map to the Ojster server over the Unix domain socket..env, symlink .env.keys.dotenvx get -o (configurable) to decrypt in memory.execs the real entrypoint.statfsSecurely provision the private key on the Ojster server host. Only the Ojster server should ever have access to the private key. Access to the ojster volume (which contains the IPC socket file) is equivalent to the ability to request decryptions: any process that can open the socket can talk HTTP to the server and obtain decrypted values. Treat the socket like a sensitive IPC endpoint.
chmod 600 and ownership matching UID/GID running the Ojster server.no-new-privileges, no DNS, no outbound network access, immutable rootfs, tmpfs for tmp files.Contributing
./test.sh passes.Testing
export BUILDKIT_PROGRESS=plain
docker bake test # logs in ./log/test.log
License
Apache License 2.0.
Ojster (pronounced “oyster”) is a metaphor for a protective shell that keeps something valuable sealed away until the moment it’s needed. The J gives the name a distinctive, memorable twist while subtly nodding to its creator. Its nautical undertone fits naturally within the Docker ecosystem.