How to properly set VOLUME and CMD instructions in Postgres Dockerfile?

1k views Asked by At

I have a working Postgres Dockerfile that I modify and unfortunately after applying modifications Postgres container stops working as expected. I'd like to ask your for explanation of what I'm doing wrong.

Working example

Here's the Postgres Dockerfile that works and which I modify:

# Use ubuntu image
FROM ubuntu

# Install database
RUN apt-get update && apt-get install -y postgresql-9.3

# Switch to postgres user.
USER postgres

# Create databse and user with all privileges to the database.
RUN /etc/init.d/postgresql start && \
    psql --command "CREATE DATABASE docker;" && \
    psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
    psql --command "GRANT ALL PRIVILEGES ON DATABASE docker TO docker;"

# Allow remote connections to the database.
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.3/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf

# Add VOLUMEs to allow backup of config, logs and databases
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

# Set the default command to run when starting the container
CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

I build it like that:

docker build --tag postgres-image .

Then I create a container:

docker run -d -it -p 32768:5432 --name=postgres postgres-image

And I connect with database:

psql -h localhost -p 32768 -d docker -U docker --password

First modification

I don't need to have any volumes because I'm going to use data-only container that will store all Postgres data. When I remove the line:

VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

and do all steps like in working example I get the following error after passing password in the last step:

psql: FATAL:  the database system is starting up
FATAL:  the database system is starting up

So the question is: Why do I need VOLUME instruction in the Dockerfile?

Second modification

This modification doesn't include the first one. Both modification are independent.

The parameters used in CMD instraction points to default Postgres data directory and configuration file so I wanted to simplify it by setting CMD to the command I always use to start Posgres:

service postgres start

After setting CMD to:

CMD ["service", "postgres", "start]

and doing all steps like in working example I get the following error after passing password in the last step:

psql: could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 32768?

The question is: Why the command that works on my host system doesn't work in Docker container?

1

There are 1 answers

4
Adrian Mouat On BEST ANSWER

I'm not sure about the first problem. It may be that Postgres doesn't like running on top of the UFS.

The second problem is just that a container will exit when its main process ends. So the command "service postgres start" runs, starts Postgres in the background then immediately exits and the container halts. The first version works because Postgres stays running in the foreground.

But why are you doing this? Why not just use the official Postgres image?