docker stack: setting environment variable from secrets
I found this neat extension to Alejandro's approach: make your custom entrypoint load from ENV_FILE
variables to ENV
ones:
environment:
MYSQL_PASSWORD_FILE: /run/secrets/my_password_secret
entrypoint: /entrypoint.sh
and then in your entrypoint.sh
:
#!/usr/bin/env bash
set -e
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
file_env "MYSQL_PASSWORD"
Then, when the upstream image changes adds support for _FILE
variables, you can drop the custom entrypoint without making changes to your compose file.
You need modify docker compose to read the secret env file from /run/secrets
. If you want to set environment variables via bash
, you can overwrite your docker-compose.yaml
file as displayed below.
You can save the following code as entrypoint_overwrited.sh
:
# get your envs files and export envars
export $(egrep -v '^#' /run/secrets/* | xargs)
# if you need some specific file, where password is the secret name
# export $(egrep -v '^#' /run/secrets/password| xargs)
# call the dockerfile's entrypoint
source /docker-entrypoint.sh
In your docker-compose.yaml
overwrite the dockerfile
and entrypoint
keys:
version: '3.1'
#...
build:
context: ./test
dockerfile: Dockerfile
entrypoint: source /data/entrypoint_overwrited.sh
tmpfs:
- /run/secrets
volumes:
- /path/your/data/where/is/the/script/:/data/
environment:
user_name: admin
eureka_password: /run/secrets/password
secrets:
- password
Using the snippets above, the environment variables user_name
or eureka_password
will be overwritten. If your secret env file defines the same env vars, the same will happen if you define in your service some env_file
.
To elaborate on the original accepted answer, just change your docker-compose.yml file so that it contains this as your entrypoint:
version: "3.7"
services:
server:
image: alpine:latest
secrets:
- test
entrypoint: [ '/bin/sh', '-c', 'export TEST=$$(cat /var/run/secrets/test) ; source /entrypoint.sh' ]
secrets:
test:
external: true
That way you don't need any additional files!