A Luminous Night

Musing and ramblings on automation, code and *nix

Wrangling in Those Misbehaving Docker Containers

While docker is all the rave, and for good reason, it is not without its drawbacks. One of the primary reasons we use Docker is to get more done with less work, but there are times when the boxed solution you have found does not work. Fortunately, we can easily take a broken Docker image and fix it up into shape.

Fix a Bad Image

Dockerfile to the rescue!

Use a Dockerfile to create a new image as an extension of the original:

1
2
3
4
5
# extend the broken image with your patches
FROM broken/image
# patch up the original
RUN touch /that/missing/file
RUN chmod -R user:user /home/user

Build a replacement image!

% docker build -t <tag> .
Sending build context to Docker daemon  2.56 kB
Sending build context to Docker daemon
Step 0 : FROM broken/image
 ---> 78ee0694f929
Step 1 : RUN touch /that/missing/file
 ---> Running in 78ee0694f929
 ---> ade3d87907de
Step 2 : RUN chown -R user:user /home/user/
 ---> Running in ade3d87907de
 ---> f1cdcfa9ffb8
Removing intermediate container ade3d87907de
Successfully built f1cdcfa9ffb8

Run with your new image!

% docker run -p 8080:8080 <tag>

Running Docker Without Sudo

Information about Docker suggests running docker commands with sudo, but I would prefer to use docker as my regular user.

Supposedly this is a documented topic, but I did not look hard enough to locate those details. Either way, it is pretty easy to do.

For an unpriviledged user..

Ensure the user is in the docker group

% usermod -G docker <user>

Restart the docker service

% service restart docker

Test with id

If you have not logged out, id will not include the docker group:

% id
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare)

Forcing the login, we will see this change:

% su -l user
Password: 
% id
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare),999(docker)

docker run should work!

% docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu' locally
ubuntu:latest: The image you are pulling has been verified
511136ea3c5a: Pull complete 
5bc37dc2dfba: Pull complete 
61cb619d86bc: Pull complete 
3f45ca85fedc: Pull complete 
78e82ee876a2: Pull complete 
dc07507cef42: Pull complete 
86ce37374f40: Pull complete 
Status: Downloaded newer image for ubuntu:latest
root@a91029463b28:/# 

Done!

Install Kivy on Raspberry Pi

Kivy is my favorite UI framework. Here is how to install and use it on Raspberry Pi. More documentation in the docs.

Install Kivy

Follow the docs for installing on Raspberry Pi.

Update apt for gstreamer:

% sudo echo 'deb http://vontaene.de/raspbian-updates/ . main' > /etc/apt/sources.list.d/gstreamer.list

Install system package dependencies

% sudo apt-get update
% sudo apt-get install pkg-config libgl1-mesa-dev libgles2-mesa-dev \
   python-pygame python-setuptools libgstreamer1.0-dev git-core \
   gstreamer1.0-plugins-{bad,base,good,ugly} gstreamer1.0-{omx,alsa}

Install cython with pip

The Debian package is out of date..

% sudo pip install cython

Get the Kivy source

Kivy’s support for Raspberry Pi and touchscreen hardware is under active development, it is simpler to run the code directly.

Clone the kivy repo to ~

% cd ~
% git clone https://github.com/kivy/kivy
% cd kivy

Build c source

% make

Update ~/.profile to include $PYTHONPATH

% echo "export PYTHONPATH=$(pwd):\$PYTHONPATH" >> ~/.profile
% source ~/.profile

Initial Octopress Setup

Since we’ve gotten this thing to work, why don’t we actually document how we did it.

Start with the Octopress Docs.

Ruby Setup

It makes a lot of sense to install virtual environments for Ruby as we would Python. This will keep the Ruby and gems installed for Octopress separate from the host system’s Ruby and gems.

More details here.

Install RVM

% curl -L https://get.rvm.io | bash -s stable --ruby

You can review the script first - it is good to be paranoid, you will give this script full system access through sudo.

% curl -L https://get.rvm.io | less

Install Ruby 1.9.3 with RVM

% rvm install 1.9.3 && rvm use 1.9.3 && rvm rubygems latest

Output will be similar to:

Searching for binary rubies, this might take some time.
Found remote file https://rvm_io.global.ssl.fastly.net/binaries/ubuntu/12.04/x86_64/ruby-1.9.3-p551.tar.bz2
Checking requirements for ubuntu.
Requirements installation successful.
ruby-1.9.3-p551 - #configure
ruby-1.9.3-p551 - #download
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11.3M  100 11.3M    0     0  1312k      0  0:00:08  0:00:08 --:--:-- 3065k
No checksum for downloaded archive, recording checksum in user configuration.
ruby-1.9.3-p551 - #validate archive
ruby-1.9.3-p551 - #extract
ruby-1.9.3-p551 - #validate binary
ruby-1.9.3-p551 - #setup
ruby-1.9.3-p551 - #gemset created /home/luminous/.rvm/gems/ruby-1.9.3-p551@global
ruby-1.9.3-p551 - #importing gemset /home/luminous/.rvm/gemsets/global.gems....................................
ruby-1.9.3-p551 - #generating global wrappers........
ruby-1.9.3-p551 - #gemset created /home/luminous/.rvm/gems/ruby-1.9.3-p551
ruby-1.9.3-p551 - #importing gemsetfile /home/luminous/.rvm/gemsets/default.gems evaluated to empty gem list
ruby-1.9.3-p551 - #generating default wrappers........
Using /home/luminous/.rvm/gems/ruby-1.9.3-p551
ruby-1.9.3-p551 - #downloading rubygems-2.4.4
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  433k  100  433k    0     0  4068k      0 --:--:-- --:--:-- --:--:-- 10.3M
No checksum for downloaded archive, recording checksum in user configuration.
ruby-1.9.3-p551 - #extracting rubygems-2.4.4....
ruby-1.9.3-p551 - #removing old rubygems.........
ruby-1.9.3-p551 - #installing rubygems-2.4.4..............

Test Ruby to confirm version

% ruby --version
ruby 1.9.3p551 (2014-11-13 revision 48407) [x86_64-linux]

Octopress setup

More details documented here.

Get Octopress source

% git clone git://github.com/imathis/octopress.git octopress

Cloning into 'octopress'...
remote: Counting objects: 10653, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 10653 (delta 7), reused 5 (delta 1)
Receiving objects: 100% (10653/10653), 2.79 MiB, done.
Resolving deltas: 100% (5134/5134), done.

Install Bundler

% cd octopress
% gem install bundler
Fetching: bundler-1.7.7.gem (100%)
Successfully installed bundler-1.7.7
Installing ri documentation for bundler-1.7.7
1 gem installed

Install Octopress dependencies

% bundle install

Output will look similar to:

Fetching gem metadata from https://rubygems.org/........                                                                                                                                                 [18/2888]
Resolving dependencies...
Installing rake 10.3.2
Installing RedCloth 4.2.9
Installing blankslate 2.1.2.4
Installing hitimes 1.2.2
Installing timers 4.0.1
Installing celluloid 0.16.0
Installing chunky_png 1.3.3
Installing fast-stemmer 1.0.2
Installing classifier-reborn 2.0.2
Installing coffee-script-source 1.8.0
Installing execjs 2.2.2
Installing coffee-script 2.3.0
Installing colorator 0.1
Installing fssm 0.2.10
Installing sass 3.2.19
Installing compass 0.12.7
Installing ffi 1.9.6
Installing tilt 1.4.1
Installing haml 4.0.5
Installing jekyll-coffeescript 1.0.1
Installing jekyll-gist 1.1.0
Installing jekyll-paginate 1.1.0
Installing jekyll-sass-converter 1.2.1
Installing rb-fsevent 0.9.4
Installing rb-inotify 0.9.5
Installing listen 2.8.0
Installing jekyll-watch 1.1.2
Installing kramdown 1.5.0
Installing liquid 2.6.1
Installing mercenary 0.3.5
Installing posix-spawn 0.3.9
Installing yajl-ruby 1.1.0
Installing pygments.rb 0.6.0
Installing redcarpet 3.2.0
Installing safe_yaml 1.0.4
Installing parslet 1.5.0
Installing toml 0.1.2
Installing jekyll 2.5.1
Installing jekyll-sitemap 0.6.3
Installing octopress-hooks 2.2.1
Installing octopress-date-format 2.0.2
Installing rack 1.5.2
Installing rack-protection 1.5.3
Installing rdiscount 2.1.7.1
Installing rubypants 0.2.0
Installing sass-globbing 1.0.0
Installing sinatra 1.4.5
Installing stringex 1.4.0
Using bundler 1.7.7
Your bundle is complete!
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from haml:

HEADS UP! Haml 4.0 has many improvements, but also has changes that may break
your application:

* Support for Ruby 1.8.6 dropped
* Support for Rails 2 dropped
* Sass filter now always outputs <style> tags
* Data attributes are now hyphenated, not underscored
* html2haml utility moved to the html2haml gem
* Textile and Maruku filters moved to the haml-contrib gem

For more info see:

http://rubydoc.info/github/haml/haml/file/CHANGELOG.md

Install Octopress

% rake install
## Copying classic theme into ./source and ./sass
mkdir -p source
cp -r .themes/classic/source/. source
mkdir -p sass
cp -r .themes/classic/sass/. sass
mkdir -p source/_posts
mkdir -p public

Configure

Edit _config.yaml

Set url at the very least, but might as well customize title, subtitle, author, and simple_search. We also remove/comment config for all 3rd party services except Github. Still need to verify if this worked as expected.

Deploy to Github.io

Read and follow the docs.

Create a new repo up on Github. For the simplest path, keep it empty. In case it matters, Octopress will not step on any existing commits, only add to them.

Initial github.io setup

% rake setup_github_pages

Create an empty post

Render HTML from source

% rake generate

Deploy to Github.io

% rake deploy

Setup Octopress source repo

Using Octopress rake setup_github_pages and rake deploy will manage commits and publishing to Github.io with the <user>.github.io repo. We also need a place to store the blog source.

Create a new git repo to keep the source.

Some people like to put both in the same repo (on separate branches). We will try something simpler for now - two repos. Octopress is managing the repo we deploy HTML to (created as part of setup_github_pages and with commits made/pushed by Octopress rake deploy), so it makes sense.

Add the remote URL

Jump to the Octopress repo root and run:

% git remote add origin git@github.com:user/octopress.git

Create branch for source

% git checkout -b source

Initial commit with custom config

% git add .
% git commit -m 'Initial commit with empty Octopress blog'

Push changes to remote git

% git push origin source

Using the blog

More docs here.

Generate a new post

Escaping the [ and ] was necessary for my shell setup with zsh. This will need to change.

% rake new_post\["Hello-Octopress"\]

Edit the post

The YAML header for a post looks like:

---
layout: post
title: "Hello Octopress"
date: 2014-11-22 18:00:06 +0000
comments: true
categories:
---

Disable comments and define some categories:

---
layout: post
title: "Hello Octopress"
date: 2014-11-22 18:00:06 +0000
comments: false
categories:
  - How To
  - Linux
  - Octopress
---

Add content below the header. For help with Markdown, compare a doc against the doc source code.

Use watch and preview

This will regenerate the HTML with changes made to the blog source and setup an HTTP server on localhost:4000 and available at http://localhost:4000. Use tmux to open a window/pane just for this, and be sure to activate the rvm first.

% rvm use 1.9.3
% rake watch &
% rake preview &

Setup SSH port forwarding

If the source is on a remote system, we can keep rake preview on the remote host but view the blog on http://localhost (with our browser), with all communication over SSH.

Forward localhost:4000 to a remote host

% ssh -L 4000:remote.host:4000 user@remote.host

Load http://localhost:4000 and revel with Octopress!

Done.