MariaDB / mariadb-docker

Docker Official Image packaging for MariaDB
https://mariadb.org
GNU General Public License v2.0
770 stars 438 forks source link

Image prefers UID:GID 999:999 #287

Closed hathalud closed 4 years ago

hathalud commented 4 years ago

MariaDB Docker image for 1:10.4.12 has an /etc/passwd that specifies a UID:GID setting 999:999, which is not the UID and GID that are passed to the image. I usually use a single user and group for most of my Docker containers since most all work with each other. While I don't mind having an oddball, it would have been nice if the documentation was more clear about what steps were needed to use a custom UID and GID. Or if this was a mistake, it needs to be fixed in the next version. As it was, it took me a little while to realize that my UID:GID Docker Variables were not being used correctly and that was why MariaDB was throwing permission errors at me. Thank you for all the great work on MariaDB though!

wglambert commented 4 years ago

999:999, which is not the UID and GID that are passed to the image.

The Dockerfile creates the user/group mysql https://github.com/docker-library/mariadb/blob/4c69dec03b0b771563c8474ab358b7812edbfc88/10.4/Dockerfile#L5

Which is 999:999 in the image

$ docker run -d --rm --name mariadb -e MYSQL_ROOT_PASSWORD=root mariadb:10.4.12
a40728c1f117b5096f8554da8bd202ef895a8aed9fe7846551dc3cf269567534

$ docker exec -it mariadb bash

root@a40728c1f117:/# cat /etc/passwd | grep mysql
mysql:x:999:999::/home/mysql:/bin/sh

For running MariaDB as an arbitrary user see https://github.com/docker-library/docs/tree/master/mysql#running-as-an-arbitrary-user Which will make the processes in the container run as that user and all database files initialized will be owned by that user

This is on https://labs.play-with-docker.com/ (Alpine) to workaround https://github.com/docker-library/mariadb/issues/262

$ addgroup -g 1337 test
$ adduser -u 1337 -G test test
$ cat /etc/passwd | grep test
test:x:1337:1337:Linux User,,,:/home/test:/bin/bash

$ mkdir testdir && chown test:test testdir

$ docker run -d --user 1337:1337 --name mariadb -v /etc/passwd:/etc/passwd:ro -v "$PWD"/testdir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mariadb:10.4.12
9190db34a9df6ff85c52286e222c87c1d459fad2753c1cc50f97f8076e4e0edf

$ docker exec -it --user 1337:1337 mariadb bash
groups: cannot find name for group ID 1337

test@9190db34a9df:/$ echo $UID; groups
1337
groups: cannot find name for group ID 1337
1337

test@9190db34a9df:/$ ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
test          1  0.2  0.2 1987256 87484 ?       Ssl  18:49   0:00 mysqld
test        178  0.0  0.0  18504  3356 pts/0    Ss   18:50   0:00 bash
test        194  0.0  0.0  34396  2820 pts/0    R+   18:51   0:00 ps aux

test@9190db34a9df:/$ exit
exit

$ ls -al testdir
total 141076
drwxr-xr-x    4 test     test           208 Feb  4 18:49 .
drwx------    1 root     root            21 Feb  4 18:49 ..
-rw-rw----    1 test     test      18620416 Feb  4 18:49 aria_log.00000001
-rw-rw----    1 test     test            52 Feb  4 18:49 aria_log_control
-rw-rw----    1 test     test           976 Feb  4 18:49 ib_buffer_pool
-rw-rw----    1 test     test      50331648 Feb  4 18:49 ib_logfile0
-rw-rw----    1 test     test      50331648 Feb  4 18:49 ib_logfile1
-rw-rw----    1 test     test      12582912 Feb  4 18:49 ibdata1
-rw-rw----    1 test     test      12582912 Feb  4 18:49 ibtmp1
-rw-rw----    1 test     test             0 Feb  4 18:49 multi-master.info
drwx------    2 test     test          4096 Feb  4 18:49 mysql
drwx------    2 test     test            20 Feb  4 18:49 performance_schema
hansaplasst commented 2 years ago

This issue still isn't resolved for Linux (Ubuntu 20.04)...

I finally got it working using the above solution. However, what's missing in @wglambert's response is that /etc/group:/etc/group:ro should be in there as well. Else you get group errors.

docker run -d --user 1337:1337 --name mariadb -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v "$PWD"/testdir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mariadb:latest`

Since a lot of us are using docker-compose, I've also included a solution based on dc below for completeness.

  mariadb:
    image: mariadb:latest
    container_name: mariadb
    restart: always
    user: "1337:1337"
    environment:
      MARIADB_ROOT_PASSWORD: "secret"
    ports:
      - 3306:3306
    volumes:
      - ./testdir:/var/lib/mysql
      - /etc/passwd:/etc/passwd:ro
      - /etc/group:/etc/group:ro

Cheers

grooverdan commented 2 years ago

Hi, to help me understand the issue more, why is a user/group resolution of 1337:1337 to test (or actual user/group) needed inside the container?

hansaplasst commented 2 years ago

Let me start by saying that I started working with Docker just a few days... So what I'm about to tell you could be totally wrong ;-)

However, I do have a reasonable understanding of Linux, and from what I've inferred so far, is that files in the Docker environment have the same user-id in the host system. This also counts for group-id's of course.

So when passing a volume to a Docker container -v /volume/path, it is my opinion that the volume should have a sane equivalent user ID in the host environment. Not to mention that "insane" users could make the OS behave unexpectedly ;-)

AFAIK Docker image developers can use the environment param -e or the user param --user to match a host user-id (and group-id) to a Docker user-id (and group-id). I suspect this is not handled properly by the mariadb Docker image. Therefore it wasn't working on my system. By passing /etc/passwd and /etc/group read only to the image, I presumably forced the image to properly use the correct ID's for it's equivalent user in the host.

I hope my explanation and understanding of all this is correct... It would be nice if someone with more understanding of Docker could confirm this! Cheers!

yosifkit commented 2 years ago

I've rarely seen an application that doesn't work if the user or group id doesn't exist in the container's filesystem and I've never seen an issue from the host on non-existent ids.

Like many images within the official images, the mariadb image will work whether using its default user (mysql/999 in the image) or using any user id passed via --user; the only caveat being that any folder used for storage (like /var/lib/mysql) needs to have appropriate permissions for the provided user/group. To help accommodate this, the image has a few directories like /run/mysql for mysqld.sock that have wider permissions so that any user can create/modify the file.

$ ls -ln
total 8
drwxrwsr-x 2 1000 1000 4096 Jul 12 14:48 data
...
$ # could choose any user id as long as they had enough permissions for the provided folder
$ docker run -it --rm --name sqly --user "$(id -u)":"$(id -g)" -e MYSQL_ROOT_PASSWORD=12345 -v "$PWD/data/":/var/lib/mysql mariadb
2022-07-13 17:36:03+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.8.3+maria~jammy started.
...
2022-07-13 17:36:09 0 [Note] Server socket created on IP: '0.0.0.0'.
2022-07-13 17:36:09 0 [Note] Server socket created on IP: '::'.
2022-07-13 17:36:09 0 [Note] mariadbd: ready for connections.
Version: '10.8.3-MariaDB-1:10.8.3+maria~jammy'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
$ # stopped in another terminal
$ ls -ln data/
total 139252
-rw-rw---- 1 1000 1000  16719872 Jul 13 10:36 aria_log.00000001
-rw-rw---- 1 1000 1000        52 Jul 13 10:36 aria_log_control
-rw-rw---- 1 1000 1000         9 Jul 13 10:36 ddl_recovery.log
-rw-rw---- 1 1000 1000       868 Jul 13 10:36 ib_buffer_pool
-rw-rw---- 1 1000 1000  12582912 Jul 13 10:36 ibdata1
-rw-rw---- 1 1000 1000 100663296 Jul 13 10:36 ib_logfile0
-rw-rw---- 1 1000 1000  12582912 Jul 13 10:36 ibtmp1
-rw-rw---- 1 1000 1000         0 Jul 13 10:36 multi-master.info
drwx--S--- 2 1000 1000      4096 Jul 13 10:36 mysql
-rw-r--r-- 1 1000 1000        14 Jul 13 10:36 mysql_upgrade_info
drwx--S--- 2 1000 1000      4096 Jul 13 10:36 performance_schema
drwx--S--- 2 1000 1000     12288 Jul 13 10:36 sys

(note that it is not possible to use root or user id 0 to run mysqld via the entrypoint, since the entrypoint script will do some initial chown/chmod setup and then step down to mysql before eventually starting mysqld)

hansaplasst commented 2 years ago

First of all. Thanks for the awesome work you've done!

In reply to your comment. Maybe I was a bit too conservative as to state that the D-user must have an equivalent user in the host. Let's trust that Linus has fixed all the bugs and that "insane" users are handled appropriately ;-) I've updated my answer from "must" to "my opinion" and "should"...

Nevertheless, I don't like seeing "systemd-coredump:systemd-coredump" on my docker paths... It looks wrong. Just like 999:999 looks wrong. IMHO. Docker or (until there a cure) sysadmins and image builders should handle the "insane" users and not Linus. But that's just my opinion ;-)

The issue remains that in the mariadb image UID:GID can't be changed as I would have expected by just passing the arguments for UID and GID via -e or --user. I will include the error tomorrow since I'm desperately need some sleep now...

-H

grooverdan commented 2 years ago

As you can see from other container runtimes, running rootless/unprivileged containers, there's uid/gid maps (but not user/group maps) between host and container so they aren't necessary the same (ref: blog, Red Hat blogs/docs). Even docker has rootless mode.

I'm looking to add a test to the test suite. Just trying to write it to account for rootful/rootless modes concurrently.

See also #256.