Closed mickel8 closed 1 year ago
I believe that this is because
/data
directory is alwayschown
toredis:redis
no matter we are running as root or non-root. In case of running as non-root, some user (who is running docker) will try to write to the/data
where onlyredis
user can write.
We actually can't chown
as non-root :sweat_smile: That's why this check makes sure id -u
returns 0
:
My guess is that you probably ran this line without -u
in the past, and thus your myredis3
folder was already pre-chown
'd, so you need to run something like sudo chown -R (id -u):(id -g) myredis3
to fix it before this command will work.
What about this line
https://github.com/docker-library/redis/blob/master/7.0/Dockerfile#L112
Here, we chown
to redis:redis :thinking:
Shouldn't we write RUN mkdir /data
?
The directory in the image, yes, but that shouldn't "chown" your local directory.
But when I run redis with -u
and -v
, isn't this like I am trying to write something as host user to a directory owned by redis
user?
I don't fully get why we have to chown
/data
to redis:redis
in the Dockerfile :thinking: . When we run redis as root, then every file is chown
to redis in the entrypoint. When we run redis as non-root then only /data is chown
to redis in the dockerfile.
Because the entrypoint does a chown
on /data
if you run the image as root, if you ever did that before this line you've shared with us, it would've run chown
on it and you'd have to fix that before you run it again. I've just verified that this does work correctly and nothing is chown
'd if you run as non-root:
$ mkdir redis
$ docker run -it --rm --user "$(id -u):$(id -g)" -v "$PWD/redis":/data --name redis redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
26c5c85e47da: Already exists
39f79586dcf2: Pull complete
79c71d0520e5: Pull complete
60e988668ca1: Pull complete
873c3fc9fdc6: Pull complete
50ce7f9bf183: Pull complete
Digest: sha256:f50031a49f41e493087fb95f96fdb3523bb25dcf6a3f0b07c588ad3cdbe1d0aa
Status: Downloaded newer image for redis:latest
1:C 26 Apr 2023 22:56:24.435 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 26 Apr 2023 22:56:24.435 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 26 Apr 2023 22:56:24.435 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 26 Apr 2023 22:56:24.435 * monotonic clock: POSIX clock_gettime
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 7.0.11 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 1
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | https://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
1:M 26 Apr 2023 22:56:24.436 # Server initialized
1:M 26 Apr 2023 22:56:24.436 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 26 Apr 2023 22:56:24.436 * Ready to accept connections
^C1:signal-handler (1682549859) Received SIGINT scheduling shutdown...
1:M 26 Apr 2023 22:57:39.067 # User requested shutdown...
1:M 26 Apr 2023 22:57:39.067 * Saving the final RDB snapshot before exiting.
1:M 26 Apr 2023 22:57:39.074 * DB saved on disk
1:M 26 Apr 2023 22:57:39.074 # Redis is now ready to exit, bye bye...
$ ls -lan redis/
total 12
drwxr-xr-x 2 1000 1000 4096 Apr 26 15:57 .
drwxr-xr-x 6 1000 1000 4096 Apr 26 15:55 ..
-rw------- 1 1000 1000 89 Apr 26 15:57 dump.rdb
If you change the user that the container runs as, then you also have to provide a directory that the chosen user can write to (since we aren't running as root, we can't chown
anything). A few scenarios of how docker works with a bind mount local directory (and a name volume). All these tests are on Docker Desktop using WSL2 but have the same results on a regular Linux distribution.
Running as-is, no user specified. This is where the entrypoint chown
comes in.
$ ls -l
total 0
$ docker run -it --rm -v "$PWD/myredis:/data" redis
...
^C1:signal-handler (1682548431) Received SIGINT scheduling shutdown...
1:M 26 Apr 2023 22:33:51.366 # User requested shutdown...
1:M 26 Apr 2023 22:33:51.366 * Saving the final RDB snapshot before exiting.
1:M 26 Apr 2023 22:33:51.371 * DB saved on disk
1:M 26 Apr 2023 22:33:51.371 # Redis is now ready to exit, bye bye...
$ ls -ln
total 4
drwxr-xr-x 2 999 0 4096 Apr 26 15:33 myredis
Running as my user, without creating a directory first. The failure happens because dockerd
will create the source directory if it doesn't exist and it will be root
owned.
$ ls -l
total 0
$ docker run -it --rm -u "$(id -u):$(id -g)" -v "$PWD/myredis:/data" redis
...
^C1:signal-handler (1682548603) Received SIGINT scheduling shutdown...
1:M 26 Apr 2023 22:36:43.336 # User requested shutdown...
1:M 26 Apr 2023 22:36:43.336 * Saving the final RDB snapshot before exiting.
1:M 26 Apr 2023 22:36:43.336 # Failed opening the temp RDB file temp-1.rdb (in server root dir /data) for saving: Permission denied
1:M 26 Apr 2023 22:36:43.336 # Error trying to save the DB, can't exit.
1:M 26 Apr 2023 22:36:43.336 # Errors trying to shut down the server. Check the logs for more information.
$ ls -l
total 4
drwxr-xr-x 2 root root 4096 Apr 26 15:36 myredis
$ ls -ln
total 4
drwxr-xr-x 2 0 0 4096 Apr 26 15:36 myredis
Running as my user, but create the directory first.
$ ls -n
total 0
$ mkdir myredis
$ ls -ln
total 4
drwxr-xr-x 2 1000 1000 4096 Apr 26 15:48 myredis
$ docker run -it --rm -u "$(id -u):$(id -g)" -v "$PWD/myredis:/data" redis
...
^C1:signal-handler (1682549348) Received SIGINT scheduling shutdown...
1:M 26 Apr 2023 22:49:08.349 # User requested shutdown...
1:M 26 Apr 2023 22:49:08.349 * Saving the final RDB snapshot before exiting.
1:M 26 Apr 2023 22:49:08.357 * DB saved on disk
1:M 26 Apr 2023 22:49:08.357 # Redis is now ready to exit, bye bye...
$ ls -ln
total 4
drwxr-xr-x 2 1000 1000 4096 Apr 26 15:49 myredis
Running with a new named volume. This doesn't work as a different user, since the permissions of a new named volume get inherited from the image (this is where the Dockerfile chown comes into play).
$ docker volume create myredis-vol
myredis-vol
$ docker run -it --rm -u "$(id -u):$(id -g)" -v "myredis-vol:/data" redis
...
^C1:signal-handler (1682549865) Received SIGINT scheduling shutdown...
1:M 26 Apr 2023 22:57:45.440 # User requested shutdown...
1:M 26 Apr 2023 22:57:45.440 * Saving the final RDB snapshot before exiting.
1:M 26 Apr 2023 22:57:45.440 # Failed opening the temp RDB file temp-1.rdb (in server root dir /data) for saving: Permission denied
1:M 26 Apr 2023 22:57:45.440 # Error trying to save the DB, can't exit.
1:M 26 Apr 2023 22:57:45.440 # Errors trying to shut down the server. Check the logs for more information.
$ docker run -it --rm -u "$(id -u):$(id -g)" -v "myredis-vol:/data" redis bash
I have no name!@43913f565087:/data$ ls -lna
total 8
drwxr-xr-x 2 999 999 4096 Apr 17 22:51 .
drwxr-xr-x 1 0 0 4096 Apr 26 22:58 ..
Then what is the purpose of chown
in RUN mkdir /data && chown redis:redis /data
?
Assuming we always mount host directory (using -v):
chown
every file in the entrypoint so /data
directory tooroot
redis:redis
but this fails as non-root user cannot save to the data
owned by redis:redis
When we run without mounting host directory but as a non-root user e.g. docker run -it --rm -u "$(id -u):$(id -g)" redis
this also fails.
So I cannot find the reason of RUN mkdir /data && chown redis:redis /data
instead of RUN mkdir /data
.
So I cannot find the reason of
RUN mkdir /data && chown redis:redis /data
instead ofRUN mkdir /data
.
The chown
is there for the named volume (with -v myredis-vol:/data
) or anonymous volume (no -v
or --mount
). It is applicable if starting as root
(and the find | chown
skips it because it is already the right user). It is also there when running as the redis user: docker run --user redis:redis redis
.
Thank you! That is really helpful! . Do you know any resources where I can read more about permissions of docker volumes and dockerd? I believe that this kind of info is missing in the docummentation of volumes
When I am trying to run redis as non-root user with
I cannot close the container. The error is as follows:
I believe that this is because
/data
directory is alwayschown
toredis:redis
no matter we are running as root or non-root. In case of running as non-root, some user (who is running docker) will try to write to the/data
where onlyredis
user can write.