Public Repository

Last pushed: 2 years ago
Short Description
A minimalistic Postgresql 9.4.1.0 image
Full Description

This is a minimal postgres 9.4.1.0 server image. The server is built from source, with make world (thus containing the standard extensions).

A container built from this image depends on communitycloud/postgres-data:9.4 image with data. To run the server:

docker create --name pgdata -v /var communitycloud/postgres-data :
docker run --rm -it --volumes-from pgdata -u 1000 -p 5432:5432 communitycloud/postgres -D /var/pgsql/data

Note the : at the end of the docker create command is the minimal command; since the container only exists to seed the data volume and contains no binaries, this is the simplest command that docker will allow when creating a container.

Configuration

Optionally, one can modify the configuration files after creating the container, but before starting the server. Mount the data container's volume from a stock distribution that contains an editor, and then edit the config files in /var/pgsql/data:

docker run --rm -it --volumes-from pgdata debian:jessie /bin/bash

# vim /var/pgsql/data/pg_hba.conf 
...

Build

This image was built by hand on the scractch base to incorporate only the postgres binary and the libraries it depends on.

The build process is like this:

docker run --rm \
           --name pg-builder \
           --hostname pg-builder \
           -v /var/run/docker.sock:/var/run/docker.sock \
           -it communitycloud/docker-builder

communitycloud/docker-builder is a bare-bones Debian jessie official image with a statically compiled docker 1.4.1 binary copied into it.

To get the latest Postgres stuff, we'll need to add postgres sources first to apt, as described on the postgres wiki:

echo "deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
&& apt-get update && DEBIAN_FRONTEND=noninteractive \
&& apt-get install -y wget ca-certificates sudo \
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - \
&& apt-get update \
&& apt-get install -y build-essential tree strace libreadline-dev libncurses5-dev \
                      libpcre3-dev libssl-dev perl libpq-dev libossp-uuid-dev locales

Now that we have all prerequisites, building Postgres is fairly straightforward. We'll use /opt as the root:

wget https://ftp.postgresql.org/pub/source/v9.4.1/postgresql-9.4.1.tar.bz2 \
&& bunzip2 postgresql-9.4.1.tar.bz2 \
&& tar -xf postgresql-9.4.1.tar \
&& rm postgresql-9.4.1.tar \
&& cd postgresql-* \
&& ./configure \
    --prefix=/opt/pgsql \
    --with-openssl \
    --with-ossp-uuid \
&& make world \
&& make install-world \
&& cd .. \
&& rm -rf postgresql-* \
&& ldconfig

Remove unnecessary stuff:

rm -r /opt/pgsql/include/ /opt/pgsql/lib/pgxs /opt/pgsql/share/{doc,man}

cd / \
&& tar cf pgsql.tar \
    /opt/pgsql/bin/postgres \
    /opt/pgsql/lib/ \
    /opt/pgsql/share/ 

In addition, we'll need all libraries that the postgres binary and the extensions link to:

ldd /opt/pgsql/bin/postgres /opt/pgsql/lib/*.so \
    | grep -v '^/' \
    | awk 'BEGIN{ORS=" "}$1~/^\//{print $1}$3~/^\//{print $3}'  \
    | sed 's/ /\n/g; s/_at\n/_at /g' \
    | sort | uniq \
    | tar rhf pgsql.tar -T - 

This command figures out which libraries the binary depends on and collects them into a tar file. The h flag in tar dereferences all symlinks and imports the target files instead.

It turns out that Postgres also needs this file when running in a container:

tar rhf /pgsql.tar /lib/x86_64-linux-gnu/libnss_files.so.2

While we are at it, let's help our container find the libraries faster, and a few more files it wants, as we gleaned from the strace output:

tar rf /pgsql.tar /etc/ld.so.cache /etc/host.conf /etc/gai.conf \
                  /etc/nsswitch.conf /etc/protocols

Next, we need the postgres user in /etc.

mkdir -p /tmp/etc; cd tmp \
&& echo 'postgres:x:1000:1000::/home/postgres:/bin/sh' > etc/passwd \
&& echo 'postgres:x:1000:' > etc/group \
&& echo 'postgres:!:16452:0:99999:7:::' > etc/shadow \
&& echo 'postgres:!::' > etc/gshadow \
&& tar rf /pgsql.tar etc/

Since we mounted the docker client and a socket to the docker server, we can build the runtime image directly from the builder:

rm -rf /images/pgsql \
&& mkdir -p /images/pgsql && cp /pgsql.tar /images/pgsql \
&& cd /images/pgsql \
&& cat > Dockerfile <<EOF
FROM scratch
ADD pgsql.tar /
EXPOSE 5432
ENV PGDATA=/var/pgsql/data
ENTRYPOINT ["/opt/pgsql/bin/postgres"]
EOF

docker build -t pgsql . 

Running

The container must run as uid 1000, which will translate into the postgres user inside the container.

docker run --rm -u 1000 pgsql --version
=> postgres (PostgreSQL) 9.4.1

Container Layout

|-- etc
|-- lib
|   `-- x86_64-linux-gnu
|-- lib64
|-- opt
|   `-- pgsql
|       |-- bin
|       |-- lib
|       |   `-- pkgconfig
|       `-- share
|           |-- extension
|           |-- timezone
|           |   |-- Africa
|           |   |-- America
|           |   |   |-- Argentina
|           |   |   |-- Indiana
|           |   |   |-- Kentucky
|           |   |   `-- North_Dakota
|           |   |-- Antarctica
|           |   |-- Arctic
|           |   |-- Asia
|           |   |-- Atlantic
|           |   |-- Australia
|           |   |-- Brazil
|           |   |-- Canada
|           |   |-- Chile
|           |   |-- Etc
|           |   |-- Europe
|           |   |-- Indian
|           |   |-- Mexico
|           |   |-- Pacific
|           |   `-- US
|           |-- timezonesets
|           `-- tsearch_data
`-- usr
    `-- lib
        `-- x86_64-linux-gnu
Docker Pull Command
Owner
communitycloud