New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VOLUME changes directory permissions from 700 to 755; RUN chmod doesn't fix it #6137

Closed
abevoelker opened this Issue May 31, 2014 · 16 comments

Comments

Projects
None yet
6 participants
@abevoelker

So I have a Dockerfile that looks like this, which I'm using to install Postgres:

FROM ubuntu:trusty

# Ignore APT warnings about not having a TTY
ENV DEBIAN_FRONTEND noninteractive

# Ensure UTF-8 locale
RUN echo "LANG=\"en_US.UTF-8\"" > /etc/default/locale
RUN locale-gen en_US.UTF-8
RUN dpkg-reconfigure locales

RUN apt-get update

# Install build dependencies
RUN apt-get install -y wget

# Install Postgres dependencies
RUN apt-get install -y libreadline-dev zlib1g-dev flex bison libxml2-dev libxslt1-dev libssl-dev libpq-dev

# Add PostgreSQL Global Development Group apt source
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main" > /etc/apt/sources.list.d/pgdg.list

# Add PGDG repository key
RUN wget -qO - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | apt-key add -

RUN apt-get update

# Install Postgres 9.3, PL/Python, PL/V8
RUN apt-get install -y postgresql-9.3 postgresql-contrib-9.3 postgresql-server-dev-9.3 postgresql-plpython-9.3 postgresql-9.3-plv8

RUN ls -l /var/lib/postgresql/9.3

VOLUME /var/lib/postgresql/9.3/main

RUN ls -l /var/lib/postgresql/9.3

VOLUME keeps insisting on changing the permissions of the /var/lib/postgresql/9.3/main directory to 755. Here's some output from a fresh build:

Step 12 : RUN ls -l /var/lib/postgresql/9.3
 ---> Running in 25e3730790f8
total 4
drwx------ 15 postgres postgres 4096 May 31 16:19 main
 ---> 10d263b114f5
Removing intermediate container 25e3730790f8
Step 13 : VOLUME /var/lib/postgresql/9.3/main
 ---> Running in c167e683d1bb
 ---> e3724123d0b0
Removing intermediate container c167e683d1bb
Step 14 : RUN ls -l /var/lib/postgresql/9.3
 ---> Running in 06424a95509d
total 4
drwxr-xr-x 15 postgres postgres 4096 May 31 16:19 main
 ---> d0babab6b64e

Postgres refuses to start because of this permission issue:

root@64daa14d1df2:/# /etc/init.d/postgresql start
 * Starting PostgreSQL 9.3 database server                                                                              * The PostgreSQL server failed to start. Please check the log output:
2014-05-31 16:21:26 UTC FATAL:  data directory "/var/lib/postgresql/9.3/main" has group or world access
2014-05-31 16:21:26 UTC DETAIL:  Permissions should be u=rwx (0700).

If I add this line below the VOLUME line:

RUN chmod -R 700 /var/lib/postgresql/9.3/main

It doesn't make any difference.

Is this expected behavior, or is this a bug? If it's the former, how am I supposed to work around it? I need to expose this directory as a data volume because it's where Postgres stores the actual database data, which I would like to persist beyond container lifetimes.

I'm running Ubuntu 14.04 64-bit, with the latest Docker dev build to work around a different issue (#6047):

$ docker version
Client version: 0.11.1-dev
Client API version: 1.12
Go version (client): go1.2.1
Git commit (client): 05cf349
Server version: 0.11.1-dev
Server API version: 1.12
Go version (server): go1.2.1
Git commit (server): 05cf349

$ docker info
Containers: 21
Images: 307
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 350
Execution Driver: native-0.2
Kernel Version: 3.13.0-27-generic
Username: abevoelker
Registry: [https://index.docker.io/v1/]
WARNING: No swap limit support

$ uname -a
Linux abe-PC 3.13.0-27-generic #50-Ubuntu SMP Thu May 15 18:06:16 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

I tried to reproduce this issue using a simplified Dockerfile, but it seems to work fine when I manually create the directory. Not sure what is special about the Postgres install that causes this.

@abevoelker

This comment has been minimized.

Show comment
Hide comment
@abevoelker

abevoelker May 31, 2014

This is working as expected on 0.9.1, the latest version available in the Ubuntu repos:

Step 12 : RUN ls -l /var/lib/postgresql/9.3
 ---> Running in b224c45943d0
total 4
drwx------ 15 postgres postgres 4096 May 31 16:54 main
 ---> f00d57fe4ffb
Step 13 : VOLUME /var/lib/postgresql/9.3/main
 ---> Running in 4cba43c0aa30
 ---> d1dbdb5672c5
Step 14 : RUN ls -l /var/lib/postgresql/9.3
 ---> Running in 38ec6ffe3736
total 4
drwx------ 15 postgres postgres 4096 May 31 16:54 main
 ---> 9ddf28ead3d7
$ docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1
Last stable version: 0.11.1, please update docker

I'll see if I can do a git bisect and figure out where it went wrong.

edit: According to git bisect, 84f19a0 is the commit that is causing this.

edit2: 84f19a0 is probably a red herring though because it seems to be setting the volume directory permissions to whatever that line says. If I revert that commit, it always sets the volume directory to 700. It seems like the fact that this line is setting the permissions on the volume directory in the first place is the error. But then again I don't know the code base so I will shut up now.

edit3: My docker info states that I'm using AUFS, so why is this (apparently) VFS code even running?

edit4: I've manually forced the daemon's storage driver to both AUFS and VFS with the -s flag but there was no difference.

This is working as expected on 0.9.1, the latest version available in the Ubuntu repos:

Step 12 : RUN ls -l /var/lib/postgresql/9.3
 ---> Running in b224c45943d0
total 4
drwx------ 15 postgres postgres 4096 May 31 16:54 main
 ---> f00d57fe4ffb
Step 13 : VOLUME /var/lib/postgresql/9.3/main
 ---> Running in 4cba43c0aa30
 ---> d1dbdb5672c5
Step 14 : RUN ls -l /var/lib/postgresql/9.3
 ---> Running in 38ec6ffe3736
total 4
drwx------ 15 postgres postgres 4096 May 31 16:54 main
 ---> 9ddf28ead3d7
$ docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1
Last stable version: 0.11.1, please update docker

I'll see if I can do a git bisect and figure out where it went wrong.

edit: According to git bisect, 84f19a0 is the commit that is causing this.

edit2: 84f19a0 is probably a red herring though because it seems to be setting the volume directory permissions to whatever that line says. If I revert that commit, it always sets the volume directory to 700. It seems like the fact that this line is setting the permissions on the volume directory in the first place is the error. But then again I don't know the code base so I will shut up now.

edit3: My docker info states that I'm using AUFS, so why is this (apparently) VFS code even running?

edit4: I've manually forced the daemon's storage driver to both AUFS and VFS with the -s flag but there was no difference.

@abevoelker

This comment has been minimized.

Show comment
Hide comment
@abevoelker

abevoelker May 31, 2014

Okay this is a minimal Dockerfile that reproduces my issue. Seems to be a problem with user-owned directories being exposed as volumes.

FROM ubuntu:trusty

RUN mkdir -p /tmp/foo &&\
  chown www-data:www-data /tmp/foo &&\
  chmod -R 777 /tmp/foo

RUN ls -l /tmp

VOLUME ["/tmp/foo"]

RUN ls -l /tmp
$ docker build --no-cache -t foo .
Uploading context 4.608 kB
Uploading context 
Step 0 : FROM ubuntu:trusty
 ---> 99ec81b80c55
Step 1 : RUN mkdir -p /tmp/foo &&  chown www-data:www-data /tmp/foo
 ---> Running in af45d00f9924
 ---> 9df71a2bdb67
Removing intermediate container af45d00f9924
Step 2 : RUN chmod -R 777 /tmp/foo
 ---> Running in a7a6d597c25e
 ---> d160c0cdda87
Removing intermediate container a7a6d597c25e
Step 3 : RUN ls -l /tmp
 ---> Running in cdb99fe1d8b0
total 4
drwxrwxrwx 2 www-data www-data 4096 May 31 19:48 foo
 ---> 636742db91f3
Removing intermediate container cdb99fe1d8b0
Step 4 : VOLUME ["/tmp/foo"]
 ---> Running in 90640170d845
 ---> 80e802865d63
Removing intermediate container 90640170d845
Step 5 : RUN ls -l /tmp
 ---> Running in a795c6d91b2c
total 4
drwxr-xr-x 2 www-data www-data 4096 May 31 19:48 foo
 ---> ff39b74fe292
Removing intermediate container a795c6d91b2c
Successfully built ff39b74fe292

Okay this is a minimal Dockerfile that reproduces my issue. Seems to be a problem with user-owned directories being exposed as volumes.

FROM ubuntu:trusty

RUN mkdir -p /tmp/foo &&\
  chown www-data:www-data /tmp/foo &&\
  chmod -R 777 /tmp/foo

RUN ls -l /tmp

VOLUME ["/tmp/foo"]

RUN ls -l /tmp
$ docker build --no-cache -t foo .
Uploading context 4.608 kB
Uploading context 
Step 0 : FROM ubuntu:trusty
 ---> 99ec81b80c55
Step 1 : RUN mkdir -p /tmp/foo &&  chown www-data:www-data /tmp/foo
 ---> Running in af45d00f9924
 ---> 9df71a2bdb67
Removing intermediate container af45d00f9924
Step 2 : RUN chmod -R 777 /tmp/foo
 ---> Running in a7a6d597c25e
 ---> d160c0cdda87
Removing intermediate container a7a6d597c25e
Step 3 : RUN ls -l /tmp
 ---> Running in cdb99fe1d8b0
total 4
drwxrwxrwx 2 www-data www-data 4096 May 31 19:48 foo
 ---> 636742db91f3
Removing intermediate container cdb99fe1d8b0
Step 4 : VOLUME ["/tmp/foo"]
 ---> Running in 90640170d845
 ---> 80e802865d63
Removing intermediate container 90640170d845
Step 5 : RUN ls -l /tmp
 ---> Running in a795c6d91b2c
total 4
drwxr-xr-x 2 www-data www-data 4096 May 31 19:48 foo
 ---> ff39b74fe292
Removing intermediate container a795c6d91b2c
Successfully built ff39b74fe292
@shykes

This comment has been minimized.

Show comment
Hide comment
@shykes

shykes May 31, 2014

Collaborator

ping @unclejack @vieux @crosbymichael this looks like 1.0 material

On Sat, May 31, 2014 at 12:49 PM, Abe Voelker notifications@github.com
wrote:

Okay this is a minimal Dockerfile that reproduces my issue. Seems to be a
problem with user-owned directories being exposed as volumes.

FROM ubuntu:trusty

RUN mkdir -p /tmp/foo &&
chown www-data:www-data /tmp/foo &&
chmod -R 777 /tmp/foo

RUN ls -l /tmp

VOLUME ["/tmp/foo"]

RUN ls -l /tmp

$ docker build --no-cache -t foo .
Uploading context 4.608 kB
Uploading context
Step 0 : FROM ubuntu:trusty
---> 99ec81b80c55
Step 1 : RUN mkdir -p /tmp/foo && chown www-data:www-data /tmp/foo
---> Running in af45d00f9924
---> 9df71a2bdb67
Removing intermediate container af45d00f9924
Step 2 : RUN chmod -R 777 /tmp/foo
---> Running in a7a6d597c25e
---> d160c0cdda87
Removing intermediate container a7a6d597c25e
Step 3 : RUN ls -l /tmp
---> Running in cdb99fe1d8b0
total 4
drwxrwxrwx 2 www-data www-data 4096 May 31 19:48 foo
---> 636742db91f3
Removing intermediate container cdb99fe1d8b0
Step 4 : VOLUME ["/tmp/foo"]
---> Running in 90640170d845
---> 80e802865d63
Removing intermediate container 90640170d845
Step 5 : RUN ls -l /tmp
---> Running in a795c6d91b2c
total 4
drwxr-xr-x 2 www-data www-data 4096 May 31 19:48 foo
---> ff39b74fe292
Removing intermediate container a795c6d91b2c
Successfully built ff39b74fe292


Reply to this email directly or view it on GitHub
#6137 (comment).

Collaborator

shykes commented May 31, 2014

ping @unclejack @vieux @crosbymichael this looks like 1.0 material

On Sat, May 31, 2014 at 12:49 PM, Abe Voelker notifications@github.com
wrote:

Okay this is a minimal Dockerfile that reproduces my issue. Seems to be a
problem with user-owned directories being exposed as volumes.

FROM ubuntu:trusty

RUN mkdir -p /tmp/foo &&
chown www-data:www-data /tmp/foo &&
chmod -R 777 /tmp/foo

RUN ls -l /tmp

VOLUME ["/tmp/foo"]

RUN ls -l /tmp

$ docker build --no-cache -t foo .
Uploading context 4.608 kB
Uploading context
Step 0 : FROM ubuntu:trusty
---> 99ec81b80c55
Step 1 : RUN mkdir -p /tmp/foo && chown www-data:www-data /tmp/foo
---> Running in af45d00f9924
---> 9df71a2bdb67
Removing intermediate container af45d00f9924
Step 2 : RUN chmod -R 777 /tmp/foo
---> Running in a7a6d597c25e
---> d160c0cdda87
Removing intermediate container a7a6d597c25e
Step 3 : RUN ls -l /tmp
---> Running in cdb99fe1d8b0
total 4
drwxrwxrwx 2 www-data www-data 4096 May 31 19:48 foo
---> 636742db91f3
Removing intermediate container cdb99fe1d8b0
Step 4 : VOLUME ["/tmp/foo"]
---> Running in 90640170d845
---> 80e802865d63
Removing intermediate container 90640170d845
Step 5 : RUN ls -l /tmp
---> Running in a795c6d91b2c
total 4
drwxr-xr-x 2 www-data www-data 4096 May 31 19:48 foo
---> ff39b74fe292
Removing intermediate container a795c6d91b2c
Successfully built ff39b74fe292


Reply to this email directly or view it on GitHub
#6137 (comment).

@vieux vieux added this to the 1.0 milestone May 31, 2014

@vieux

This comment has been minimized.

Show comment
Hide comment
@vieux

vieux May 31, 2014

Collaborator

@abevoelker thanks for the git bisect, added to the 1.0 milestone

Collaborator

vieux commented May 31, 2014

@abevoelker thanks for the git bisect, added to the 1.0 milestone

@abevoelker

This comment has been minimized.

Show comment
Hide comment
@abevoelker

abevoelker May 31, 2014

I've built off master, 0.11.1, 0.11.0, 0.10.0, 0.9.0, 0.8.0, and 0.7.6; all are exhibiting this behavior so far. Per the above-referenced commit, master chmods 755 and the other versions chmod 700.

I've built off master, 0.11.1, 0.11.0, 0.10.0, 0.9.0, 0.8.0, and 0.7.6; all are exhibiting this behavior so far. Per the above-referenced commit, master chmods 755 and the other versions chmod 700.

@abevoelker

This comment has been minimized.

Show comment
Hide comment
@abevoelker

abevoelker May 31, 2014

@vieux No problem, but I actually think that might be a red herring due to my original Postgres-based Dockerfile starting with 700 permissions, which just happened to coincide with the hardcoded permissions in the commit the bisect found. In my minimal reproduction Dockerfile where I start with 777 permissions, I cannot find a good commit that retains those permissions after VOLUME.

@vieux No problem, but I actually think that might be a red herring due to my original Postgres-based Dockerfile starting with 700 permissions, which just happened to coincide with the hardcoded permissions in the commit the bisect found. In my minimal reproduction Dockerfile where I start with 777 permissions, I cannot find a good commit that retains those permissions after VOLUME.

@shykes

This comment has been minimized.

Show comment
Hide comment
@shykes

shykes May 31, 2014

Collaborator

Thanks a lot @abevoelker and really sorry for the waste of your time. We will fix it asap. We really appreciate you taking the time to give such detailed reports.

Collaborator

shykes commented May 31, 2014

Thanks a lot @abevoelker and really sorry for the waste of your time. We will fix it asap. We really appreciate you taking the time to give such detailed reports.

@crosbymichael

This comment has been minimized.

Show comment
Hide comment
@crosbymichael

crosbymichael May 31, 2014

Contributor

Note:

This is not just permissions but ownership as well

Contributor

crosbymichael commented May 31, 2014

Note:

This is not just permissions but ownership as well

@abevoelker

This comment has been minimized.

Show comment
Hide comment
@abevoelker

abevoelker May 31, 2014

@shykes Oh my gosh no worries lol, you're way overestimating the value of my time. I'm just hoping this will lead to a fix that helps other people and doesn't end up just exposing something dumb I'm doing! :-)

And I must say the dev build process was really smooth so it didn't take much time at all to try out different docker versions. Kudos to you guys, you are changing the world! Happy to contribute a nano-sized piece to the effort.

@shykes Oh my gosh no worries lol, you're way overestimating the value of my time. I'm just hoping this will lead to a fix that helps other people and doesn't end up just exposing something dumb I'm doing! :-)

And I must say the dev build process was really smooth so it didn't take much time at all to try out different docker versions. Kudos to you guys, you are changing the world! Happy to contribute a nano-sized piece to the effort.

@abevoelker

This comment has been minimized.

Show comment
Hide comment
@abevoelker

abevoelker Jun 3, 2014

My Postgres image is now running flawlessly. Thank you @crosbymichael and others! 👍 :shipit:

My Postgres image is now running flawlessly. Thank you @crosbymichael and others! 👍 :shipit:

@crosbymichael

This comment has been minimized.

Show comment
Hide comment
@crosbymichael

crosbymichael Jun 3, 2014

Contributor

@abevoelker no problem, thanks for testing master

Contributor

crosbymichael commented Jun 3, 2014

@abevoelker no problem, thanks for testing master

@anentropic

This comment has been minimized.

Show comment
Hide comment
@anentropic

anentropic Dec 4, 2014

how do you make this work?

I have a Dockerfile like:

RUN useradd postgres
RUN mkdir -p /var/lib/postgresql
VOLUME /var/lib/postgresql
RUN chown -R postgres /var/lib/postgresql

if I then run that image the volume is still owned by root:

$ docker run -it postgres_data bash
[ root@c844a9bab4dd:~ ]$ ls -l /var/lib
drwxr-xr-x  2 root    root    4.0K Dec  4 07:24 postgresql/

how do you make this work?

I have a Dockerfile like:

RUN useradd postgres
RUN mkdir -p /var/lib/postgresql
VOLUME /var/lib/postgresql
RUN chown -R postgres /var/lib/postgresql

if I then run that image the volume is still owned by root:

$ docker run -it postgres_data bash
[ root@c844a9bab4dd:~ ]$ ls -l /var/lib
drwxr-xr-x  2 root    root    4.0K Dec  4 07:24 postgresql/
@anentropic

This comment has been minimized.

Show comment
Hide comment
@anentropic

anentropic Dec 4, 2014

if I do the chown in a bash script run by CMD, i.e. at run-time rather than build-time, then it sets permissions on the mounted volume ok... but I thought from the above it was possible via Dockerfile alone?

if I do the chown in a bash script run by CMD, i.e. at run-time rather than build-time, then it sets permissions on the mounted volume ok... but I thought from the above it was possible via Dockerfile alone?

@cpuguy83

This comment has been minimized.

Show comment
Hide comment
@cpuguy83

cpuguy83 Dec 4, 2014

Contributor

@anentropic You can't modify /var/lib/postgresql once you've called VOLUME on it.
So put your chown first.

Contributor

cpuguy83 commented Dec 4, 2014

@anentropic You can't modify /var/lib/postgresql once you've called VOLUME on it.
So put your chown first.

@anentropic

This comment has been minimized.

Show comment
Hide comment
@anentropic

anentropic Dec 5, 2014

thanks, this works

thanks, this works

@anentropic

This comment has been minimized.

Show comment
Hide comment
@anentropic

anentropic Dec 5, 2014

it doesn't seem to work when using host volume or --volumes-from though, in that case the permissions of the incoming volume still overwrite existing dir permissions

eg in a postgres Dockerfile I have

# /var/lib/postgresql path exists and is owned by postgres:postgres
VOLUME /var/lib/postgresql

(same result if I don't declare the volume in the dockerfile, just showing it doesn't help)

$ docker run -it postgres bash
postgres@ed134fb2d997:/$ ls -l /var/lib
drwxr-xr-x  3 postgres postgres 4096 Dec  4 23:37 postgresql

$ docker run -it --volumes-from 8f77483a50fc postgres bash
postgres@4abfbcb4411b:/$ ls -l /var/lib
drwxr-xr-x  2    1000    1000 4096 Dec  4 23:09 postgresql

$ docker run -it -v /Users/anentropic/.postgres_data:/var/lib/postgresql postgres bash
postgres@639f3e94690d:/$ ls -l /var/lib
drwxr-xr-x  1    1000 staff     68 Dec  5  2014 postgresql

is this intended behaviour? am I doing it wrong?
is there a proper way to do what I need to do, or a workaround?

in the case of --volumes-from and a data volume container I guess I could maybe force the postgres user to have the same uid in both containers... seems hacky though

it doesn't seem to work when using host volume or --volumes-from though, in that case the permissions of the incoming volume still overwrite existing dir permissions

eg in a postgres Dockerfile I have

# /var/lib/postgresql path exists and is owned by postgres:postgres
VOLUME /var/lib/postgresql

(same result if I don't declare the volume in the dockerfile, just showing it doesn't help)

$ docker run -it postgres bash
postgres@ed134fb2d997:/$ ls -l /var/lib
drwxr-xr-x  3 postgres postgres 4096 Dec  4 23:37 postgresql

$ docker run -it --volumes-from 8f77483a50fc postgres bash
postgres@4abfbcb4411b:/$ ls -l /var/lib
drwxr-xr-x  2    1000    1000 4096 Dec  4 23:09 postgresql

$ docker run -it -v /Users/anentropic/.postgres_data:/var/lib/postgresql postgres bash
postgres@639f3e94690d:/$ ls -l /var/lib
drwxr-xr-x  1    1000 staff     68 Dec  5  2014 postgresql

is this intended behaviour? am I doing it wrong?
is there a proper way to do what I need to do, or a workaround?

in the case of --volumes-from and a data volume container I guess I could maybe force the postgres user to have the same uid in both containers... seems hacky though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment