2

I am creating a docker image for postgresql installation from sources. Here is my Dockerfile which I created according to the postgresql documentation:

FROM ubuntu

RUN apt-get update && apt-get install gcc zlib1g-dev libreadline6-dev apt-utils make -y

RUN mkdir -p /tmp/downloads

ADD https://ftp.postgresql.org/pub/source/v9.6.6/postgresql-9.6.6.tar.gz /tmp/downloads

RUN cd /tmp/downloads && tar -zxf postgresql-9.6.6.tar.gz

RUN cd /tmp/downloads/postgresql-9.6.6 && make configure
RUN cd /tmp/downloads/postgresql-9.6.6 && ./configure
RUN cd /tmp/downloads/postgresql-9.6.6 && make
RUN cd /tmp/downloads/postgresql-9.6.6 && su
RUN cd /tmp/downloads/postgresql-9.6.6 && make install
RUN cd /tmp/downloads/postgresql-9.6.6 && adduser postgres
RUN cd /tmp/downloads/postgresql-9.6.6 && mkdir /usr/local/pgsql/data
RUN cd /tmp/downloads/postgresql-9.6.6 && chown postgres /usr/local/pgsql/data
RUN cd /tmp/downloads/postgresql-9.6.6 && su postgres
RUN cd /tmp/downloads/postgresql-9.6.6 && /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
RUN cd /tmp/downloads/postgresql-9.6.6 && /usr/local/pgsql/bin/createdb test
RUN cd /tmp/downloads/postgresql-9.6.6 && /usr/local/pgsql/bin/psql test

So when I run docker build -t roksolanad/psql:latest . I get errors:

initdb: cannot be run as root
Please log in (using, e.g., "su") as the (unprivileged) user that will
own the server process.
The command '/bin/sh -c cd /tmp/downloads/postgresql-9.6.6 && /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data' returned a non-zero code: 1

So how can I fix my Dockerfile? I would be very grateful for some help!

2 Answers 2

3

Problem is that each RUN creates its own shell. Which means that username changes only persistent for that one instance. This is different from any filesystem changes which will persist.

Try chaining your commands together like this instead:

RUN cd /tmp/downloads/postgresql-9.6.6 &&\
    make configure &&\
    ./configure &&\
    make &&\
    su &&\
    make install &&\
    adduser postgres &&\
    mkdir /usr/local/pgsql/data &&\
    chown postgres /usr/local/pgsql/data

RUN cd /tmp/downloads/postgresql-9.6.6 &&\
    su postgres &&\
    /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data &&\
    /usr/local/pgsql/bin/createdb test &&\
    /usr/local/pgsql/bin/psql test
Sign up to request clarification or add additional context in comments.

1 Comment

I get just the same error, as I described. Also, on the previous step (which is make configure...) I can see such error message Enter new UNIX password: Retype new UNIX password: passwd: Authentication token manipulation error passwd: password unchanged Use of uninitialized value $answer in chop at /usr/sbin/adduser line 591. Use of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 592. Try again? [y/N] Changing the user information for postgres
1

As said by @Harald Nordgren, you need sum up all the RUN commands in one command, if possible.

Along with that there are couple of things which are causing the failures

1) adding "postgres" user:

"adduser" expects the additional parameters to be configured when you add a user, as you have mentioned in the comments like asking for password and so. So you need to modify the command to disable the arguments as well as the password like below:

adduser postgres --gecos '' --disabled-login 

2) executing postgress using root user

When you execute the command "su postgres", it executes with root user. But whereas we have changed the permissions in the above command "chown postgres /usr/local/pgsql/data"

For this you need a execute the command as "postgres" user which can be enabled by adding USER in dockerfile.

Finally your Dockerfile looks something like this:

FROM ubuntu

RUN apt-get update && apt-get install gcc zlib1g-dev libreadline6-dev apt-utils make -y

RUN mkdir -p /tmp/downloads

ADD https://ftp.postgresql.org/pub/source/v9.6.6/postgresql-9.6.6.tar.gz /tmp/downloads

RUN cd /tmp/downloads && tar -zxf postgresql-9.6.6.tar.gz

RUN cd /tmp/downloads/postgresql-9.6.6 &&\
    make configure &&\
    ./configure &&\
    make &&\
    su &&\
    make install &&\
    adduser postgres --gecos '' --disabled-login &&\
    mkdir /usr/local/pgsql/data &&\
    chown postgres /usr/local/pgsql/data

USER postgres

#use below command only if it is necessary, it is similar to "cd" linux command
WORKDIR /tmp/downloads/postgresql-9.6.6
RUN /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data 

With this I am able to create a Docker image and tested as well. Adding more information which may be useful.

# docker run -it postgres:2.0 /bin/bash
postgres@8354d83023f9:/tmp/downloads/postgresql-9.6.6$ ps -eaf
UID        PID  PPID  C STIME TTY          TIME CMD
postgres     1     0  0 10:58 ?        00:00:00 /bin/bash
postgres     9     1  0 10:59 ?        00:00:00 ps -eaf


postgres@8354d83023f9:/tmp/downloads/postgresql-9.6.6$ /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start
server starting

postgres@8354d83023f9:/tmp/downloads/postgresql-9.6.6$ ps -eaf
UID        PID  PPID  C STIME TTY          TIME CMD
postgres     1     0  0 10:58 ?        00:00:00 /bin/bash
postgres    13     1  0 10:59 ?        00:00:00 /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
postgres    15    13  0 10:59 ?        00:00:00 postgres: checkpointer process   
postgres    16    13  0 10:59 ?        00:00:00 postgres: writer process   
postgres    17    13  0 10:59 ?        00:00:00 postgres: wal writer process   
postgres    18    13  0 10:59 ?        00:00:00 postgres: autovacuum launcher process   
postgres    19    13  0 10:59 ?        00:00:00 postgres: stats collector process   
postgres    20     1  0 10:59 ?        00:00:00 ps -eaf


postgres@8354d83023f9:/tmp/downloads/postgresql-9.6.6$ /usr/local/pgsql/bin/createdb test


postgres@8354d83023f9:/tmp/downloads/postgresql-9.6.6$ /usr/local/pgsql/bin/psql test
psql (9.6.6)
Type "help" for help.

test=# 
test=# 

There are other ways to build this docker image but this way I am able to.

1 Comment

Thank you very much for helping me to fix this bug and for the clear explanation!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.