Home > Mobile >  Dockerfile mkdir permission denied
Dockerfile mkdir permission denied

Time:11-07

I am trying to build the image with:

docker build -t db-demo .

But i get

RUN mkdir -p /usr/src/app: #5 0.512 mkdir: cannot create directory '/usr/src/app': Permission denied

The Dockerfile

FROM mcr.microsoft.com/mssql/server
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . /usr/src/app
RUN chmod  x /usr/src/app/run-initialization.sh
ENV SA_PASSWORD bpassword
ENV ACCEPT_EULA Y
ENV MSSQL_PID Express
EXPOSE 1433

CMD /bin/bash ./entrypoint.sh

The OS is Windows.How to fix this?

CodePudding user response:

If we start the mssql container with an interactive shell:

docker run -it --rm mcr.microsoft.com/mssql/server /bin/bash

and then look at the active user within the container:

mssql@ed73727870bb:/$ whoami
mssql

we see that the active user is mssql. Furthermore, if we look at the permissions for /usr/src inside the container:

mssql@ed73727870bb:/$ ls -lisa /usr | grep -i src
163853 4 drwxr-xr-x 2 root root 4096 Apr 15  2020 src

we see that only root has write-access to directory /usr/src.

Thus, if we want to create a directory /usr/src/app, so that user mssql can write to it, we will have to

  • create it as root and
  • grant the appropriate permissions to mssql.

This leads to the following Dockerfile:

FROM mcr.microsoft.com/mssql/server

# change active user to root
USER root 

# create the app directory
RUN mkdir -p /usr/src/app

# set mssql as owner of the app directory
RUN chown mssql /usr/src/app

# change back to user mssql
USER mssql

WORKDIR /usr/src/app

# sanity check: try to write a file
RUN echo "Hello from user mssql" > hello.txt

if we build and run this Dockerfile:

docker build -t turing85/my-mssql -f Dockerfile .
docker run -it --rm turing85/my-mssql /bin/bash

We can now see that:

  • the active user is still mssql:

    mssql@85e401ccc3f9:/usr/src/app$ whoami
    mssql
    
  • a file /usr/src/app/hello.txt has been created, and user mssql has read-access:

    mssql@85e401ccc3f9:/usr/src/app$ cat hello.txt
    Hello from user mssql
    
  • user mssql has write-access to /usr/src/app:

    mssql@85e401ccc3f9:/usr/src/app$ touch test.txt && ls -lisa
    total 16
    171538 4 drwxr-xr-x 1 mssql root 4096 Nov  6 20:13 .
    171537 8 drwxr-xr-x 1 root  root 4096 Nov  6 20:02 ..
    171539 4 -rw-r--r-- 1 mssql root   17 Nov  6 20:02 hello.txt
    171604 0 -rw-r--r-- 1 mssql root    0 Nov  6 20:13 test.txt
    
  • user mssql has no write-access to /usr/src:

    mssql@85e401ccc3f9:/usr/src/app$ touch ../test2.txt
    touch: cannot touch '../test2.txt': Permission denied
    

A comment on the Dockerfile in the post:

It seems that we try to copy an application into the mssql container. I assume this is done to start said application within the mssql container. While this is possible (with some configuration), I strongly advice against this approach. We could instead define two containers (one for the database, one for the application), e.g. through a docker-compose file.

CodePudding user response:

WORKDIR creates the named directory if it doesn't exist. If your only permission problem is while trying to create the directory, you can remove the RUN mkdir line and let Docker create the directory for you.

FROM any-base-image
# Docker creates the directory if it does not exist
# You do not need to explicitly RUN mkdir
WORKDIR /usr/src/app
...

Looking further at this example, the RUN chmod ... line might also fail if the base image has a non-root user that can't access a root-owned directory. COPY will also copy the permissions from the host, so if the file is executable in the host environment you would not need to explicitly chmod x it after it is COPYed in. That would let you delete all of the RUN lines; you'd be left with COPY and ENV instructions and runtime metadata, none of which should encounter permission problems.

  • Related