How to Setup Rails, Docker, PostgreSQL (and Heroku) for Local Development ?

My current side project is an online tool to do remote planning pokers. I followed my previous tutorial to setup Rails, Docker and Heroku.

Naturally, as a BDD proponent, I tried to install cucumber to write my first scenario.

Here is the result of my first cucumber run :

1
2
3
4
$ docker-compose run shell bundle exec cucumber
rails aborted!
PG::ConnectionBad: could not translate host name "postgres://postgres:@herokuPostgresql:5432/postgres" to address: Name or service not known
...

It turned out that I had taken instructions from a blog article on codeship that mistakenly used host: instead of url: in their config/database.yml

After fixing that in my database.yml file, things where only slightly working better :

1
2
3
4
$ docker-compose run shell bundle exec cucumber
rails aborted!
ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR:  cannot drop the currently open database
: DROP DATABASE IF EXISTS "postgres"

The thing is the config was still using the same database for all environments. That’s not exactly what I wanted. I updated my config/database.yml :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000
  username: postgres
  port: 5432
  host: herokuPostgresql

development:
  <<: *default
  database: planning_poker_development

test: &test
  <<: *default
  database: planning_poker_test

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>

Victory ! Cucumber is running

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ docker-compose run shell bundle exec cucumber
Using the default profile...
0 scenarios
0 steps
0m0.000s
Run options: --seed 45959

# Running:



Finished in 0.002395s, 0.0000 runs/s, 0.0000 assertions/s.

0 runs, 0 assertions, 0 failures, 0 errors, 0 skips

Fixing rake db:create

By searching through the web, I found that people were having similar issues with rake db:create. I tried to run it and here is what I got :

1
2
3
$ docker-compose run shell bundle exec rake db:create
Database 'postgres' already exists
Database 'planning_poker_test' already exists

Why is it trying to create the postgres database ? It turns out that the DATABASE_URL takes precedence over what is defined in my config/database.yml. I need to unset this variable locally. I already have the docker-compose.override.yml for that :

1
2
3
4
5
6
7
8
9
web:
  environment:
    DATABASE_URL:
  ...

shell:
  environment:
    DATABASE_URL:
  ...

Rake db:create works just fine now :

1
2
3
$ docker-compose run shell bundle exec rake db:create
Database 'planning_poker_development' already exists
Database 'planning_poker_test' already exists

Starting a psql session

During all my trouble-shootings, I tried to connect to the Postgresql server to make sure that the databases where created and ready. Here is how I managed to do that :

1. Install psql client

On my Ubuntu machine, that was a simple sudo apt-get install postgresql-client-9.4.

2. Finding the server port

The port can be found through config/database.yml or through docker ps. Let’s use the later, as we’ll need it to find the server IP as well.

1
2
3
$ docker ps
CONTAINER ID        IMAGE            COMMAND                  CREATED             STATUS              PORTS           NAMES
b58ce42d2b2b        postgres         "/docker-entrypoint.s"   46 hours ago        Up 46 hours         5432/tcp        planningpoker_herokuPostgresql_1

Here the port is clearly 5432.

3. Finding the server IP

Using the container id we got on previous docker ps command, we can use docker inspect to get further details :

1
2
3
4
$ docker inspect b58ce42d2b2b | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",

4. Connecting to the database

Connecting is now just a matter of filling the command line.

1
2
3
4
5
$ psql -U postgres -p 5432 -d planning_poker_development -h 172.17.0.2
planning_poker_development=# select * from schema_migrations;
 version
---------
(0 rows)

5. Installing psql client directly in the shell

It should be possible to install the psql client in the shell container automatically, but I must admit I did not try this yet. It should just a matter of adding this to the Dockerfile

1
RUN apt-get install postgresql-client-<version>

How to Boot a New Rails Project With Docker and Heroku

A few years ago, I used Heroku to deploy my side-project. It provides great service, but I remember that updates to the Heroku Stack was a nightmare … Versions of the OS (and nearly everything) changed. The migration was a matter of days, and while doing a side-project, this was difficult. At the time, I remember thinking that using branches and VMs would have been the solution.

Now that I started to use Heroku again, I decided to use Docker from the beginning. More specifically, I am expecting :

  • to have a minimal setup on my host machine
  • to use the same infrastructure in dev than in production
  • to simplify switching to a new machine
  • to simplify the migration to the next Heroku stack

As an added benefit, if ever someone else joins me in my side-project, it will be a matter of minutes before we can all work on the same infrastructure !

Heroku provides a tutorial about how to deploy an existing Rails app to heroku using containers. Unfortunately, I did yet have an existing rails app … So the first challenge I faced, was how to create a Rails app without actually installing Rails on my machine. The trick is to bootstrap rails in docker itself before packaging all this for Heroku.

1. Install the required software

I installed only 4 things on my host machine – Docker instructions – Docker Compose instructions – Heroku Toolbelt instructions – Heroku container plugin heroku plugins:install heroku-container-tools

That’s all I changed to my host machine.

2. Setup docker

First, let’s create a new dir and step into it. Run :

1
2
mkdir docker-rails-heroku
cd docker-rails-heroku

To prepare the Heroku setup, create a Procfile

1
web: bundle exec puma -C config/puma.rb

and app.json

1
2
3
4
5
6
7
8
{
  "name": "Docker Rails Heroku",
  "description": "An example app.json for container-deploy",
  "image": "heroku/ruby",
  "addons": [
    "heroku-postgresql"
  ]
}

To generate docker files for Heroku, run :

1
heroku container:init

You want to run Rails in dev mode locally, so we need to override Heroku’s default env (Check my previous post for details)

Create an .env file

1
RAILS_ENV=development

and docker-compose.override.yml

1
2
3
4
5
6
7
8
9
web:
  volumes:
    - '.:/app/user'
  environment:
    RAILS_ENV: "${RAILS_ENV}"

shell:
  environment:
    RAILS_ENV: "${RAILS_ENV}"

3. Create the Rails app

It’s now time to follow the official docker-compose rails tutorial to bootstrap the rails app and directories :

Change Dockerfile to

1
2
3
4
5
6
7
8
9
10
# FROM heroku/ruby

FROM ruby:2.2.0
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp

Create a bootstrap Gemfile with the content

1
2
source 'https://rubygems.org'
gem 'rails', '4.2.0'

Bundle install within the container requires a existing Gemfile.lock

1
2
# Create an empty Gemfile.lock
touch Gemfile.lock

It’s now time to build your docker container to be able to run rails and generate your source files. Run the following :

1
2
3
4
5
# Build your containers
docker-compose build

# Run rails within the shell container and generate rails files
docker-compose run shell bundle exec rails new . --force --database=postgresql --skip-bundle

Unfortunately, rails is ran as root inside the container. We can change ownership and rights with this command :

1
2
3
4
5
# Change ownership
sudo chown -R $USER:$USER .

# Change rights
sudo chmod -R ug+rw .

4. Make it Heroku ready

Now that the rails files are generated, It’s time to replace the bootstrap settings with real Heroku Dockerfile

Revert Dockerfile to simply :

1
FROM heroku/ruby

Heroku uses Puma so we need to add it to our Gemfile

1
2
# Use Puma as the app server
gem 'puma', '~> 3.0'

We also need to add a config file for Puma. Create config/puma.rb with this content (you can check heroku doc for details)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end

It should now be possible to rebuild the container, and run the app :

1
2
3
4
5
# Rebuild the containers
docker-compose build

# Start the rails app using the web container
docker-compose up web

The app should be accessible at http://0.0.0.0:8080

5. Deploying to heroku

We’re almost ready to deploy to heroku.

First, we need to exclude development files from our image. For this, we need to create a .dockerignore file with the content

1
2
3
4
5
6
7
8
9
10
.git*
db/*.sqlite3
db/*.sqlite3-journal
log/*
tmp/*
Dockerfile
.env
docker-compose.yml
docker-compose.override.yml
README.rdoc

It’s then classic Heroku deploy commands :

1
2
3
4
5
# create an Heroku app
heroku apps:create <your-app-name>

# And deploy to it
heroku container:release --app <your-app-name>

Your app should be accessible on line at https://<your-app-name>.herokuapp.com/

Rails does not provide a default homepage in production. But you can check the logs with

1
heroku logs --app <your-app-name>

6. Running commands

When in development mode, you might want to run rails or other commands on your source code again. The shell container exists just for that, run docker-compose run shell ....

1
2
# For example, to update your bundle
docker-compose run shell bundle update

EDIT 2016-07-20

For the moment, there’s a catch with bundle install or update commands, as the gems are installed outside the shared volume, only Gemfile.lock will be updated, which required to run docker-compose build again … I’ll have a look into this later and see if I can fix that.

1
2
docker-compose run shell bundle update
docker-compose build

Docker Compose Trick : How to Have an Overridable Environment Variable in Development Mode ?

I have recently been playing with Docker and Docker Compose while starting my new side project. I’ve fallen into a situation where my production container uses a value for an environment variable, but while developing, I’ll need both a different default and the ability to override this value.

I’m using Rails and found various references about how to deploy Rails app using Docker, but in the end, I decided to use Heroku which handles a lot of ops for me. Rails uses the RAILS_ENV environment variable to know if it’s going to run in development, test or production mode. The heroku/ruby image sets RAILS_ENV=production, but we usually want to use RAILS_ENV=development locally. I could have overridden RAILS_ENV in a docker-compose.override.yml file, but that would prevent me from running my app in production locally.

The trick

I eventually fixed my issue with combination of 2 files.

docker-compose.override.yml

1
2
3
4
5
web:
  ...
  environment:
    RAILS_ENV: "${RAILS_ENV}"
...

.env

1
RAILS_ENV=development

The logs

My app starts in development mode by default :

1
2
3
4
5
6
7
8
9
10
philou@philou-UX31E:~/code/planning-poker$ docker-compose up web
Starting planningpoker_herokuPostgresql_1
Recreating planningpoker_web_1
Attaching to planningpoker_web_1
web_1               | Puma starting in single mode...
web_1               | * Version 3.4.0 (ruby 2.2.3-p173), codename: Owl Bowl Brawl
web_1               | * Min threads: 5, max threads: 5
web_1               | * Environment: development
web_1               | * Listening on tcp://0.0.0.0:8080
web_1               | Use Ctrl-C to stop

But I can still override RAILS_ENV to test for example :

1
2
3
4
5
6
7
8
9
10
philou@philou-UX31E:~/code/planning-poker$ RAILS_ENV=test docker-compose up web
planningpoker_herokuPostgresql_1 is up-to-date
Recreating planningpoker_web_1
Attaching to planningpoker_web_1
web_1               | Puma starting in single mode...
web_1               | * Version 3.4.0 (ruby 2.2.3-p173), codename: Owl Bowl Brawl
web_1               | * Min threads: 5, max threads: 5
web_1               | * Environment: test
web_1               | * Listening on tcp://0.0.0.0:8080
web_1               | Use Ctrl-C to stop

5 Years of Blogging About Software

5 years ago, I started blogging. I started really casually, my posts were personal reminders and notes rather than real well thought of articles. Nevertheless, it did me great good :

  • I’ve been invited to talk at meetups
  • I’ve had the joy of seeing some articles being tweeted many times
  • I received interesting job offers from all over the world

6 months ago, after reading Soft Skills: The software developer’s life manual, I set up the practice of writing at least one article per week, and here is my (very encouraging) graph of sessions since then:

Excuses Why Not To Blog

Here is a collection of the (bad) excuses you’ll often hear people say for not blogging :

I don’t know how to write …

Blogging regularly is actually a pretty good way to improve your writing skills. As usual, the key is to fake it until you make it.

I’m not into this social media stuff …

You don’t need to share anything personal on your software blog. In the end, your blog is a professional tool.

I don’t have anything interesting to say …

They are others in the same situation as you who would like to see more posts about the kind of uninteresting things you just discovered. Wouldn’t you have liked someone to have written the newby article about « how to do XXX » you just spent 3 days to crack ?

I don’t have the time …

Make it ! Time is never found, it is made. In the end, it’s just a matter of prioritization.

Obviously, there are other totally valid reasons why not to blog, but I’ll assume you’re able to recognize those.

Why Would You Blog ?

On the other side, if you jump into blogging, you can expect a lot of returns :

  • First thing is that you’ll obviously gain more visibility. I’ve got readers from all over the world, and my articles are sometimes re-tweeted many times.
  • You’ll improve your writing skills. Writing skills turn out to be unexpectedly important for software writers !
  • In order to lay down your ideas about something, you’ll need to dig a bit more into. It is said to be the last step to learning.
  • It can act as a personal documentation. I used to write mine as a how-to notepad on which I could refer later on.
  • If you have a day job, you can re-post your articles there. You should gain extra visibility and expose the company to new ideas.

How to start

Once you’ve decided that you want to blog, starting should not be an issue.

Pick a platform

There are a lot of blogging platforms out there. For programmers, I would recommend a few though :

Platform Pros Cons
Octopress Free, Open Source, Github hosting, static HTML generation, markdown & Git based, made for programmers Theming can be rocky
Medium Free, no setup, good looking, simple to use It’s a private company, so it could close some day ! It happened to postero.us (I remember, I was there …)
Posthaven Created by the founders of postero.us, sustainable, guarantees to keep it live for ever, can post by email ! Nothing special for programmers, 5$ / month
Logdown Looks like a hosted version of Octopress, without the hassle ! 50$/year

Then, it’s up to you !

Start with how-to articles

When I started my blog, it was mostly has a personal how-to reference. It allowed me to come back to it and find out how I did something last time. I thought that if it was important to me, it must be important to others as-well !

Blog regularly

Blogging every week made a huge difference to me. My traffic went from erratic to steadily increasing. I am currently observing a 11% traffic increase per month. This means that it nearly quadruples every year : I’m not going to stop now !

Integrate with the web

This boils down to social networks and analytics. Obviously, you’ll want to use Google Analytics to see how people are reading your content. I’m using the venerable Feedburner to automatically post my new articles on twitter. There’s an option to use your post categories as hashtags, be sure to make it works, it brings a lot of traffic.

It’s all up to you now !

The Size of Code

The CFO’s debt is visible in his balance sheet. The CTO’s technical debt is invisible. What about making it visible ?

Developers have an intuitive sense of the technical debt in some parts of the system. But few have an accurate estimation of its full extent. Even the size of a code base is difficult to grasp. In the same way, the size of the code is just a number. But the fact are there : between 10 000 and 10 000 000 lines of code, the rules aren’t the same, but it’s only invisible data on hard drives …

Showing It

If we had a device or a trick to show to non-developers the size of the source code, people might start to feel the embarrassment of working in a bloated code base. Unfortunately, for the moment, the only ideas I had are somehow unrealistic, albeit funny !

First Idea : Printouts

Suppose we printed all the source code every Monday, and then keep it around for everyone to feel its size. We could leave it in the middle of the place, or in the CTO’s office, so that he’d actually be hindered by the space loss. The larger the code, the bigger the troubles.

It’s possible to print 50 lines on a sheet of paper, that’s 100 on both sides. That’s 50 000 in a pack of 500 pages. And eventually, 200 000 in this kind of standard case :

Keeping these printouts in sync with the real cost would make the thing even more painful realistic. Imagine all the printings costs, and moving around cases of paper every day … ;)

Second Idea : Inflatable Device

What about an inflatable device linked to SonarQube (or any other code metrics tracking system) ? It could grow as new code is written. We could make it as large as we want : 1m3 for every 10K lines of Code, making the whole office a difficult place to walk around. Try to figure out how to work with this thing in the office :

Third Idea : Sand

For maximum pain, let’s use real sand instead of an inflatable device ! Imagine the mess with some sand lying around in the office. If the only way to clean up the mess was to clean up the code, surely everyone would take the issue seriously !

Final Word

Obviously, these are jokes, but I guess there’s a real need there. If we managed to make non developers feel the size and cost of the code base, it would be easier to agree on priorities.

Legacy Code Coverall Day

Some days, coding feels like speleology or mining … Dealing with weird and undocumented old logic can even some time be damaging to the mind ! I think we should go to work wearing the adequate protection !

OK, maybe we cannot start to go to work wearing a coverall everyday, but let’s say very 21st of June is now legacy code day, the day when every developer maintaining legacy code comes to work dressed like that !

Obviously, that’s a joke, but it could attract the attention of other non-coding people on the state of their codebase and amount of their technical debt.

Anti Ugly-Code Glasses

I think I found a way to fix the dirty code problem once and for all …

In The Hitchhiker’s Guide to the Galaxy Zaphod Beeblebrox has some anti panic glasses. They feature some special danger detection mechanism that turns them opaque black to save their bearer from panicking.

(It turns out that Zaphod has two heads …)

In 2016, it’s shocking that some many hours are lost by poor developers reading ugly code.

Let’s build anti ugly-code glasses ! We’d just need an IDE or editor plugin, connect it to Sonar in order to get the quality of the current file, and if too bad, shut the glasses black !

Finally the killer feature for augmented reality glasses !

How to Keep Up With Software Technologies

Since I started to program professionally 15 years ago, a lot of things have changes. A lot of technologies appeared and became mainstream while others fell out of fashion.

As software developers, it is really challenging to stay fit and productive in new technologies. I cannot obviously say that I am an expert in all new technologies, but I can say that I can get up to speed in a pretty short time in nearly all.

If there is a single reason for that I strongly believe it is because “I studied my classics” !

How does it work

At the same time I started to program all day long for my living, I also started to read a lot of programming books on my spare time. This allowed me to learn at night and practice at day, setting everything in my brain.

This might come as a surprise, but I never read a lot of books about the technologies I was using. I’d rather study fundamental programming books. These contain a lot of transportable knowledge, unlike in most books about a particular technology.

I believe this is a pretty good use of time since it made me a better programmer and also greatly reduced the time I need to master most new technologies. I can now easily relate them to some more general concept I learned before.

For example, I never read a book about UI. By the time I had to do some UI programming, I had absolutely no issue getting up to speed on the topic. I had already seen quite some UI code examples in other books, I knew that most UI frameworks are built from a set of Object Oriented patterns. Coming from a different perspective, I was even able to suggest improvements to the code that UI experts had not thought of.

That’s not to say that I never read books about a particular technology, sometimes, that’s just what you need to start something new. But when I do, I usually find them quite easy to read and digest. And I tend to skip things I intuitively understand and use them as cookbooks containing recipes for particular problems rather than end to end walk-through.

My books

The Pragmatic Programmer: From Journeyman to Master

As a young programmer this book made me understand that my job was not only about writing code, but about building maintainable systems. It provided me with tools to do so, 10 years later, I can still remember “The power of plain text”. This is also the book that made me have a first look into Ruby :).

Refactoring: Improving the Design of Existing Code

Here is the theory behind all automated IDE refactorings. Reading this book had a profound influence on my coding style. The examples made me understand the difference between readable and unreadable code … It’s also the foundation for any kind of incremental design and architecture. That’s the book that got me started with TDD.

Domain-Driven Design: Tackling Complexity in the Heart of Software

This book teaches good object oriented programming. Some say it is tough to read, but it’s definitely worth doing so. Among other things, it explains how to use functional programming concept in your object oriented project, by separating Value Objects and Entities for example.

The C Programming Language

With around 250 pages, it’s pretty difficult to find a programming book with a greater value/page ratio. This one will teach you all there is to learn about C, and help you understand everything that was built on top of C (and that’s quite a lot …)

Structure and Interpretation of Computer Programs

Compared to C, Lisp is at the other side of the language spectrum. Learning C and Lisp gives the ability to put nearly anything in contrast to these 2 languages. Lisp is dynamic, functional and meta. It can be morphed into nearly anything and SICP teaches how to do so. There’s a Lisp practice that is invaluable to any programmer : use your language to express your problem as simply as possible. SICP teaches that.

Programming Erlang: Software for a Concurrent World

Neither the C book nor SICP deals with distribution and concurrency. That’s what this book does. I had never programmed distributed systems before reading this book. After I read it, I learned how to code for distribution in a maintainable way. The lessons taught by Erlang are applicable in many languages.

Not the best books

I did not and will never read all programming books available. There might be newer books that treat the same subjects better, but these books are the ones that taught me the most about our craft. My point is that learning fundamentals and things far away from our daily technologies will teach us more.

Software Is Like Writing and Revising a Giant Book

With time, I discovered a way of explaining the subtleties of my developer job to my uninformed relatives and friends.

Sharing what your developer job is about with others can be very frustrating. Some people think you are “Just playing around with computers” as if it was not serious work. Others think that it is an extremely Cartesian and solitary activity with no place for communication or creativity. Trying to explain the diversity and richness of a developer’s work is often a disappointing experience.

The book metaphor

I explain to people that writing software is not unlike writing a huge book. A book long many millions of lines. I explain that the challenge is to maintain the whole story of the book coherent. I stress how difficult this is given that no one can take the time to read the full book, that the authors come and go, and that the book is under constant heavy revision.

Details of our work

The metaphor is quite valid and even holds about more subtle aspects of our work. Here is a summary of the last discussion I had about the book metaphor :

  • (Him) Do you have some ‘gatekeepers’ for different sections of the story to make sure that these parts remain coherent ?
  • (Me) That’s what we would call strong code ownership, this was the norm 20 years ago, but that the industry is moving to more collective code ownership, in order to decrease the bus factor.
  • (Him) What is the bus factor ?
  • (Me) The number of person who need to be hit by a bus to block your development progress
  • (Him) I see, that’s kind of funny. But then, does that mean that any developer can change any part of the code ? Isn’t that dangerous ?
  • (Me) Sure that would be difficult, that’s not really how we do it. We make a lot of efforts to split the big story in many smaller independent ones as much as possible. This way, teams specialize on different ‘chapters’ and work collectively within it.
  • (Him) I see
  • (Me) And if you need to change something in another ‘chapter’ you should ask the guys who know it better to help you.
  • (Him) That makes sense. And what happens if two developers want to modify the same part of the story at the same time
  • (Me) That can happen. People might even want to modify the story in conflicting ways ! We’ve got tools, processes and best practices to minimize this. If nothing is done, we’ll get what we call a ‘merge conflict’.
  • (Him) Ho … I wouldn’t have guessed, but it seems collaboration is really important in your work, isn’t it ?
  • (Me) Sure it is !

We are software writers

All this reminds me of DHH’s talk about writing software :

How I Fixed the Unknown Language Pygments Error in Octopress

Last time I tried to insert a code snippet in my Octopress blog, I was hurt by the following error :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
vagrant@ae4a04cebb73:/vagrant$ bundle exec rake generate
## Generating Site with Jekyll
unchanged sass/screen.scss
Configuration from /vagrant/_config.yml
Building site: source -> public
/vagrant/plugins/pygments_code.rb:27:in `rescue in pygments': Pygments can't parse unknown language: ruby. (RuntimeError)
  from /vagrant/plugins/pygments_code.rb:24:in `pygments'
  from /vagrant/plugins/pygments_code.rb:14:in `highlight'
  from /vagrant/plugins/backtick_code_block.rb:37:in `block in render_code_block'
  from /vagrant/plugins/backtick_code_block.rb:13:in `gsub'
  from /vagrant/plugins/backtick_code_block.rb:13:in `render_code_block'
  from /vagrant/plugins/octopress_filters.rb:12:in `pre_filter'
  from /vagrant/plugins/octopress_filters.rb:28:in `pre_render'
  from /vagrant/plugins/post_filters.rb:112:in `block in pre_render'
  from /vagrant/plugins/post_filters.rb:111:in `each'
  from /vagrant/plugins/post_filters.rb:111:in `pre_render'
  from /vagrant/plugins/post_filters.rb:166:in `do_layout'
  from /vagrant/vendor/bundle/gems/jekyll-0.12.1/lib/jekyll/post.rb:195:in `render'
  from /vagrant/vendor/bundle/gems/jekyll-0.12.1/lib/jekyll/site.rb:200:in `block in render'
  from /vagrant/vendor/bundle/gems/jekyll-0.12.1/lib/jekyll/site.rb:199:in `each'
  from /vagrant/vendor/bundle/gems/jekyll-0.12.1/lib/jekyll/site.rb:199:in `render'
  from /vagrant/vendor/bundle/gems/jekyll-0.12.1/lib/jekyll/site.rb:41:in `process'
  from /vagrant/vendor/bundle/gems/jekyll-0.12.1/bin/jekyll:264:in `<top (required)>'
  from /vagrant/vendor/bundle/bin/jekyll:22:in `load'
  from /vagrant/vendor/bundle/bin/jekyll:22:in `<main>'

I had been switching to Docker in Vagrant to host my Octopress installation, but that did not seem related …

Plan A : Upgrade Octopress

It turned out it was related to my migration to Vagrant and Docker.xs This kind of nasty error often comes from obsolete environment. Internet confirmed confirmed it :

  • Ubuntu now uses Python3 instead of Python2
  • Octopress2 uses an old version of Pygments
  • That version of Pygments requires Python2

I thought that I did not want to play this game against open source libs, so I set out to update. Octopress 3 has been released. It’s not yet documented yet, and there is no official upgrade guide, but some guys have done it :

I tried it … but I stopped before the end. It’s kind of working, but fundamental features like category archives required too much Jekylling for me at the time. And themes are still an issue … I mean, stock theme uses a clean and simple gem based update workflow, but most other themes rely on a tricky git clone-merge update workflow.

Plan B : Find a hosted blog engine for hackers

I found quite a few options :

  • Medium Looks cool, but there is no simple migration tool, and I’ve been burned by postero.us shutting down, I want to keep control on my content
  • Posthaven Having loved postero.us, this one seems cool, It’s just I’m not sure the guys are keeping the motivation to increase their feature list with their current business model
  • Ghost Looked great, but too expensive for me (19$ per month)
  • Codrspace This is a special blogging platform for coders, but it seems it has not been updated for a long time
  • LogDown This also is a special blogging platform for hackers. It seemed great and had everything I was looking for … I was ready to spend the 50$ per year for it as it could save me a lot of hassle. Unfortunately, I could not find a way to forward the categories of a post as Twitter hashtags as I’ve been doing with Octopress and Feedburner

In the end, I was rather disappointed by the alternatives, even though I was ready to pay for them.

Plan C : Fix the error in Octopress 2

Eventually, the fix was rather easy. People had fixed it by patching mentos.py file in the pygments.rb gem to run Python 2 instead of the stock Python. That’s not great because it means that I’d have to redo the patch every time I updated my gems, or rebuilt my workspace. Here is what I added to my Vagrantfile instead :

1
2
sudo apt-get -y install python2.7
sudo ln -sf /usr/bin/python2.7 /usr/bin/python

Here is the commit on my Github repo.

Conclusion

I’m sticking with Octopress2 for the moment. Maybe I’ll re-try to migrate to Octopress3 later on, when an official migration tool or guide is available. Meanwhile, I’m still dreaming of my perfect blogging platform :

  • Open source
  • Static HTML generation
  • Self or SAAS hosted
  • Great integration with social media and the web
  • Easy to maintain
  • Plugable themes

I’m looking for my next side project at the moment, that could be a useful one ! Anyone interested ?