Ícaro Lorran
Ícaro Lorran

Reputation: 96

Permission denied when writing file in volume mounted in Docker

I want to a accomplish a relatively simple task, which is to be able to read and write from a samba share that is attached to docker. I have several services sharing the same volume, they are mostly spark workers and a master. I also have an almond jupyter server that can access this volume. Everything is deployed as a docker compose file:

services:
  spark:
    image: docker.io/bitnami/spark:3.5.2
    user: root
    environment:
      - SPARK_MODE=master
      - SPARK_RPC_AUTHENTICATION_ENABLED=no
      - SPARK_RPC_ENCRYPTION_ENABLED=no
      - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no
      - SPARK_SSL_ENABLED=no
      - SPARK_USER=spark
    ports:
      - '8080:8080'
      - '7077:7077'
    volumes:
      - .:/main/workspace
      - cifs-volume:/main/data
    security_opt:
      - label:disable
      - seccomp:unconfined
      - apparmor:unconfined
    cap_add:
      - ALL
    privileged: true
  spark-worker:
    image: docker.io/bitnami/spark:3.5.2
    user: root
    deploy:
      replicas: ${N_REPLICAS}
    environment:
      - SPARK_MODE=worker
      - SPARK_MASTER_URL=$SPARK_MASTER_URL
      - SPARK_RPC_AUTHENTICATION_ENABLED=no
      - SPARK_RPC_ENCRYPTION_ENABLED=no
      - SPARK_WORKER_MEMORY=$MEMORY
      - SPARK_EXECUTOR_MEMORY=$MEMORY
      - SPARK_WORKER_CORES=$N_CORES
      - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no
      - SPARK_SSL_ENABLED=no
      - SPARK_USER=spark
    volumes:
      - .:/main/workspace
      - cifs-volume:/main/data
    security_opt:
      - label:disable
      - seccomp:unconfined
      - apparmor:unconfined
    cap_add:
      - ALL
    privileged: true
  almond:
    image: almondsh/almond:latest
    user: root    
    ports:
      - 8002:8888
    environment:
      - JUPYTER_TOKEN=almond
    volumes:
      - .:/main/workspace
      - cifs-volume:/main/data
    security_opt:
      - label:disable
      - seccomp:unconfined
      - apparmor:unconfined
    cap_add:
      - ALL
    privileged: true
volumes: 
  cifs-volume:
    driver_opts:
      type: cifs 
      o: username=${SMB_USER},password=${SMB_PASSWORD},uid=1000,gid-1000,vers=3.0,rw
      device: ${SMB_URL}

As you can see, I have tried several ways to elevate privileges or completely negate security features, which is fine for these containers as I am dealing with public data.

If I try to write into the volume from the almond notebook, I get an error:

import scala.io.Source

val fileContent = "Hello, World!"
val filePath = "/main/data/file.txt"
val file = new java.io.File(filePath)
file.createNewFile()
java.io.IOException: Permission denied
  java.io.UnixFileSystem.createFileExclusively(Native Method)
  java.io.File.createNewFile(File.java:1023)
  ammonite.$sess.cmd2$Helper.<init>(cmd2.sc:8)
  ammonite.$sess.cmd2$.<init>(cmd2.sc:7)
  ammonite.$sess.cmd2$.<clinit>(cmd2.sc:-1)

If I do ls -l on /main, I can see that the files within are still restricted:

total 4
drwxr-xr-x 2 1021 users    0 Dec 13 12:17 data
drwxrwxr-x 4 1002  1002 4096 Dec 14 11:20 workspace

Upvotes: 1

Views: 71

Answers (1)

Andreas Lundgren
Andreas Lundgren

Reputation: 12545

First of all, the following line in your docker file has a dash between gid and 1000, it should be an =. o: username=${SMB_USER},password=${SMB_PASSWORD},uid=1000,gid-1000,vers=3.0,rw But maybe this was just an error when puting the code here at SO.

Anyways, I think that this line may be the key to a possible solution. When you mount the volume, you should provide the User ID and Group ID of the User that will use the mount later on. Default is often the root user, or whatever user that user has privileges to do the mount itself.

In your case, only the owner (drwxr-xr-x) has write access to the folder, and the owner is 1021. So I think you should try to mount using o: username=${SMB_USER},password=${SMB_PASSWORD},uid=1021,gid=1000,vers=3.0,rw.

If this don't work, run the command id before trying to write to the folder and double check what user is acting during your file.createNewFile() command.

Upvotes: 0

Related Questions