Chris Bednarski

Software Engineering: Make it work. Make it right. Make it fast.

Makefiles for Everyone

| Comments

A little over two years ago I got a MacBook from work. It was my first full-time unix machine, and while I’d played with Linux in the past I always used the package manager to get software. After getting frustrated with some of the Mac installers for php and mysql, one of my colleagues recommended compiling my own software from source.

One evening I went home and tried it and found it suprisingly easy. Before long I was downloading tarballs and git cloning and compiling code from source and beginning to understand what made Linux and open source so powerful. Any time I wanted to try something out, whether it was a new nosql database or the bleeding edge of PHP, it was a three-step process:

git clone

I don’t know C. I can pretend, sure. But not actually knowing how to write it doesn’t stop me from downloading C code, compiling it, and getting it running. Sometimes make blew up. So I googled the error messages, fixed a few bugs in the code I checked out, and recompiled the code. And it worked.

make became the great equalizer. But it wasn’t until later that I learned how to wield it myself.

The State of the Art in PHP

| Comments

I started learning PHP about 6 years ago, back in the heyday of Drupal, Wordpress, and phpbb (then in the 2.0 series). At that time the style of PHP was mostly procedural, with a typical app consisting of a few dozen PHP files, each of which contained a snaking nest of HTML, PHP, and SQL, used conditional includes for flow control, and was littered with global state.

Some of the wiser folks in the php community knew this was not the right way to do things. This highly-coupled code was hard to test, hard to change, and hard to reuse. The more elegant solutions to these problems took a few years to build, and were spurred by the addition of namespacing to PHP’s OOP model, the race to build MVC frameworks to compete with Ruby on Rails, and the emergence of git and github as the de-facto standards for open source.

Now on the verge of 2014, there’s a new breed of PHP applications and libraries. They represent the current State of the Art in PHP development. They’re built on the work of Fabien Potencier, Jordi Boggiano, Jonathan Wage, Sebastian Bergmann, and others.

If you want to be taken seriously as a PHP developer going forward, you will have to master these tools and practices. Change is hard. But the road ahead has been paved for you.

Running RethinkDB With Python C++ Protobuf Drivers on OSX

| Comments

I ran across RethinkDB a few days ago on O’Reilly Radar and decided to give it a shot, since I’m a big fan of MongoDB and Riak, and RethinkDB seems to take the best features of both (slick json data structures with easy administration) and mash them together.

I figured moving from Flask and Mongo to Flask and RethinkDB would be pretty easy, so I ran

brew install rethinkdb
pip install rethinkdb

and was off to the races. I was having a great time with the repl and RethinkDB’s awesome built-in admin interface and stuffing things into the DB left and right.

The totally awesome-looking rethinkdb admin interface

However, query performance in my python app kinda sucked. I wanted to fix that.

Veewee, for Creating VMs

| Comments

If you want to play around with virtualization software like Vagrant, Virtualbox, or VMWare Fusion, you’ll need to create a virtual machine image (henceforth referred to as a “VM”). The most common way to do this is to download an Ubuntu or CentOS ISO and install it through the virtualization GUI. However this is a time-consuming process, and if you discover that you made a mistake or you want to tweak the way you installed the operating system, you have to start the process over.

Veewee to the rescue! Veewee is a tool for automatically building VMs from ISOs, in a variety of formats. Veewee describes the exact process used to create the VM, so it’s easy to share with other people (team members or contributors for example). Also, you can check the procedure into version control and easily reproduce the original VM later, so you don’t need to keep different versions of a 700 megabyte VM sitting around on your hard drive.

Creating a CentOS 6.2 Base Box for Vagrant 1.1

| Comments

In order to use vagrant you need something called a base box. When you run vagrant up, vagrant makes a copy of your base box to use with your project.

Mitchell Hashimoto (vagrant’s author) provides an example base box based on Ubuntu, but I use CentOS at my workplace, so I’ve rolled my own base boxes. This walkthrough explains how to create a base box for Vagrant 1.1 using CentOS 6.2.

There are some automated tools you can use to do this, but I wanted to understand how all of the pieces fit together, because I feel less nervous about putting ssh keys and passwords into boxes that way, and I’m also better situated to troubleshoot when things go wrong (and they will).

However, once you’ve digested this article you might want to check out veewee and bento. At the very least, I’m sure you can improve on my process.

Installing Ruby the Correct Way

| Comments

Ruby is an extremely flexible, concise language which boasts a rampant proliferation of libraries and popular frameworks like rails. However, using your system’s default ruby to install gems is a quick path into dependency nightmares, as different gems fight to use different versions of the same library.

I’ll walk you through how to avoid this using rbenv, ruby-build, and bundler. At the conclusion, you’ll have a better understanding of where ruby lives on your system and you’ll also have a stable, flexible ruby installation that can grow with new development while simultaneously providing a bulletproof runtime environment for existing applications and tools.

Understanding Environment Variables and the Unix Path

| Comments

When I was new to Mac and Linux, environment variables and the Unix PATH were mysterious and confusing. Documentation for various tools would frequently make references to “add this to your path” or “set this environment variable” and I had no idea what they meant.

Fortunately, this seemingly-magic behavior is relatively transparent once you know where to look and understand some of the basic assumptions in Unix. By the time you’re done reading you’ll be on your way to mastering environment variables.

PATH and ENV In 5 Minutes or Less

When you type the name of a program cat or grep, your shell looks in all the directories specified in your PATH to try to find a matching program. PATH itself is an environment variable (other common ones include EDITOR and JAVA_HOME). Environment variables are global variables that live in your shell session, and help your shell fill in shortcuts or specify preferences.

You can dynamically set (or change) environment variables using export, or persistently set the values in your ~/.bash_profile or ~/.bashrc file. For example, we set EDITOR to vim, then use $EDITOR to invoke vim on our .bash_profile so we can persist some other environment variables:

$ export EDITOR=vim
$ $EDITOR ~/.bash_profile
export PATH=$PATH:/something/i/need/to/add

Environment variables are read from .bash_profile at the start of the shell session, so after you save the file you’ll need open a new terminal window before the changes will take effect.

If the extremely terse example above doesn’t satisfy you, keep reading. (Also, if you got stuck in vim, press ESC type :quit! and press ENTER to exit.)

Make It Work. Make It Right. Make It Fast.

I strive to follow a simple, disciplined and pragmatic approach to software engineering, which I’ve borrowed from Kent Beck and learned through blood and sweat: Make it work. Make it right. Make it fast.

People commonly mistake this for the adage “Good, cheap, or fast. Pick any two.”, which represents the three axes of control that a product owner has to tweak delivery timelines. These two ideas are only vaguely related (in the sense that if you don’t Make it Right, Work, and Fast, you’ll choose none from the preceeding selection). But the relation stops there.

Make it Work > Right > Fast is not a choice. It’s the order in which you do things.

Linux Login Using SSH Keys

| Comments

Using SSH keys to login to a server provides a convenient alternative to typing your password each time. SSH key-based authentication also allows scripts to run unattended without leaving your password in plain text. And it does your laundry. Well, alright, maybe not that last one.

Once you have ssh auth setup, you can use commands like ssh, scp, sftp, and rsync without having to enter a password. Handy!

SSH Keys in 5 Minutes or Less

If you’re lazy or adventurous and prefer to skip the details, you can follow these instructions:

Generate a key if you don’t have one already, pressing enter at all the prompts:

$ ssh-keygen

Set permissions on your private key and upload your public key to the server:

$ chmod 400 ~/.ssh/id_rsa*
$ scp ~/.ssh/ [email protected]:~/

Login to the remote server to create the .ssh folder, create the authorized keys file and set permissions:

$ ssh [email protected]
[email protected]'s password: <enter password>
$ mkdir ~/.ssh/
$ cat >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
$ rm
$ exit

Now when you login via ssh, it should use your ssh key instead of prompting you for a password.

SSH Keys in Slightly More than 5 Minutes

If you got stuck in the <5 minutes version, would like to know a bit more about what just happened (or what you’re about to do), or want to learn about some advanced use cases, read on.