Tag Archives: docker

PRUN: Ruby server with Docker

logo-plumbadge

The idea is that: as equivalent to LAMP (Linux/Apache/Mysql/Php) architecture, in Ruby world we could have

PRUN architecture: Postgresql + Ruby + Ubuntu + Nginx.

Name: ‘Prun’ means ‘Plum’ in Romanian language.

I have used Docker to create a container with:

  • Ubuntu 14.04 trusty
  • Postgres 9.3
  • Ruby 2.1.2
  • Nginx 1.4.6

Also based on OpenSSH to connect, Chef to manage Rails apps configurations and Supervisor to maintain daemons at the container.

The repo is published on https://github.com/jlebrijo/prun and you can see the image at Docker hub https://registry.hub.docker.com/u/jlebrijo/prun/

The basic operation should be (details in the next post):

  1. Install with Docker: docker run -d -p 2222:22 -i jlebrijo/prun
  2. Manage configuration with Chef: knife solo cook root@lebrijo.com -p 2222
  3. Deploy with Capistrano: cap production deploy

That easy!!

Docker basics

Installation

[On Ubuntu 14.04] Installation:

sudo apt-get update
sudo apt-get install -y docker.io
sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io

Last version installation:

wget -qO- https://get.docker.io/gpg | sudo apt-key add -
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker -y

Removing sudo for commands

I order to avoid ‘sudo’ prefix in all docker commands, here I write a tip for removing sudo from all Docker commands:

# Add the docker group
sudo groupadd docker
 
# Add the connected user "${USERNAME}" to the docker group.
sudo gpasswd -a ${USERNAME} docker
# Logout/Login with this user for changes to take effect
 
# Restart the docker daemon.
sudo service docker.io restart

Run your first container

Docker Hub is the big repo of images. You can login by ‘docker login’

Download image and run container console:

docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# exit

Basic operations

Operations with Containers:

  • ‘docker ps [-a] CONTAINER’ containers running (-a shows all including stopped)
  • ‘docker logs -f CONTAINER’ container standard output
  • ‘docker top CONTAINER’ container processes running list
  • ‘docker inspect CONTAINER’ container low level json report
  • ‘docker stop CONTAINER’ stops the container
  • ‘docker start CONTAINER’ restarts a container previously stopped
  • ‘docker rm [-f] CONTAINER’ removes definitely a container previously stopped. ‘docker rm -f $(docker ps -a -q)’ removes all containers.

Operations with images:

  • ‘docker images’ list images in workstation
  • ‘docker search TERM’ search images (look at Docker Hub)
  • ‘docker tag [ID] [NAME]:[TAG]’ tags an image
  • ‘docker push [NAME]’ upload image to Docker.hub
  • ‘docker rmi [NAME]’ locally removes an image

Create an Image

mkdir ubuntu-chef
cd ubuntu-chef
touch Dockerfile

And write it:

# Ubuntu + chef-solo
FROM ubuntu:14.04
MAINTAINER Juan Lebrijo "juan@lebrijo.com"

RUN apt-get -y update
RUN apt-get -y install curl build-essential libxml2-dev libxslt-dev git
RUN curl -L https://www.opscode.com/chef/install.sh | bash

Operations with Chef:

  • ‘docker build -t jlebrijo/ubuntu-chef .’ creates an image
  • docker run -d -m 8g –cpuset 0-7 –name rails_stack -p 2222:22 -i jlebrijo/trusty-chef
  • knife solo cook root@localhost -p 2222
  • ssh root@localhost -p 2222

Tricks

  • Stopping all containers: docker stop $(docker ps -a -q)
  • Removing all containers: docker rm $(docker ps -a -q)

Exposing a port on a live container

You need to create an image from your container and restart the container based on this image:

docker stop www
docker commit www www-image
docker rm www
docker run --detach=true --name www -p 2222:22 -p 80:80 -p 443:443 -p 9292:9292 www-image
docker rm www-image

 

Docker vs Vagrant

Thanks to a question of my friend Xavier: “Is this something that might potentially interest us? CoreOS Now Available On DigitalOcean!“, I reopened this internal discussion “Vagrant or Docker, this is the question?”. Well here are my thoughts ….

CoreOS is a minimal Linux Distro in order to save RAM when you manage Clusters (or slices within a machine). They promise  to use only 144MB RAM.

When you use Docker, you need a host OS in your Server (CoreOS promises to be the lighter host OS).

So the question here is …… should we use Docker?

  • SERVER SIDE:
    • Docker/CoreOS are scalability tools: as Adrian said this is a really powerful tool to scale applications, you can deploy packaged containers (slices) within a server and among servers in a farm. CoreOS seems to help a lot at this point also, running ‘etcd‘ by default.
    • Removes Lock-in: You can move your apps among providers (DO, Rackspace, AWS, Linode,… your private farm). Once you have your container configured, you just need to have a linux host (an AWS linux AMI, Ubuntu, CoreOS ….) with Docker installed.
  • DEVELOPER SIDE: Docker instead of Vagrant to emulate the system locally (take a look at this great discussion between both creators)
    • This is only possible, for the moment, if your app servers are linux (this does not mean that your Dev workstation should be Linux)
    • Docker engine (Virtualization layer) is based on LXC, which manages chroot, network, mount… all kernel “Containerizing” capabilities directly. This efficiency is extreme if your local OS is Linux.
      • Vagrant lies over VirtualBox which creates a lot of CPU and Memo overhead.
    • Portability: Docker allows to reproduce EXACTLY the production scenario in your workstation (or other environments like staging or testing). You just need Docker/Linux installed in both, and Docker acts as an abstraction layer.
      • Vagrant offers images which haven’t the same configuration as your provider’s images (I experienced this directly: ubuntu-14.04 has not the same configuration in vagrantcloud.com‘s box, and DigitalOcean.com’s image)
    • Images weight: Vagrant boxes are much larger than Docker repos (ubuntu/trusty is ~600MB image box, against 64MB as Docker repo)

I was until this weekend with an eye on this Infrastructure Maintenance Stack:

  • Chef: Manages server installation and future configurations.
  • Vagrant: reproduces (approximately) our production server in order to check configurations.
  • Capistrano: Manages continuous deployment.

But due to read (and tests) about Docker this weekend, I am thinking to substitute Vagrant per Docker (the reasons above are really persuasive).

So, hey guys!! what do you think? Is Docker/CoreOs something that might potentially interest us?