Thursday, 1 October 2020

"Permission denied" - Docker and permissions and PostgreSQL

Long story very short, I've been wrangling with a knotty "Permission denied" issue with a PostgreSQL container, with regard to some SQL and Bash scripts that the Dockerfile copies into the /docker-entrypoint-initdb.d directory at build time.

After some tinkering and thought, I realised what was going on ....

In short, the COPY command within the Dockerfile will, of course, inherit the permissions of the source files and, unless you choose to override with a chmod command, that's all she wrote ....

I proved this via a very simple test case: -

I started with this: -

ls -al

total 16

drwxr-x---  2 root root 4096 Oct  1 12:52 .

drwx------ 15 root root 4096 Oct  1 12:52 ..

-rw-r-----  1 root root   94 Oct  1 12:32 Dockerfile

-rw-------  1 root root   13 Oct  1 12:28 greeting.txt

Note the permissions of the greeting.txt file are set to chmod 640rw-r----- ). That means owner ( root ) has read, group ( root ). has read and everybody/public has NOTHING.

And here's the Dockerfile: -

FROM alpine

RUN mkdir /msg
COPY greeting.txt /msg
RUN ls -al /msg
RUN cat /msg/greeting.txt

When I built the image: -

docker build --no-cache -t dave:latest -f Dockerfile .

notice that the permission of that file are retained: -

Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM alpine
 ---> 0d9ffb5b0ee7
Step 2/5 : RUN mkdir /msg
 ---> Running in 9b3a38e9a0df
Removing intermediate container 9b3a38e9a0df
 ---> 23b61ff3ebc9
Step 3/5 : COPY greeting.txt /msg
 ---> d0d76efa3d8a
Step 4/5 : RUN ls -al /msg
 ---> Running in 96b2db84132a
total 12
drwxr-xr-x    1 root     root          4096 Oct  1 13:03 .
drwxr-xr-x    1 root     root          4096 Oct  1 13:03 ..
-rw-------    1 root     root            13 Oct  1 12:28 greeting.txt
Removing intermediate container 96b2db84132a
 ---> 000ca956de06
Step 5/5 : RUN cat /msg/greeting.txt
 ---> Running in f5b63433f174
Hello World!
Removing intermediate container f5b63433f174
 ---> 8ccdc3916112
Successfully built 8ccdc3916112
Successfully tagged dave:latest

In other words, if the permissions start at 640 they stay at 640.

If I change the permissions on my build machine: -

chmod 644 greeting.txt

ls -al

total 16
drwxr-x---  2 root root 4096 Oct  1 12:52 .
drwx------ 15 root root 4096 Oct  1 12:52 ..
-rw-r-----  1 root root   94 Oct  1 12:32 Dockerfile
-rw-r--r--  1 root root   13 Oct  1 12:28 greeting.txt

Note the permissions of the greeting.txt file are set to chmod 644 ( rw-r--r-- ).

That means owner ( root ) has readgroup ( root ). has read and everybody/public has read.

When I re-run the build: -

docker build --no-cache -t dave:latest -f Dockerfile .

Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM alpine
 ---> 0d9ffb5b0ee7
Step 2/5 : RUN mkdir /msg
 ---> Running in 0bd5097bde82
Removing intermediate container 0bd5097bde82
 ---> e05cbcd1c9a4
Step 3/5 : COPY greeting.txt /msg
 ---> 4281fac6e501
Step 4/5 : RUN ls -al /msg
 ---> Running in a0da87ffd1b4
total 12
drwxr-xr-x    1 root     root          4096 Oct  1 13:11 .
drwxr-xr-x    1 root     root          4096 Oct  1 13:11 ..
-rw-r--r--    1 root     root            13 Oct  1 12:28 greeting.txt
Removing intermediate container a0da87ffd1b4
 ---> 33973f2c3e98
Step 5/5 : RUN cat /msg/greeting.txt
 ---> Running in 8e9d1c3cf3e6
Hello World!
Removing intermediate container 8e9d1c3cf3e6
 ---> 27b1dd46c329
Successfully built 27b1dd46c329
Successfully tagged dave:latest

So, again, the permissions of the file on the host build machine are inherited/preserved inside the built image.

So, for me, the fix is to either: -

(a) change the permissions in the GitHub repo from which I'm building the image
(b) add a sneaky chmod into my Dockerfile.

For PostgreSQL, this was breaking things as the files were owned by the root user, so the postgres user didn't ever have access.


No comments:

Note to self - use kubectl to query images in a pod or deployment

In both cases, we use JSON ... For a deployment, we can do this: - kubectl get deployment foobar --namespace snafu --output jsonpath="{...