Skip to content

Instantly share code, notes, and snippets.

@0xMurage
Created September 10, 2025 19:04
Show Gist options
  • Select an option

  • Save 0xMurage/09ef2435ba195213b21b7a287986b0f6 to your computer and use it in GitHub Desktop.

Select an option

Save 0xMurage/09ef2435ba195213b21b7a287986b0f6 to your computer and use it in GitHub Desktop.
HashiCorp Vault Docker Compose Examples

Examples of running HashiCorp Vault or OpenBao with different storage backends.

  1. File Storage Backend (compose.file.yaml) This is the simplest configuration, using the filesystem for storage. It's ideal for a single-node developer setup.

  2. Raft Storage Backend (compose.raft.yaml) The provided configuration is for a single-node setup, which simplifies the example while demonstrating the required configuration. This backend is often used for high-availability clusters (3+ nodes).

  3. PostgreSQL Storage Backend (compose.postgres.yaml) This example shows how to run a Vault instance that connects to a separate PostgreSQL container for its storage. The example above is set up for single node but can be scaled to multiple nodes.

services:
openbao:
image: docker.io/openbao/openbao:2.4
restart: unless-stopped
command: ["server"]
cap_add:
- IPC_LOCK # Required for memory locking
healthcheck:
test: [ "CMD", "vault", "status" ]
interval: 30s
timeout: 10s
retries: 5
ports:
- "8200:8200"
environment:
BAO_LOCAL_CONFIG: '{"storage": {"file": {"path": "/openbao/file/raft/data"}},"listener": [{"tcp": { "address": "0.0.0.0:8200", "tls_disable": true}}] }'
VAULT_UI: true
VAULT_LOG_LEVEL: info
BAO_ADDR: http://0.0.0.0:8200 #required by health check or running vault command inside the container
services:
postgresdb:
image: docker.io/library/postgres:16.9-alpine3.22
restart: unless-stopped
healthcheck:
test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
networks:
- vault_backend
environment:
POSTGRES_PASSWORD: somesecretpassword
POSTGRES_USER: vault_owner
POSTGRES_DB: vaultdb
openbao:
image: docker.io/openbao/openbao:2.4
restart: unless-stopped
command: ["server"]
cap_add:
- IPC_LOCK # Required for memory locking
healthcheck:
test: [ "CMD", "vault", "status" ]
start_period: 30s
interval: 30s
timeout: 10s
retries: 5
ports:
- "8200:8200"
networks:
- vault_backend
environment:
BAO_LOCAL_CONFIG: '{"storage": {"postgresql": {}},"listener": [{"tcp": { "address": "0.0.0.0:8200", "tls_disable": true}}] }'
VAULT_UI: true
VAULT_LOG_LEVEL: info #warn or err or debug
BAO_ADDR: http://0.0.0.0:8200 #required by health check or running vault command inside the container
BAO_API_ADDR: http://0.0.0.0:8200
VAULT_PG_CONNECTION_URL: postgres://vault_owner:somesecretpassword@postgresdb:5432/vaultdb?sslmode=disable&search_path=public
networks:
vault_backend:
services:
openbao:
image: docker.io/openbao/openbao:2.4
restart: unless-stopped
command: ["server"]
cap_add:
- IPC_LOCK # Required for memory locking
healthcheck:
test: [ "CMD", "vault", "status" ]
interval: 30s
timeout: 10s
retries: 5
ports:
- "8200:8200"
environment:
BAO_LOCAL_CONFIG: '{"storage": {"raft": {}},"listener": [{"tcp": { "address": "0.0.0.0:8200", "tls_disable": true}}] }'
VAULT_UI: true
VAULT_LOG_LEVEL: warn
BAO_ADDR: http://0.0.0.0:8200 #required by health check or running vault command inside the container
#Following are required since raft is HA
BAO_API_ADDR: http://0.0.0.0:8200
BAO_CLUSTER_ADDR: https://127.0.0.1:8201
VAULT_RAFT_PATH: /openbao/file/
VAULT_RAFT_NODE_ID: 0
# Example of how to [lazily] utilize envconsul to read vault values
# Ensure .env.stack file exists on host machine before running this services
# Don't forget to update the secret path `peacock/data/production` accordingly, ()
# Peacock service is included to demonstrate how to await env-init sidecar
services:
peacock-env-init:
image: hashicorp/envconsul:0.13.4
command: [ 'envconsul', '-pristine', '-vault-renew-token=false', '-no-prefix=true', '-secret=peacock/data/production', '--', 'printenv', '>/home/envconsul/env.output' ]
restart: unless-stopped
volumes:
- ./.env.stack:/home/envconsul/env.output
environment:
- VAULT_ADDR=${VAULT_ADDR}
- VAULT_TOKEN=${VAULT_TOKEN}
peacock:
image: alpine:3.22.1
depends_on:
peacock-env-init:
condition: service_completed_successfully
env_file:
- .env.stack
@0xMurage
Copy link
Author

Envconsul supports multiple secret paths and also env variables using Go templates i.e.

services:
  peacock-env-init:
    image: hashicorp/envconsul:0.13.4
    command: [ 'envconsul', '-pristine', '-vault-renew-token=false', '-no-prefix=true', '-secret={{ env "SECRET_PATH1" }}',  '-secret={{ env "SECRET_PATH2" }}',  '--', 'printenv',  '>/home/envconsul/env.output' ]
    restart: unless-stopped
    environment:
      - VAULT_ADDR=${VAULT_ADDR}
      - VAULT_TOKEN=${VAULT_TOKEN}
      - SECRET_PATH1=peacock/data/production
      - SECRET_PATH2=disney/data/production

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment