Reputation: 344
I am trying to recursively copy some files and directories into a Docker image. The source directory contains files and a sub-directory with some files in it.
src/
├─ subdir/
│ ├─ sub_file_1
│ ├─ sub_file_2
├─ file_1
├─ file_2
...
├─ file_n
I am running the following command in Dockerfile:
COPY --chown=user:user --chmod=600 src/ /dst/
The permissions are correctly applied for all top level files (file_1
to file_n
) and the sub directory itself, but not for the files in subdir
(e.g. sub_file_1).
Entering the container and running ls, the output is:
user@container:/$ ls -la /dst/subdir
ls: cannot access '/dst/subdir/sub_file_1': Permission denied
ls: cannot access '/dst/subdir/sub_file_2': Permission denied
total 0
d????????? ? ? ? ? ? .
d????????? ? ? ? ? ? ..
-????????? ? ? ? ? ? sub_file_1
-????????? ? ? ? ? ? sub_file_2
Is there a way to recursively apply --chmod
and --chown
options of the COPY
command?
Upvotes: 4
Views: 16609
Reputation: 106
Short answer:
You have to actually give exec permissions to your folder and files by replacing your chmod
with --chmod=700
. And you can look up more details below or just google `Linux file permissions.
Long answer: So i recreated your example and as you can see bellow i have some scripts that i'm running in various stages before my server actually starts. I'm following good production docker practices as you do i can see and i also use your method to change permissions on the scripts file.
# App files
COPY --chown=node:node --from=builder /usr/src/app/build ./build
# Migration files
COPY --chown=node:node ./migrations ./migrations
# Scripts
COPY --chown=node:node --chmod=600 ./scripts ./scripts
# Client
COPY --chown=node:node ./client ./build/client
EXPOSE 80
And no surprise, i get a similar error.
sh: ./scripts/wait-for.sh: Permission denied
npm ERR! code ELIFECYCLE
npm ERR! errno 126
npm ERR! [email protected] preprod: `./scripts/wait-for.sh page-db:5432 -- npm run migrate -- --config build/src/config/database.json -e production `
npm ERR! Exit status 126
The problem here is the code you are giving to your chmod. Your goal is to make them executable and for security reasons make them executable for only the node(default) docker user. Now these decimal numbers we give to our chmod
are just sugar to our eyes, in reality, these will be converted to binary and assigned to every one of the permission variables for the directory and its child files/folders(in this case). You have 4 values in the Linux file system permissions, one bit to indicate file or directory, 3 bit to define user access to file/dir, another 3 for the group of users and 3 more for everyone else, you want to give execute permissions to the current user so you will need 111=7
so the final chmod
will look more like this:
# App files
COPY --chown=node:node --from=builder /usr/src/app/build ./build
# Migration files
COPY --chown=node:node ./migrations ./migrations
# Scripts
COPY --chown=node:node --chmod=700 ./scripts ./scripts
# Client
COPY --chown=node:node ./client ./build/client
EXPOSE 80
And as you can see the problem no longer persists
> [email protected] preprod /usr/src/app
> ./scripts/wait-for.sh page-db:5432 -- npm run migrate -- --config build/src/config/database.json -e production
> [email protected] migrate /usr/src/app
> db-migrate up "--config" "build/src/config/database.json" "-e" "production"
[INFO] No migrations to run
[INFO] Done
> [email protected] prod /usr/src/app
> npm run start
> [email protected] start /usr/src/app
> node build/src/server.js
18:28:17 info: Initializing thanos webpage Server version: 0.0.1. Environment: development
18:28:17 info: /usr/src/app/build/src
18:28:17 info: Thanos web page server is listening on port -> 80
Upvotes: 9