I tried docker on RHEL. It’s very well documented but it’s not easy to understand how to build your own image. For testing, i tried a PostgreSQL one.

goal

I wanted to have a recent postgresql version(9.3) available on my RHEL 6 without making a mess in my system packages or compiling it.

The best way seems to be docker. It allows me to have a recent version with the datas and postgresql configuration files outside of the container. So it’s safe, easy to backup and could be moved to a standard system easily.

Installing docker on RHEL

Nothing special here. It’s very well documented here : RHEL installation

Dockerfile

I have a git repository on github with all the files of my container : docker_postgresql

An avantage here is new ubuntu version contains postgresql 9.3 so no need to define new apt repositories.

FROM ubuntu:14.04
# update packages
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get upgrade -y

# install postgresql
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql postgresql-contrib

Here an more interesting part :

# define data volume
VOLUME ["/data"]

It will define /data as a shared volume. It’s where i will store all datas.

When running the docker image, we will use the option -v to link this directory with one directory from the host :

-v /data:/data

The main problem with this solution is than it’s not possible to setup the database and user directly during the build phase.

So i need to add a startup script doing all this stuff when i instantiate the image :

# add parameters
ADD config.env /config.env

# Set the default command to run when starting the container
ADD start.sh /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]

This start.sh script check if the data directory exists. If not, it runs initdb and create a user based on the parameters in config.env file.

docker hub

Creating an image can take time but the good thing is the existing repositories in hub docker. It provides a lot of images for different services.

It’s also easy to provide his own images.

Only two commands, the one to login :

sudo docker login

And the one to push the image :

sudo docker push adejoux/postgresql
The push refers to a repository [adejoux/postgresql] (len: 1)
Sending image list
Pushing repository adejoux/postgresql (1 tags)
511136ea3c5a: Image already pushed, skipping
5e66087f3ffe: Image already pushed, skipping
4d26dd3ebc1c: Image already pushed, skipping
d4010efcfd86: Image already pushed, skipping
99ec81b80c55: Image already pushed, skipping
b36460ec7f39: Image successfully pushed
7b2d189afabb: Image successfully pushed
3837e9683707: Image successfully pushed
739ec2413801: Image successfully pushed
8a8b32c7812d: Image successfully pushed
b4d2e23a8aca: Image successfully pushed
a42665adfa10: Image successfully pushed
972577dcca4f: Image successfully pushed
badd392d772b: Image successfully pushed
Pushing tag for rev [badd392d772b] on {https://registry-1.docker.io/v1/repositories/adejoux/postgresql/tags/latest}

After that, the image is available for everyone in docker hub : adejoux/postgresql

image use

Getting the image on another computer is easy with docker :

docker pull adejoux/postgresql

Starting the container :

sudo docker run -d -p 5432:5432 -v /data:/data --name="adx_postgresql" adejoux/postgresql

Checking if it’s running with ps :

sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e530bc034707 adejoux/postgresql:latest /start.sh /bin/sh -c 5 seconds ago Up 5 seconds 0.0.0.0:5432->5432/tcp adx_postgresql

See container’s logs :

sudo docker logs adx_postgresql
Starting postgresql server
LOG: could not create IPv6 socket: Address family not supported by protocol
LOG: database system was interrupted; last known up at 2014-06-26 15:21:32 UTC
LOG: database system was not properly shut down; automatic recovery in progress
LOG: record with zero length at 0/18581A0
LOG: redo is not required
LOG: autovacuum launcher started
LOG: database system is ready to accept connections

conclusion

Docker is really great. I only played a little with it but i liked it very much :)