I have been trying to setup vault using docker composer file. I have three requirements,
- Make sure the secrets and other configurations created are persisted after a container restart
- Should be able to access the web ui of the vault
- Start the vault using the production mode
I tried these two configuration segments.
vault-server:
image: vault:latest
ports:
- "8204:8200"
environment:
VAULT_ADDR: "http://0.0.0.0:8204"
VAULT_DEV_ROOT_TOKEN_ID: "vault-plaintext-root-token"
cap_add:
- IPC_LOCK
volumes:
- ./vault/logs:/vault/logs
- ./vault/file:/vault/file:rw
vault_dev:
hostname: vault
container_name: vault
image: vault:latest
environment:
VAULT_ADDR: "http://0.0.0.0:8205"
VAULT_DEV_ROOT_TOKEN_ID: "vault-plaintext-root-token"
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8205"
ports:
- "8205:8200"
volumes:
- ./vault/files:/vault/file:rw
cap_add:
- IPC_LOCK
entrypoint: vault server -dev
My problems are;
- With the vault server configuration, I could access the vault UI with the url http://localhost:8204/ui/ but the secrets created are not retained after restart
- With the vault_dev configuration, (which I though would help me to start the vault in production mode when I remove the -dev command) I can't access the vault UI with the url http://localhost:8205/ui/
I really don't understand what is the difference between these two configuration segments and how to achieve step 1 and 3. For the persistence, since it says we need to add a volume, I tried mounting the file path, but still the content vanishes when the container is restarted. In some documents it says, in the dev mode you can't make it persist and have to run in prod mode. But I a, unable to figure out how modify the vault-server configuration set to make it run in prod mode.
Appreciate, if someone can help, as I have been going through several links for the past few days and kind of lost at the moment.
CodePudding user response:
I think what's causing your issue is VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8205"
.
That causes Vault to listen on port 8205 rather than the default 8200. So when you do that, you need to map port 8205 rather than 8200. That would look like this
ports:
- "8205:8205"
But when you run in a container, there's rarely any reason to change port numbers inside the container, since there's typically only one process running so it can't really conflict with anything. So I'd just let it listen on the default 8200 and map it to 8205 on the host.
I looked at the docs for VAULT_ADDR and I think you should delete that as well, unless you have multiple Vault nodes and a load balancer in front of them.
So you'll end up with
vault_dev:
hostname: vault
container_name: vault
image: vault:latest
environment:
VAULT_DEV_ROOT_TOKEN_ID: "vault-plaintext-root-token"
ports:
- "8205:8200"
volumes:
- ./vault/files:/vault/file:rw
cap_add:
- IPC_LOCK
entrypoint: vault server -dev
Then Vault should be reachable on http://localhost:8205/ui
.
CodePudding user response:
If you look at the Docker Hub page for the vault
image it documents:
Running the Vault container with no arguments will give you a Vault server in development mode.
/vault/file
[is used] for writing persistent storage data when using thefile
data storage plugin. By default nothing is written here (adev
server uses an in-memory data store); thefile
data storage backend must be enabled in Vault's configuration before the container is started.
(H/T @ChrisBecke who described this behavior in a comment; it is also in the well-commented Dockerfile.)
Later on that page is a section entitled "Running Vault in Server Mode for Development". The key point here is that you need to explicitly provide a command: vault server
to cause it to not start up in dev mode.
@HansKilian's answer on port setup is also important here. Incorporating that answer's simplifications and the need to explicitly run vault server
without -dev
, you should get something like:
version: '3.8' # most recent stable Compose file format
services:
vault:
image: vault:1.12.2
environment:
VAULT_LOCAL_CONFIG: >-
{
"storage": {
"file": {"path": "/vault/file"}
},
"listener": [{
"tcp": {
"address": "0.0.0.0:8200",
"tls_disable": true
}
}],
"default_lease_ttl": "168h",
"max_lease_ttl": "720h",
"ui": true
}
ports:
- "8204:8200"
cap_add:
- IPC_LOCK
volumes:
- vault_file:/vault/file:rw
volumes:
vault_file:
The JSON block is copied from the documentation, which also notes
Disabling TLS and using the
file
storage backend are not recommended for production use.
The underlying Vault storage can't be usefully accessed from the host (if nothing else, it is encrypted) and I've chosen to store it in a named Docker volume instead.
Since this is not running in dev mode, you will need to go through the steps of initializing Vault, which will give you a set of critical credentials, and then you'll need to create user identities and add credentials to Vault. It sounds like you're not looking for a fully-automated setup here, so be aware that there are some manual steps involved with some "no really don't lose these keys" output.