-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set password and other options via ENV variable #46
Comments
In the mean time you could check out tutumcloud/redis which supports this, and much much more. |
We don't supply a config file, so that would be up to you to just |
@yosifkit copying a config file at build time isn't dynamic. Many scenarios involve creating a config template, passing environment variables and generating a configuration file in the entrypoint. This isn't a good solution. |
tutumcloud/redis is going to be deprecated soon. This alternative looks interesting: https://github.com/bitnami/bitnami-docker-redis |
@oryband That is a nice one, thank you very much! Going to test this out |
I'm still not sure I'm understanding what the need here for additional complexity is, given that Redis itself supports supplying any of the configuration file options directly via the command-line, which I've just verified: $ docker run --name some-redis -d redis redis-server --requirepass foobared
896132042afb124aae06ea855e02da2a211bd0540a862f1d785b586a3bbc4479
$ docker run -it --link some-redis:redis --rm redis redis-cli -h redis -p 6379
redis:6379> AUTH test
(error) ERR invalid password
redis:6379> AUTH foobared
OK
redis:6379> This could be abstracted to an environment variable trivially via something like: $ docker run --name some-redis -d -e REDIS_PASSWORD=foobared redis sh -c 'exec redis-server --requirepass "$REDIS_PASSWORD"' |
Additionally to bake an image that supports that usage: FROM redis
ENV REDIS_PASSWORD default-password
CMD ["sh", "-c", "exec redis-server --requirepass \"$REDIS_PASSWORD\""] Combine that with automated builds (https://docs.docker.com/docker-hub/builds/) and repository links (https://docs.docker.com/docker-hub/builds/#repository-links) and it's reasonably easy to have an up-to-date image built |
Just for a bit of context, Dokku integrates with the "official" images provided by docker to give developers access to various popular datastores. We use internal networking by default - safer on infra where there isn't private networking, like DigitalOcean - requiring that users manually expose the datastores for remote access. In the case where a user wants to expose a service publicly, even a bit of protection is nice, and where possible we default to requiring a password for a datastore anyhow. Redis is the only one where we can't do that without:
It would be nice if we could set an environment variable for the password, as then we can easily integrate password protection and provide our users a modicum of security. See dokku/dokku-redis#58 for (a lot less) detail. |
@josegonzalez, It would not have to be in the clear on the command line. 😄
|
Wouldn't that show up in the output of docker inspect? I suppose providing an env file would be the same, but at least it wouldn't be in the command inspect output. |
The "--env-file" feature is client-side-only; it parses the file and passes
the relevant "environment" options directly, so they'll still appear in the
"docker inspect" output.
|
FWIW, both the I think this makes for a nicer evaluation experience. It's simple to plug a When I first look at an available docker image, one of the next things I do is look at how flexible it is and what it can do via I've seen images accept an entire config via |
@anthonyrisinger, $ # postgres
$ docker run --name pg -d postgres -c max_connections=200 -c shared_buffers=1GB -c effective_cache_size=3GB -c work_mem=5242kB -c maintenance_work_mem=256MB -c min_wal_size=1GB -c max_wal_size=2GB -c checkpoint_completion_target=0.7 -c wal_buffers=16MB -c default_statistics_target=100
$ # mysql
$ docker run --name sql -d -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci Redis is basically the same but allows all of its config via flags, including password. $ docker run --name red -d redis --slaveof 10.0.0.2 6379 --requirepass secret Doing the same via docker-compose: version: "2"
services:
postgres:
image: postgres
command: >
-c max_connections=200
-c shared_buffers=1GB
-c effective_cache_size=3GB
-c work_mem=5242kB
-c maintenance_work_mem=256MB
-c min_wal_size=1GB
-c max_wal_size=2GB
-c checkpoint_completion_target=0.7
-c wal_buffers=16MB
-c default_statistics_target=100
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: my-secret-pw
command: >
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
redis:
image: redis
command: >
--slaveof 10.0.0.2 6379
--requirepass secret How are flags to |
@yosifkit I acknowledge you can get there with I like the declarative aspect of I might be old-fashioned or in the minority here, I'm not sure. What say you? (whynotboth)? |
It would be nice to have a way to use Docker secrets to read from /run/secrets/redis-pass and set the redis --requirepass flag. For example: On a swarm manager set the redis-pass, then use docker stack deploy -c docker-compose-prod.yml appname
|
We need some more love for Redis :) MariaDB has this since almost a year: MariaDB/mariadb-docker@6452a88 |
I am still against adding env vars for config since a) it is easy to add to @amq, here is a solution for using a secret with the cli flag. I did it with a volume, but a secret should be the same by swapping out the volume and adding in the yaml for the secret. version: '3.1'
services:
redis:
image: redis:4.0.2
volumes:
- './secret:/run/secrets/redis-pass'
environment:
REDIS_PASS_FILE: /run/secrets/redis-pass
command: [
"bash", "-c",
'
docker-entrypoint.sh
--requirepass "$$(cat $$REDIS_PASS_FILE)"
'
] |
@yosifkit I'm only asking for the secret support of the password env var. I agree that using secrets for all env configuration is unnecessary. |
@yosifkit thank you ,great!
|
In case anyone wonders if tianon's solution would work with kubernetes secrets as well... It works. I just tested it. You can use a password for redis from a secret like this:
|
i think the best way for docker-compose set .env
check with
|
Inspired by @yosifkit I've ended up with something more robust:
This allows you to use all characters in the secret file (except null), or to not set the password when the environment variable is empty or unset (useful for development). |
so i now what to use redis on my kubernetes cluster and first need to build my own image to be able to get the password in it via kubernetes secrets? really? this should be in the box by default |
@davesmits there is possibility to override command in pod manifest, see https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/ You could inject secret to environment variable and then pass it to My custom example may not apply to you: containers:
- name: redis
image: my-custom-redis-image
command: ["redis-server", "/etc/redis.conf", "--requirepass", "$(REDIS_PASSWORD)"]
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-password
key: password |
Providing a password should be easy and documented directly in the README! Otherwise you risk thousands of lazy sysadmins exposing their images to the wild without any protection. Please add this feature soon! |
I ended up extending this image and adding support for FROM redis:5-alpine
RUN sed -e '3i\\nif [ -n "$REDIS_PASSWORD" ]; then set -- "$@" --requirepass "$REDIS_PASSWORD"; fi' -i /usr/local/bin/docker-entrypoint.sh The main reason being the ability to use |
Surprisingly the `redis` image doesn't have a nicer way of setting the `redis-server` password and ignores the `REDIS_PASSWORD` environment variable. This was causing the `ERR Client sent AUTH, but no password is set` error (as the client still passed the password correctly). This change overrides the image command and set the password. See open issue and solution: redis/docker-library-redis#46 (comment)
This works but I was so confused why Reference link: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#use-environment-variables-to-define-arguments I believe since the option to set the password and other options as environment variable is already available (explained above), we can close this issue. |
So I'm fine with the solutions in this, but request to the maintainers, can you put the CLI example in the README for the container? |
FYI I use this to fix this issue and support container with and without PW that extend from this common container:
|
For most cases, I'd suggest using a configuration file instead of the $ docker pull redis
Using default tag: latest
latest: Pulling from library/redis
Digest: sha256:7b84b346c01e5a8d204a5bb30d4521bcc3a8535bbf90c660b8595fad248eae82
Status: Image is up to date for redis:latest
docker.io/library/redis:latest
$ docker run -dit --name test redis
0cea7b89a839e45e0f61bc887f2879bfdbb0bf6a974963a82560c433027d58e5
$ docker logs test
1:C 05 Feb 2020 20:33:47.217 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 05 Feb 2020 20:33:47.217 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 05 Feb 2020 20:33:47.217 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
...
$ docker exec -i test redis-cli config get '*' > before.txt
$ docker rm -vf test
$ docker run -dit --name test redis --requirepass test
19805af3d5f4c4129d80606820030222dc6e627c5fde622c9399ee8715a55cd0
$ docker logs test
1:C 05 Feb 2020 20:35:35.670 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 05 Feb 2020 20:35:35.670 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 05 Feb 2020 20:35:35.670 # Configuration loaded
...
$ docker exec -i test redis-cli -a test config get '*' > after.txt
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
$ diff -u before.txt after.txt
--- before.txt 2020-02-05 12:35:09.375349180 -0800
+++ after.txt 2020-02-05 12:36:20.157339827 -0800
@@ -1,7 +1,7 @@
dbfilename
dump.rdb
requirepass
-
+test
masterauth
cluster-announce-ip
@@ -201,7 +201,7 @@
dir
/data
save
-3600 1 300 100 60 10000
+
client-output-buffer-limit
normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60
unixsocketperm |
Whats being configured with |
@SuperSandro2000, that is the |
Can we set the save value via the command line? I kinda want to avoid doing a config file. |
You can, yes. My point is simply that if this one changes in that way,
there might be others in the future, so it's something to be aware of (and
using a full config file is the easiest way I know of to avoid that
potential issue).
|
@yosifkit Why is the environment variable REDIS_PASS_FILE required? Why will it not it just accept just the path in its place? I tried swapping its value in and it failed and I'm curious as to why it's failing.
|
@paulcalabro,
Did you also mount in a file with a single line of text or set up a secret to use? |
@yosifkit I did create a secret and associate it with the service. Sounds like it might be a bug on my end. I'll troubleshoot it further. Thanks for confirming it's not not subtlety I'm missing. |
This is a "Docker image" that does not support "Docker secrets" feature. In the meantime, this should work for now: |
Given #46 (comment) (TLDR: adding any flag or config file loses the redis defaults), we will not be adding support for an It is relatively easy to add support for your own needs to use a file or direct env variable: #46 (comment) / #46 (comment) |
#46 is not a solution. It offers to map a volume and then read the password from that file. The whole idea of docker secrets is to not save a password in a file on the host. |
Can this be revisited now that it sounds like the issue causing this behavior in Redis has been addressed since 6.2? See: redis/redis#7092 |
Passing the password through the command line parameter is not secure, cause every user on the server can get the password through the |
Indeed, environment variables are slightly more obscure, but similarly
insecure (which is why Docker's "Secrets" feature only supports files).
If you want to store your password securely, I would highly recommend a
proper config file with appropriate filesystem permissions.
|
Can someone put forward recommended security configuration for Docker, Kubernetes and Consul/Vault? |
FWIW, as of Redis 6, the recommended approach to users' management is via the Access Control List mechanism and an external file with the defined permissions. In this context, the file can be stored on the host and mounted to the container. |
@tianon , thanks for the comment. I think if documentation at https://hub.docker.com/_/redis could be updated, it would be nice. I usually just search in google "docker run <whatever i want (redis|mysql etc...)>" and first website that pops up is hub.docker.com. So, more documentation there (or a link to all supported configuration in redis website) will help. |
It would be awesome if it would be possible to set the Password via an ENV variable. Is this planned any time soon or maybe even already possible?
Of course it would even more awesome when we could set other parameters as well 👍
The text was updated successfully, but these errors were encountered: