playing with docker
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 :)