Since the 0.9 version, Docker is shipped with the libcontainer execution driver and the containers can be accessed with the nsenter util (e.g. you don't need to install SSH in a container anymore!).

Nsenter is included in the util-linux package, from version 2.23.

If your distribution has an older versione of util-linux, you can compile it:

~$ curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-
~$ cd util-linux-2.24
~$ ./configure --without-ncurses
~$ make nsenter
~$ sudo cp nsenter /usr/local/bin

To enter a container you need to know its pid, which can be found with docker inspect knowing its ID:

~$ PID=$(docker inspect --format '{{.State.Pid}}' CONTAINER_ID)

Using the PID you can then enter the container:

~$ sudo nsenter --target $PID --mount --uts --ipc --net --pid /bin/bash

If you don't specify which program launch inside the container, ${SHELL} is run. I prefer to specify it (/bin/bash) because I use ZSH but I don't usually want to to install it inside the containers.


In the last post I suggested a minimal setup to begin with ruby-based TDD. In this post I want to show a possibile minimal setup for node.js-based TDD (node.js and npm must be installed). The kata will be again The Game of Life.

I'm not an expert of Node.js, so I hope what I'm writing is correct :)

I'll use the test framework Mocha and expect.js, a "Minimalistic BDD-style assertions for Node.JS and the browser".

Let's begin with the package.json file which will tell to npm what to install:

{
  "name": "game-of-life",
  "version": "0.0.1",
  "dependencies": {
    "mocha": "*",
    "expect.js": "*"
  }
}

With this file in the project folder you can run npm install to install the libraries. Then create the test/ folder with the mocha.opts file, where you can specify various options, like the reporter to use:

--reporter spec

With this file in place, the mocha command will launch the test.
So write the minimal js file and its corresponding test file:

test/game_of_life_test.js:

var expect = require('expect.js'),  
  GameOfLife = require('../lib/game_of_life');

describe('Universe', function(){  
  it('should have an initial size', function() {
    var u = new GameOfLife(6)
    expect(u.getSize()).to.equal(36);
  });
})

lib/game_of_life.js:

function GameOfLife(side){  
  this.size = side * side;
}
GameOfLife.prototype.getSize = function() { return this.size; }

module.exports = GameOfLife;  

Now launch mocha and the first test should pass:

~$ mocha

  Universe
    ✓ should have an initial size 

  1 passing

To know something more about TDD and Node.js, start reading this post from Azat Mardan


In the last weeks with the guys of the Firenze Ruby Social Club we started to think about organizing some Code Katas to play with test-driven development and yesterday we met to play with The Game of Life.

We used Ruby and RSpec with a simple setup that I want to report here if you'd like to play with some katas.

Although probably a Kata exercise won't need many gems, in ruby projects I like to always use a Gemfile with the required gems:

ruby '2.1.2'  
source 'https://rubygems.org'  
gem 'rspec'  

After a bundle install you're ready to start writing some code (if you don't have the bundle command, install the bundler gem with gem install bundler).

A basic example to begin TDD with the Game of Life could be this:

game_of_life_spec.rb:

require './game_of_life'

describe GameOfLife::Universe do  
  it "should have an initial size" do
    u = GameOfLife::Universe.new(6)
    expect(u.size).to eq(36)
  end
end  

game_of_life.rb:

module GameOfLife  
  class Universe
    attr_reader :size
    def initialize(side)
      @size = side**2
    end
  end
end  

With this minimalistic setup, the test passes:

~$ bundle exec rspec --color game_of_life_spec.rb
.

Finished in 0.00095 seconds (files took 0.0966 seconds to load)  
1 example, 0 failures  

You're now ready to start playing with TDD in Ruby :)


If you deploy a rails app forgetting to configure logs automatic rotation, few weeks later won't be difficult to find something like this:

$ ls -lh log/production.log
  -rw-rw-r-- 1 www-data www-data 93,2M apr 10 17:49 production.log

Think if you have to find some error log inside a 100MB file, not easy... :)

Setting log rotation isn't difficult at all. I know two main ways.

Use syslog

This is a really easy solution. Rails will use standard syslog as logger, which means the logs will rotate automatically.

Open config/environments/production.rb and add this line:

config.logger = SyslogLogger.new  

If you want to avoid your logs to be mixed with system logs you need to add some parameters:

config.logger = SyslogLogger.new('/var/log/<APP_NAME>.log')  

Use logrotate

This is the cleaner way, but requires to create a file in the server, inside the /etc/logrotate.d/ folder. This is a possible content of the /etc/logrotate.d/rails_apps file:

/path/to/rails/app/log/*.log {
    weekly
    missingok
    rotate 28
    compress
    delaycompress
    notifempty
    copytruncate
}

The copytruncate option is required unless you want to restart the rails app after log rotation. Otherwise the app will continue to use the old log file, if it exists, or will stop logging (or, worse, will crash) if the file is deleted.
Below the copytruncate details from the logrotate man page:

copytruncate  
      Truncate  the  original log file in place after creating a copy,
      instead of moving the old log file and optionally creating a new
      one,  It  can be used when some program can not be told to close
      its logfile and thus might continue writing (appending)  to  the
      previous log file forever.  Note that there is a very small time
      slice between copying the file and truncating it, so  some  log-
      ging  data  might be lost.  When this option is used, the create
      option will have no effect, as the old log file stays in  place.

To check the logrotate script you can use the logrotate command with the debug (-d) option, which executes a dry-run:

sudo logrotate -d /etc/logrotate.d/rails_apps  

If everything seems ok you can wait until the next day or manually launch the rotation with:

sudo logrotate -v /etc/logrotate.d/rails_apps  

If you, like me, have a lot of ruby apps and want to check if the code is vulnerable, Codesake::Dawn could be a useful gem.

This gem supports Rails, Sinatra and Padrino apps. To install it in a Rails app, add the gem to the development group in Gemfile:

group :development do  
  gem 'codesake-dawn', require: false
end  

then run bundle install.
Now add this line in the Rakefile:

require 'codesake/dawn/tasks'  

Install finished. To check the app you just have to run rake dawn:run:

~$ rake dawn:run
15:27:03 [*] dawn v1.1.0 is starting up  
15:27:04 [$] dawn: scanning .  
15:27:04 [$] dawn: rails v4.0.3 detected  
15:27:04 [$] dawn: applying all security checks  
15:27:04 [$] dawn: 171 security checks applied - 0 security checks skipped  
15:27:04 [$] dawn: 1 vulnerability found  
15:27:04 [!] dawn: Owasp Ror CheatSheet: Session management check failed  
15:27:04 [$] dawn: Severity: info  
15:27:04 [$] dawn: Priority: unknown  
15:27:04 [$] dawn: Description: By default, Ruby on Rails uses a Cookie based session store. What that means is that unless you change something, the session will not expire on the server. That means that some default applications may be vulnerable to replay attacks. It also means that sensitive information should never be put in the session.  
15:27:04 [$] dawn: Solution: Use ActiveRecord or the ORM you love most to handle your code session_store. Add "Application.config.session_store :active_record_store" to your session_store.rb file.  
15:27:04 [$] dawn: Evidence:  
15:27:04 [$] dawn:     In your session_store.rb file you are not using ActiveRercord to store session data. This will let rails to use a cookie based session and it can expose your web application to a session replay attack.  
15:27:04 [$] dawn:     {:filename=>"./config/initializers/session_store.rb", :matches=>[]}  
15:27:04 [*] dawn is leaving