This was new territory for me but this guide will get you far enough for hacking around on a project. If this is an awful way of doing things let me know.
Same rules apply - we want to provision a project level Postgres instance listening on host port
5432 with a new database and user.
If you're not using
boot2docker(if you're on a supported Linux platform) you can skip this bit
Docker is primarily a Linux based tool but there are wrappers for Windows and OSX. Since I'm using a Mac I'll also use boot2docker that uses a Linux VM and proxies requests to the VM.
I'm going to assume that at this point we have
docker and, if necessary,
boot2docker installed. If you're using OSX
brew is your friend (
brew install boot2docker).
boot2docker installed we need to start it.
boot2docker init # only need this the first time boot2docker up
After this has started you should see an information message about setting the necessary environment variables to allow docker and boot2docker to talk correctly. There is a quick way to do all this provided by
Dockerfile specifies the rules for building a docker image that we can use to create container instances from. I'll just dump ours here and break it down after.
FROM ubuntu # add postgresql release repository to apt RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8 RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list # install the necesarry packages RUN apt-get update && \ apt-get install -y \ python-software-properties \ software-properties-common \ postgresql-9.4 # run the rest as the postgres user USER postgres # create the database and user RUN /etc/init.d/postgresql start && \ psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" && \ createdb -O docker docker # ensure host can connect to postgres correctly RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.4/main/pg_hba.conf RUN echo "listen_addresses='*'" >> /etc/postgresql/9.4/main/postgresql.conf # expose the 5432 port to outside the container EXPOSE 5432 # set the default command to run when starting the container CMD ["/usr/lib/postgresql/9.4/bin/postgres", \ "-D", "/var/lib/postgresql/9.4/main", \ "-c", "config_file=/etc/postgresql/9.4/main/postgresql.conf"]
The flow is somewhat similar to the previous post,
- We want to use the latest version of Postgres so we add the offical Postgres repo (and pgp-key) to the
- We install all the necessary packages
- Then we switch to the newly created
postgresuser to perform the rest of the operations
RUNwe start the database, create the user
dockerand finally create the
- We then update the necessary
*.conffiles to allow us to connect to the Postgres instance outside of the container.
- Next we
EXPOSEthe 5432 port to the outside world (in a
boot2dockerworld this exposes it from the container to the VM, we still have a bit of work to do to get it exposed to the actual host.
- Finally we stipulate how to start the Postgres instance when the container starts.
So now we have specified the rules in the
Dockerfile (this is somewhat similar to the Ansible playbook concept, sort of, but not quite) we want to build a versioned image from this,
docker build --tag postgres:9.4 --rm .
Running this from the same directory as the
Dockerfile will build an image called
postgres tagged with
--rm command tells docker to remove the intermediary images created.
We can see that our image has been created using the
docker images command
> docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE postgres 9.4 f25b0a52a81b 26 minutes ago 358.8 MB
Next we need to take this image and run it as a container,
docker run -p 5432:5432 --name postgres-instance -d postgres:9.4
Lets have a look at the option here,
-p 5432:5432publishes the
5432port effectively making it accessible outside the container.
--name postgres-instanceis the friendly name we want to give the container
-d postgres:9.4is the image name and tag to create the container from
We can verify the container instance is running using the
docker ps command
> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f54de34e1308 postgres:9.4 "/usr/lib/postgresql 22 minutes ago Up 22 minutes 0.0.0.0:5432->5432/tcp postgres-instance
At this point we should be able to access the Postgres instance via the IP of the VM. To ge the IP we can use the
ip command of
> boot2docker ip 192.168.59.103
boot2docker Port Forwarding
If we are using
boot2docker we still wont be able to access the instance via localhost. As already mentioned
boot2docker transparently uses a Linux VM (via VirtualBox) to run docker within. By default this VM doesn't forward any ports to the host so we need to tell
VBoxManage) to open that port.
VBoxManage modifyvm "boot2docker-vm" --natpf1 "postgres-port,tcp,127.0.0.1,5432,,5432"
This command tells VirtualBox to forward the 5432 TCP port of the
boot2docker VM to the host.
At this point we should be able to access the Postgres instance via
localhost on the host as well as the VMs IP address directly.