skip to Main Content

To be brief I’m struggling persisting the data saved in a vault container in my local machine after I put a docker-compose down and re-deploy it with docker-compose up -d, the data is lost. I’ll show you how my .yml looks like very simple:

version: '3.7'

services:
  vault_dev:
      image: vault:latest
      volumes:
        - vault-file:/vault/file
      ports:
        - "8200:8200/tcp"
      environment:
        VAULT_DEV_ROOT_TOKEN_ID: 'root'
        VAULT_DEV_LISTEN_ADDRESS: '0.0.0.0:8200'
      cap_add:
        - IPC_LOCK
      container_name: vault_dev
      entrypoint: "vault server -dev"

volumes:
     vault-file: {}

2

Answers


  1. When Vault is started with the -dev option it stores secrets in memory only. They are lost when it shuts down. Nothing to do with Docker.

    You probably want to remove the -dev option in your Dockerfile entrypoint and use file storage option in your configuration file.

    Login or Signup to reply.
  2. Using production Vault server in docker-compose for local development is not convenient, because you have to unseal it often, typically every time the container is restarted.

    I find it much easier to use the Vault dev server mode with one additional bootstrapping container that is initializing the Vault state as I need it.

    Here’s how to do it. First define the Vault Dev Server in compose.

    • It is automatically unsealed
    • It has Vault UI accessible at http://localhost:8200/ui/vault from your dev machine
    • It has predefined root token with value "root", that can be given to services which need to communicate with the Vault

    docker-compose.yml

    vault:
        hostname: vault
        container_name: vault
        image: vault:1.12.0
        environment:
          VAULT_ADDR: "http://0.0.0.0:8200"
          VAULT_API_ADDR: "http://0.0.0.0:8200"
        ports:
          - "8200:8200"
        volumes:
          - ./volumes/vault/file:/vault/file:rw
        cap_add:
          - IPC_LOCK
        entrypoint: vault server -dev -dev-listen-address="0.0.0.0:8200" -dev-root-token-id="root"
    

    Now the Vault is ready for use but it’s empty – no keys or additional secret engines are enabled. To fill it with the necessary data I use a second container which is started just once and is enabling/creating the engines/keys which will be used during my work.

    docker-compose.yml

      vault-init:
        container_name: vault-init
        image: vault:1.12.0
        volumes:
          - ./vault-init.sh:/vault-init.sh
        depends_on:
          - vault
        restart: "no"
        entrypoint: sh -c "/vault-init.sh"
    

    This container is executing a vault-init.sh script which I have prepared in a directory (in this example it’s the same dir as the docker-compose file, but you can place it in another and change the mount path). The script is making the following steps:

    • login to Vault
    • enable Vault transit engine
    • create two keys inside the engine with specific names and types
    #! /bin/sh
    
    set -e
    
    export VAULT_ADDR=http://vault:8200
    
    # give some time for Vault to start and be ready
    sleep 3
    
    # login with root token at $VAULT_ADDR
    vault login root
    
    # enable vault transit engine
    vault secrets enable transit
    
    # create key1 with type ed25519
    vault write -f transit/keys/key1 type=ed25519
    
    # create key2 with type ecdsa-p256
    vault write -f transit/keys/key2 type=ecdsa-p256
    

    After you start it with docker-compose up -d you can open the Vault UI with a browser and verify that the Vault is in the state that you desire: http://localhost:8200/ui/vault

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search