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 usermssql
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 COPY
ed 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.