dimanche 13 avril 2014

Managing Docker images and containers

In addition to managing Docker resources (including containers, images, hosts) through the official CLI, there is plenty of solutions available in the community to manage Docker resources in a comprehensive way from a single web-based interface.

DockerUI

Once our containers are running, DockerUI can be use to manage the overall system. It's a simple web app with basic features for:
 - Check the states of the images (running, stopped)
 - Remove images
 - Start, Stop, Kill and Remove containers

DockerUI can be used with the following commands

1. Building the web app from the github repository and tag the build image
$docker build -t crosbymichael/dockerui github.com/crosbymichael/dockerui

2. Launch the built container, make the web app available on the 9000 port and connect to the docker uinx socket to remotely control docker
$docker run -p 9000:9000 -v /var/run/docker.sock:/docker.sock crosbymichael/dockerui -e /docker.sock

Then on the browser, visit localhot:9000 to get something like:

Shipyard

Shipyard is a more advanced Docker management solution based on a client-server architecture where the agents (i.e. clients) collect information on Docker resources and report them to the Shipyard server. It providers in addition to the features available in DockerUI:
 - Authentication
 - Building new images by uploading local Dockerfile or providing URLs to a remote location
 - In the browser terminal emulation for attaching containers
 - Visualizing CPU and memory utilization of the running images
 - ...

1. To use Shipyard, issue to pull the image from the Docker public index:
$docker run -i -t -v /var/run/docker.sock:/docker.sock shipyard/deploy setup

Now, we can register as admin to Shipyard on http://localhost:8000/

2. Install the latest release (e.g. v0.2.5) of Shipyard agent on every hosts to collect the information on Docker resources:
$curl https://github.com/shipyard/shipyard-agent/releases/download/v0.2.5/shipyard-agent -L -o /usr/local/bin/shipyard-agent
$chmod +x /usr/local/bin/shipyard-agent

3. Run the agent and register to the main host where Shipyard is running
$/usr/local/bin/shipyard-agent -url http://localhost:8000 -register

4. On the Shipyard interface, authorize the agents already deployed to enable them.
5. Run the agent with the given key at registration:
$/usr/local/bin/shipyard-agent -url http://localhost:8000 -key agent_key



Troubleshooting, in case you get this message:
Error requesting images from Docker: Get http://127.0.0.1:4243/images/json?all=0
Then stop the Docker service and re-start it while enabling Remote API access for any IP address:
$sudo service docker stop
$docker -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock -d &

happy dockering

dimanche 6 avril 2014

Automating Docker image builds with Dockerfiles

Hello Dockerfile
This is a continuation of an previous post on Docker with the aim of using specific scripts called dockerfiles in order to automate the steps that we have been issuing to build docker images. When docker parse the script file, it sequentially executes the commands starting from a base image to create a new one after each command.
The syntax of a dockerfile instruction is as simple as :
command argument1 argument2 ... 
or
command ["argument1", "argument2", ...]  only for the entry-point command !!

It's preferable to write the command in uppercase!

Dockerfile instructions
There is a dozen of instructions that can be present in a dockerfile, a detailed list can be found in the official documentation. The most common ones are:
  • FROM all dockerfile should start with this command that specify the name of the image to use as a working or base image;
  • RUN allows to run a command in the current container and commit (automatically) the changes to a new image;
  • MAINTAINER allows to specify information (name, email) on the person responsible for maintain this script;
  • ENTRYPOINT allows to specify what command should be executed at first once the container is started;
  • USER allows to specify with which user account the command inside the container have to be executed with; 
  • EXPOSE allows to specify what port to expose for the running container.
  • ENV to use for setting environment variables
  • ADD to copy files from the build context (it does not work if using stdin to read dockerfile) into a physical directory in the image (e.g. copying a war file into tomcat webapps folder)
Here you can find the official tutorial to experiment with these command.

Parsing dockerfiles
Once finished editing the build script, issue docker build to parse the dockerfile and create a new image. There is different ways to use this command:
  • dockerfile is in current directory docker build .
  • from stdin docker build - < Dockerfile
  • from a github repository docker build github.com/username/repo docker will then clone the repo and parse the files in the repo directory.

Example
Now lets take the instructions from the previous post and gather them into a dockerfile:
# Use ubuntu as a base image
FROM ubuntu

# update package respository
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list

RUN echo "deb http://archive.ubuntu.com/ubuntu precise-security main universe" > /etc/apt/sources.list
RUN apt-get update

# install java, tomcat7
RUN apt-get install -y default-jdk
RUN apt-get install -y tomcat7

RUN mkdir /usr/share/tomcat7/logs/
RUN mkdir /usr/share/tomcat7/temp/

# set tomcat environment variables
ENV JAVA_HOME=/usr/lib/jvm/default-java
ENV JRE_HOME=/usr/lib/jvm/default-java/jre
ENV CATALINA_HOME=/usr/share/tomcat7/

# copy war files to the webapps/ folder
ADD path/to/war /usr/share/tomcat7/webapps/

# launch tomcat once the container started
#ENTRYPOINT service tomcat7 start
ENTRYPOINT /usr/share/tomcat7/bin/catalina.sh run

# expose the tomcat port number
EXPOSE 8080

Save this script to Dockerfile, build it and tag the image by tomcat7, then launch the container while exposing publicaly the tomcat server port 8080, and finally check if the container is running
$docker build -t tomcat7 - < Dockerfile
$docker run -p 8080 tomcat7
$docker ps

to be continued;