-
Wrapping sidekiq into your unicorn process; might be useful for a prototype I have in mind.
Running scripts on startup with your Raspberry Pi
09 August 2013
I’m working on a hardware project at the moment that’s more complex than a basic microcontroller-build that I could have implemented with an Arduino. So I’ve been using a Raspberry Pi as the centre of the project, and writing my code in the high-level languages I’m most proficient in. (In this case, Ruby).
As the project nears completion, it’s really important that the device doesn’t manifest as a computer in any way: it’s just a physical object. To that end, I’d like all the software inside the miniature computer to run at startup without any manual intervention.
My Pi is running Raspbian – the Pi-focused version of Debian – so, fortunately, there’s a tool easily available to do that for us: upstart.
We’ll write an upstart configuration for our script, which will turn our script into an upstart service, which we can then start at login.
First, let’s install upstart:
sudo apt-get install upstart
This will issue some warnings, because – on my install – it was replacing the traditional init.d
setup. Don’t worry; everything will continue to work.
Once you’ve installed upstart, reboot your Pi, either from the command line or with a power-cycle.
Let’s now make an upstart config file. Here’s a very basic one:
Put this code into /etc/init/myscript.conf
. You should then be able to run the script by typing sudo start myscript
, and kill it with sudo stop myscript
. And, of course, you’ll discover it’ll start automatically on startup.
That’s a very simple example, with no dependencies. But that won’t work for the script I’d like to use. In this example, I’m running a Ruby script (using the Pi Piper library) that blinks an LED attached to GPIO Pin 17. That script needs to be run as root to get access to the GPIO pins, and it needs to reference the directory’s Gemfile. Upstart scripts are run as root, so that’s not an issue – but we need to set up the environment correctly. That’s not so hard:
As you can see, we just have to export the BUNDLE_GEMFILE
variable so that Bundler will know where the Gemfile is located.
Also, you’re going to have to make sure that all references to files in your code are done with absolute paths. That wasn’t a problem with the simple shell script example, but becomes an issue with more real-world type code – especially the program I’m ultimately running, which has various includes, dependencies, and data files to load. An obvious place you’ll run into this with Ruby is when setting up the $LOAD_PATH
.
Rather than starting my Ruby script
$LOAD_PATH << 'lib'
I had to do this:
$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) + '/lib'
And similarly, any other references to file loading will need to be absolute – and, ideally, derived using tricks like File.dirname(__FILE__)
rather than through hardcoded paths.
Anyhow: it took me a while to piece together, but now that I have, it felt worth writing down – because I’ve now got reasonable complex computation-backed hardware working in an entirely headless enclosure – and one that’s resilient to power-cycling.
-
Write the documentation for your tool to define the interface. Very nifty, and has polyglot parsers.
-
"a class factory and dsl for generating command line programs real quick" I like the look of this: solves lots of things I've always made clunky workarounds for.
-
Great set of pictures from Evo 2013; I really, really ought to go sometime.
-
"Marky Markov is an experiment in Markov Chain generation implemented in Ruby. It can be used both from the command-line and as a library within your code." It's very fast, and basically does all the work I've been doing on my projects by hand for me. But better.
-
"MiniProfiler allows you to see the speed of a request conveniently on the page. It also shows the SQL queries performed and allows you to profile a specific block of code." Ooh, been looking for the latest version of something like this for a while.
-
Because AA uses Devise, this is pretty straightforward, but still: I found this guide hepful.
-
via @aanand, and because I forgot to bookmark this when I read it the first time. Good, straightforward points.
-
A Redis-based queueing system for ruby; much more efficient than Resque, from the looks of things, and really nice deployment configuration (ie: someone's bothered to write cap recipes and similar). Definitely going into the toolbelt, I think.
-
"This gem provides a ruby interface to access Novation’s Launchpad programmatically. LEDs can be lighted and button presses can be responded to." Also later ported to Processing. Big "oooooooh" from here, because that'd be a lovely UI for so many things.
-
"The Bullet gem is designed to help you increase your application’s performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you’re using eager loading that isn’t necessary and when you should use counter cache."
-
"In the golden age of BASIC, it was easy for anyone to write a program. Now we offer you this exact same capability, but this time with the advanced features of the Nintendo DSi™ system… Many programs are included to ensure that you can fully enjoy using BASIC. The included programs were also written in BASIC, so you can add new features to them in order to enhance your games. You can also take the programs and data you create and convert them to QR codes that can be shared with friends who also have Petit Computer on their Nintendo DSi systems. (Programs included: 12 feature samples,5games, a character picture tool,a background screen creation tool,a graphics tool,and a picture-drawing tool.)" Interesting – especially the music-creation stuff, as Create Digital Music proved.