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

Viewed 1195

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.

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.

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.

Related