I have created an Image based on the official postgres:9.5.3 image.
This image runs fine on docker in linux (tested with ver 1.11.2), but fails to run on Docker for Mac beta (1.12.0-rc4-beta20, diagnostic id = 100BE54F-2248-4431-9382-6BA42F9FA120).
This feels like a serious bug since the premise of docker is that an image, once created, should run exactly the same everywhere…
The purpose of said image is to serve as a pre-seeded DB for tests running in a CI server.
During tests, I want to start a DB container that contains quite a lot of data, allow the test to read and write to it, and then after the test I want all the modifications discarded so they don’t affect the next test that uses this image.
Basically the image uses a non-volume directory as
PGDATA, containing data that was copied into the container with
docker cp. See “Steps to reproduce” for a full description of how the image was created.
The owner of the custom
PGDATA directory is
root (because it was copied in).
This is not an issue normally, because the postgres official image comes with an entrypoint script that starts with the following:
mkdir -p "$PGDATA" chmod 700 "$PGDATA" chown -R postgres "$PGDATA"
The image should run. Like I said, it runs fine on a linux version of docker.
After the entrypoint script is executed, the permissions of
PGDATA are correctly set to the
Then the database loads without issue and is works fine (I can connect, read write data).
On Docker for mac, an error is displayed soon after starting the container:
FATAL: could not open lock file "postmaster.pid": Permission denied
Investigating this, I did the following:
- Run a container based on the image with bash as entrypoint:
docker run --rm -it --entrypoint=/bin/bash avivrosenberg/test-db-bug
ls -al $PGDATA, see that everything is owned by
- Change the permissions of
PGDATAlike they do in the official entrypoint script:
chmod 700 "$PGDATA" && chown -R postgres "$PGDATA"
ls -al $PGDATA, see that everything is now owned by
- Try to write to the
PGDATAdirectory as the
gosu postgres touch $PGDATA/foo.bar
This leads me to:
touch: cannot touch ‘/var/lib/postgresql/test-data/foo.bar’: Permission denied
So basically, the
touch command I used failed for the same reason as the postgres process trying to create
postmaster.pid in the
PGDATA directory after changing permissions.
Steps to reproduce the behavior
What I did is basically:
- Start a container based on
postgres:9.5.3, with custom
- Write some data into the database using some program that connected to it. This is optional, not necessary for reproducing the bug.
- Stop the postgres process in the container so that everything is persisted to disk.
- Create (but don’t start) a second postgres container, set custom
docker cpto stream the
PGDATAdir from the first container to the second, like so:
docker cp $CONTAINER1:<path> - | docker cp - $CONTAINER2:<path>
docker committhe second container a new image.
The resulting image is the one that doesn’t run in Docker for mac.
The reason I’m creating the second container and using docker cp (instead of just committing the first one) is that i’m actually creating multiple DB snapshots, each based on the previous one. I don’t commit directly because then another layer is added and image size becomes a big issue.
To try it:
- The problematic image can be pulled from dockerhub:
docker pull avivrosenberg/test-db-bug.
- This gist is a script that generates a minimal image which reproduces the bug.