Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind mounts created using rootless docker have a weird uid on the host machine. How can I delete these folders?

I have the following docker-compose.yml file which creates a bind mount located in $HOME/test on the host system:

version: '3.8'

services:
  pg: 
    image: postgres:13
    volumes:
      - $HOME/test:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=pass
      - PGUSER=postgres

I bring up the container and inspect the permissions of the bind mount directory:

$ docker-compose up -d
$ ls -l ~
drwx------ 19  4688518 usertest 4096 Mar 11 17:06 test

The folder ~/test is created with a different uid in order to prevent accidental manipulation of this folder outside of the container. But what if I really do want to manipulate it? For example, if I try to delete the folder, I get a permission denied error as expected:

$ rm ~/test -rf
rm: cannot remove '/home/usertest/test': Permission denied

I suspect that I need to change uids using the newuidmap command somehow, but I'm not sure how to go about that.

like image 868
Mike Izbicki Avatar asked Mar 12 '21 01:03

Mike Izbicki


People also ask

How does Docker bind mount work?

Bind mounts will mount a file or directory on to your container from your host machine, which you can then reference via its absolute path. To use bind mounts, the file or directory does not need to exist on your Docker host already. If it doesn't exist, it will be created on demand.

What is rootless mode in Docker?

Rootless mode allows running the Docker daemon and containers as a non-root user to mitigate potential vulnerabilities in the daemon and the container runtime. Rootless mode does not require root privileges even during the installation of the Docker daemon, as long as the prerequisites are met.

What is Docker volume bind mount?

Bind mounts have been around since the early days of Docker. Bind mounts have limited functionality compared to volumes. When you use a bind mount, a file or directory on the host machine is mounted into a container. The file or directory is referenced by its absolute path on the host machine.


2 Answers

How can I delete these folders?

But what if I really do want to manipulate it?

Using Docker, you can:

  1. Run a command in the container as a specific user using the same UID (such as rm or sh), for example:

    # Run shell session using your user with docker-compose
    # You can then easily manipulate data
    docker-compose exec -u 4688518 pg sh 
    
    # Run command directly with docker
    # Docker container name may vary depending on your situation
    # Use docker ps to see real container name 
    docker exec -it -u 4688518 stack_pg_1 rm -rf /var/lib/postgresql/data 
    
  2. Similar to previous one, you can run a new container with:

    # Will run sh by default
    docker run -it -u 4688518 -v $HOME/test:/tmp/test busybox
    
    # You can directly delete data with 
    docker run -it -u 4688518 -v $HOME/test:/tmp/test busybox rm -rf /tmp/test/*
    

    This may be suitable if your pg container is stopped or deleted. Docker image itself does not need to be the same as the one run by Docker Compose, you only need to specify proper user UID.

    Note: you may not be able to delete folder using rm -rf /tmp/test as user 4688518 may not have writing permission on /tmp folder to do so, hence the use of /tmp/test/*

  3. Use any of the above, but using root user such as -u 0 or -u root

Without using Docker, you can effectively run sudo command as suggested by other answer, or even temporarily change permission of said folder then change it back. However, from experience, when manipulating Docker-related data it's easier and less error-prone to user Docker itself.

like image 162
Pierre B. Avatar answered Oct 02 '22 01:10

Pierre B.


Dealing with user ids in docker is tricky business because docker containers share the same kernel with the host operating system (at least on linux). Consequently, any files that the container creates in the bind mount with a given uid will have the same uid on the host system.

Whenever the uid used by the container (let's say it's 2222) is different from your own uid (or you don't have write access to files owned by 2222), you won't be able to delete the folder. The easy workaround is to run sudo rm -rf ~/test.

Edit: If the user does not have admin rights, you can still give them rights to modify the generated files like so.

# Create a directory that the users can write in.
mkdir workspace
# Change the owner to the group of users that should have access (3333).
sudo chown -R 2222:3333 workspace
# Give group write access.
sudo chmod -R g+w workspace
# Make sure that all users that should have write access are in group 3333.

Then you can run the container using

docker run --rm -u `id -u`:3333 -v `pwd`/workspace:/workspace \
    -w /workspace alpine:latest touch myfile

which creates myfile in the workspace folder with the right permissions so your users can delete the file again.

like image 26
Till Hoffmann Avatar answered Oct 02 '22 01:10

Till Hoffmann