Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why docker-compose creates directories/files with user:group 999:999?

I used docker-compose up with the following docker-compose.yml

version: '3.5'
services:
 mysql-server:
  image: mysql:5.7
  environment:
    - MYSQL_ROOT_PASSWORD=root_pwd
  volumes:
   - ./var/lib/mysql:/var/lib/mysql:rw

The directory ./var/lib/mysql does not exist initially.

After running docker-compose up ..

ls -al ./var/lib/mysql command shows all the files with user:group 999:999.

I cannot find user or group called 999 in my system.

Why docker-compose chooses to create files with a non-existing uid:gid ?

In my case, I cannot commit the specific directory unless I change ownership. But even when I do, on a next run, docker-compose up updates the ownership again to 999:999.

What is the solution to the above problem? e.g. Is there a way to instruct docker-compose to map files in host machine with a specific uid:gid pair?

Host: ubuntu-18.04
docker-compose: 1.22.0

like image 765
Marinos An Avatar asked Mar 19 '19 12:03

Marinos An


People also ask

What is the purpose of Docker compose file?

Docker Compose is a tool that was developed to help define and share multi-container applications. With Compose, we can create a YAML file to define the services and with a single command, can spin everything up or tear it all down.

Where should Docker compose files be stored?

The Compose file is a YAML file defining services, networks and volumes. The default path for a Compose file is ./docker-compose.yml .

Why do we need volumes in Docker compose?

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure and OS of the host machine, volumes are completely managed by Docker.

Does Docker compose run multiple containers?

With Docker compose, you can configure and start multiple containers with a single yaml file.


3 Answers

Docker creates and populates the directory with the user that mysql image uses. That user, of course, has an uid within the container. That uid happens to be 999.

The user with that uid exists in the container but does not exist in your host.

On the container the folder looks like this:

root@f86ffddac96c:/var/lib# ls -l
total 32
...
drwxr-xr-x 5 mysql mysql 4096 Mar 19 13:06 mysql
...

and on the host it ends up looking like this.

root@machine:/home/username/mysql/var/lib# ls -l
total 4
drwxr-xr-x 5 999 docker 4096 Mar 19 15:06 mysql

This just simply means that the user mysql has uid of 999. And as you are creating a bind volume from container to host, all files within that volume must have same permissions for same uids. On my test machine docker has guid of 999, which is why it is displayed as such on the host side.

As for "fixing" this you can either use a (host-level) known uid in the dockerfile instead of the default one, or you can just ignore it, as it is working exactly as intended, unless there's a specific reason why you want it to display a certain name for a certain uid in your host system.

like image 68
Christian W. Avatar answered Sep 22 '22 12:09

Christian W.


Our Dockerfile has lines like

ARG uid=1000
ARG gid=1000
RUN groupadd -g $gid myuser && useradd -lm -u $uid -g $gid myuser
USER myuser

Then we build with

docker-compose build --build-arg uid=`id -u` --build-arg gid=`id -g` mydocker

So that the uid and gid of the user created inside the Docker is the same as the uid and gid of the user running docker-compose outside the Docker.

like image 26
RemcoGerlich Avatar answered Sep 23 '22 12:09

RemcoGerlich


Here are the files your docker image is built on : https://github.com/docker-library/mysql/tree/bb7ea52db4e12d3fb526450d22382d5cd8cd41ca/5.7

In the Dockerfile you can read:

RUN groupadd -r mysql && useradd -r -g mysql mysql

which creates a user that might have the UID/GID couple your are seeing.

And in the entrypoint.sh file, there is:

chown -R mysql:mysql "$DATADIR"

which is executed every time you run the container.

To be sure, try:

docker run exec -ti <nameOfContainer|containerHash> bash -c "id mysql"
like image 21
Louis Delfieux Avatar answered Sep 21 '22 12:09

Louis Delfieux