Using Docker to run Node.js on a Raspberry Pi
Experimenting with Docker on a Raspberry Pi
At Opensource.com, I get to learn about a lot of really interesting emerging technologies in my day to day work. But I don’t always get to explore them myself in depth. This past weekend, I set aside some time to do just that.
I’ve been a Raspberry Pi enthusiast for a few years now, not really using my Pi as a tool so much as a platform for learning about new things, whether those things are microelectronics or just trying out a new piece of software. More often than not, my experiment involves me wiping my SD card and starting over with a clean install of whatever distribution I'm interesting in playing around with. It works, and keeping a couple of extra SD cards around has helped, but in the end, I thought, there must be a better way.
Enter Docker. Docker is a tool for using Linux containers, which are an interesting topic in and of themselves. In a nutshell, you can think about them as either very light weight virtual machines that can run side-by-side on a host machine at near-native speed. In actuality, Docker containers are not virtual machines at all, but processes which run in (nearly) complete isolation from other processes on the host machine, and carry with them the complete bundle of utilities and libraries to help that process run; basically, a pared down operating system just for your selected application.
There is much more to be said about containers, and much of what you'll read about them pertains to their use in data centers, where they can help applications run side-by-side safely using fewer resources than dedicated virtual machines. Docker is also a great tool for developers, in the same way that tools like Vagrant, Puppet, Ansible, and others have helped with traditional virtual machines by letting you define your operating environment in code rather than manually editing tons of configuration files, and letting you version it, replicate it, and easily copy it to other machines.
As a Raspberry Pi tinkerer, this ease of replicating my environment had a lot of appeal, and working within the memory and processing constraints of a Raspberry Pi ruled out virtual machines as a means of doing it, so I wanted to see if I could get Docker up and running on my Raspberry Pi and then try it out.
Before we get started, let me offer a word of warning: This experiment is about playing around and learning. If you’re planning on running anything mission critical in Docker on an old model Raspberry Pi you happen to have sitting around… well, I won’t tell you it’s impossible, but be sure you do your research and fully understand what you’re doing.
The first challenge I came across, which will be obvious to anyone who has spent time with a Raspberry Pi, is that you're going to need some patience. My old Raspberry Pi model B runs at 700 MHz and has only 512 MB of memory. Once upon a time, this would have seemed insanely fast, but as I've gotten used to having a considerably faster desktop and laptop at my disposal, let's just say that building your containers may seem slow compared to what you're used to.
The second challenge is also fairly obvious, but something worth keeping in mind. While you probably run an x86 processor on your computer, your Raspberry Pi's processor uses an ARM chipset, so if you aren't going to be able to copy a container from your main computer to your Pi and have it work. You can, of course, write your Dockerfile (the text file defining what goes into a container) locally and copy it over, and you can always model your container's contents on a similar x86 container, but you're going to have to actually build it on the Pi unless you happen to have a faster ARM-based computer sitting around.
First up, I needed to get Docker installed. I followed a helpful tutorial for this, and recommend that you do too, because building it yourself could be a major challenge. The tutorial was based on the Raspberry Pi version of Arch Linux as the host OS, and I went with that to keep things simple. Since I'm used to using Fedora on the desktop, and hadn't played with my Pi in a while, it took a few minutes of searching around to remind myself how to use
ifconfig instead of
ip for setting up the network, and similarly, to use
pacman instead of
yum/dnf to get the system up-to-date, but these were minor hurdles.
Actually, installing Docker was easy, because it was in the default repository. After a
pacman -S docker to install and a
systemctl enable docker to start the daemon, I was up and running.
I found a base image based on Raspbian that seemed like a good place to start, then I created a simple Dockerfile to launch a basic web server based on a template I found, started a
docker build, and... watched it fail. Okay, maybe I overdid it with that first try, let me try something simpler.
Next, I pared it down, tried again, and it still failed, with a complaint about certificates. After a little time spent searching around, I realized that the certificate was probably failing because of a time issue. Sure enough, a quick check with the
date command told me that my Pi thought it was January 1 and several years ago. After using
timedatectl set-time to correct the issue, I tried once more, and it worked! My container was built and then successfully launched. Using
docker ps I could see that my container was working, and I could connect to it on the port I had specified.
Sure enough, I was not the first person to have this idea. I found a helpful Dockerfile on GitHub which set everything up for me. There were a couple of extra nodes I wanted to add, and after a little modification I had it up and running, too.
At this point, it's worth asking, so what? Couldn't I have just installed Node-RED directly onto my Pi? Sure, I could have. But now, when I want to "save" a project, I just need to save the Dockerfile, and I can run it on any Pi out there with a very easy installation. If I've got custom code written to import onto the Pi, maybe to talk to an Arduino or blink a series of lights, I can have that code pulled in at container launch. I can modify it easily, in code, and save that revision. I can try out a different Linux distribution for my Pi without wiping the card. I can share ideas with friends on the other side of the country that they can replicate quickly and easily without moving a large file.
And to me, that's a great tool to have in hand.
What do you think? Have you ever tried out Docker on the Raspberry Pi? Let us know in the comments below.