Skip to content

Instantly share code, notes, and snippets.

@Jip-Hop
Last active February 1, 2026 16:16
Show Gist options
  • Select an option

  • Save Jip-Hop/0b3bb9e2c63300297471c122b44a8d41 to your computer and use it in GitHub Desktop.

Select an option

Save Jip-Hop/0b3bb9e2c63300297471c122b44a8d41 to your computer and use it in GitHub Desktop.
Ansible Vault + Docker Compose

Before developing ojster I decrypted my environment variables with ansible-vault and injected them when running docker compose up. While this worked I found it had several downsides.

  • You can't see which environment variables (keys) are present in the vault, unless you decrypt the entire vault
  • You need the private key to add new environment variables
  • This approach requires wrapping around the docker compose up command
  • The decrypted environment variable values end up in the container spec and may leak (visible via docker inspect, Portainer, logs etc.)

So I tried to migrate my secrets to native file based Docker secrets, but this has 2 issues:

  1. You can't safely manage Docker secrets through Git
  2. Many images expect secrets as environment variables instead of files

All of these issues have been addressed with ojster: GitOps-safe one-way encrypted secrets, unsealed at container runtime as ephemeral env vars, for Docker Compose.

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# Inspired by:
# https://github.com/romantomjak/env-vault
VAULT_PATH=./ansible_vault
VAULT_PASSWORD_FILE=/path/to/ansible_vault_password_file
cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" # cd current directory
# Decrypt the vault and export as env variables
while IFS= read -r line; do
# Skip empty lines or comments
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
# Accept only: VAR='value'
# VAR: uppercase letters, digits, underscore
# VALUE: anything except an unescaped single quote
if ! [[ "$line" =~ ^([A-Z0-9_]+)=\'(.*)\'$ ]]; then
echo "Rejected unsafe or invalid line: $line" >&2
exit 1
fi
var="${BASH_REMATCH[1]}"
val="${BASH_REMATCH[2]}"
# Export safely (no code execution possible)
export "$var=$val"
done < <(docker run --user 65534:65534 \
--rm --network none \
--cap-drop=ALL \
--tmpfs /.ansible/tmp \
-v "$VAULT_PATH":/mnt/vault \
-v "$VAULT_PASSWORD_FILE":/mnt/password_file \
--env ANSIBLE_VAULT_PASSWORD_FILE=/mnt/password_file \
--env USERNAME=ansible \
--entrypoint='' \
ghcr.io/ansible/community-ansible-dev-tools:v25.12.0 \
ansible-vault decrypt /mnt/vault --output=-)
# The populated env variables will be available inside the compose files
# They also override any env variables set inside .env files!
docker compose up --detach --remove-orphans --build --always-recreate-deps --quiet-pull
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment