In the last days, i tinkered with different things: I installed Docker onto a Raspberry Pi 2, built several docker images [1][2] and got myself two new RTL-SDR-Sticks.

Today, I’ll bring all these Projects together and show you how to build a virtual aircraft radar (screenshot) – so fasten your seatbelt 😉

I’m ready – tell me what I need

You’ll need a Raspberry Pi 2 – yes, 2 ! – Of course, you can go with a Pi 1 – but to be honest, this thingy has just not enough ram and only one core so it’s not really suitable for docker. But hey, if you like the pain – go on 😉

! – Of course, you can go with a Pi 1 – but to be honest, this thingy has just not enough ram and only one core so it’s not really suitable for docker. But hey, if you like the pain – go on 😉 The Pi has to be prepared to run Docker – You can use the guide from my blog post if you need help

And of course you need a RTL-SDR Stick – so if you ever watched DVB-T on your Laptop, the chances are good that you already have a suitable Receiver. Some people over at Reddit compiled a nice list of sticks which are suitable for our little experiment. Oh, and an Antenna would be awesome 😉

List completed? All points checked? Great, let’s go on!

Got my stuff together – Can we build the container now?

Well, – no! We have to prepare our system first in order to use the RTL-SDR for our experiments. Unfortunately, the most operations systems have the behavior to load own drivers for specific hardware. This also happens for our RTL-SDR (DVB-T) Stick, To prevent this, we have to blacklist the system drivers.

So please connect to your raspberry via SSH and run the following command:

sudo echo -e "blacklist rtl2832

\ blacklist r820t

\ blacklist rtl2830

\ blacklist dvb_usb_rtl28xxu" > /etc/modprobe.d/rtlsdr-blacklist.conf 1 2 3 4 sudo echo - e "blacklist rtl2832

\ blacklist r820t

\ blacklist rtl2830

\ blacklist dvb_usb_rtl28xxu" > / etc / modprobe . d / rtlsdr - blacklist . conf

This will blacklist the default drivers and prevent the system to load these.

Now reboot your raspberry and reconnect via SSH.

Ok, now we should check if the raspberry is able to find the RTL-SDR Stick. So plug it in and run the command lsusb . You should get an reply like this

Bus 001 Device 004: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 1 2 3 4 Bus 001 Device 004 : ID 0bda : 2838 Realtek Semiconductor Corp . RTL2838 DVB - T Bus 001 Device 003 : ID 0424 : ec00 Standard Microsystems Corp . SMSC9512 / 9514 Fast Ethernet Adapter Bus 001 Device 002 : ID 0424 : 9514 Standard Microsystems Corp . Bus 001 Device 001 : ID 1d6b : 0002 Linux Foundation 2.0 root hub

The last three lines are internal USB devices of the Raspberry itself (yeah, the NIC is a USB device – weird eh? 😉 ), but the first entry in the list is the RTL-SDR Stick. It is possible that you see a different name, but it should always have the RTL in its name.

Ok, you see the stick in the listing? Cool, proceed!

I’m prepared – can we start now?

YES! Let’s go! We will now build two docker containers – the first container will be our “Baseimage” which contains the RTL-SDR library (which is utilised by all the other SDR tools) and the final DUMP1090 container which contains the app itself.

Part 1: the Baseimage

Connect again via SSH to your raspberry. Add a new directory called “Baseimage” and add a file called “Dockerimage”

mkdir ~/Baseimage cd ~/Baseimage touch Dockerfile 1 2 3 mkdir ~ / Baseimage cd ~ / Baseimage touch Dockerfile

Edit the “Dockerfile” (either using vi oder nano, your choice) and add the following content

# derive from debian wheezy image FROM resin/rpi-raspbian:wheezy MAINTAINER Frederik Granna RUN apt-get update && \ apt-get install -y libusb-1.0-0-dev pkg-config ca-certificates git-core cmake build-essential --no-install-recommends && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* WORKDIR /tmp RUN echo 'blacklist dvb_usb_rtl28xxu' > /etc/modprobe.d/raspi-blacklist.conf && \ git clone git://git.osmocom.org/rtl-sdr.git && \ mkdir rtl-sdr/build && \ cd rtl-sdr/build && \ cmake ../ -DINSTALL_UDEV_RULES=ON -DDETACH_KERNEL_DRIVER=ON && \ make && \ make install && \ ldconfig && \ rm -rf /tmp/rtl-sdr WORKDIR / 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # derive from debian wheezy image FROM resin / rpi - raspbian : wheezy MAINTAINER Frederik Granna RUN apt - get update && \ apt - get install - y libusb - 1.0 - 0 - dev pkg - config ca - certificates git - core cmake build - essential -- no - install - recommends && \ apt - get clean && \ rm - rf / var / lib / apt / lists / * WORKDIR / tmp RUN echo 'blacklist dvb_usb_rtl28xxu' > / etc / modprobe . d / raspi - blacklist . conf && \ git clone git : //git.osmocom.org/rtl-sdr.git && \ mkdir rtl - sdr / build && \ cd rtl - sdr / build && \ cmake . . / - DINSTALL_UDEV_RULES = ON - DDETACH_KERNEL_DRIVER = ON && \ make && \ make install && \ ldconfig && \ rm - rf / tmp / rtl - sdr WORKDIR /

Now you can build the Baseimage. Run docker build --rm -t rtlsdr-baseimage .

This will build a container called “rtlsdr-baseimage”. Docker will now download the Debian container (~150MB), install the compiler toolchain and build the RTL-SDR tools. Take a break and let the Pi do the work 😉

Oh, if you don’t want to build the image yourself, you can use my prebuild container – sysrun/rpi-rtl-sdr-base

Build done? Let’s check if the container is really there – execute a quick docker images | grep baseimage . That should give you the following output

rtlsdr-baseimage latest ad95b1a575c4 6 hours ago 283.8 MB 1 rtlsdr - baseimage latest ad95b1a575c4 6 hours ago 283.8 MB

Baseimage is there? Good – now go on

Part 2: the DUMP1090 Container

The next steps are basically the same as for the Baseimage. Add a directory and add a Dockerfile

mkdir ~/DUMP1090 cd ~/DUMP1090 touch Dockerfile 1 2 3 mkdir ~ / DUMP1090 cd ~ / DUMP1090 touch Dockerfile

Again edit the Dockerfile and add the content below

# derive from our baseimage FROM rtlsdr-baseimage MAINTAINER Frederik Granna WORKDIR /tmp RUN git clone git://github.com/antirez/dump1090.git && \ cd dump1090 && \ make WORKDIR /tmp/dump1090 ENTRYPOINT ["./dump1090"] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # derive from our baseimage FROM rtlsdr - baseimage MAINTAINER Frederik Granna WORKDIR / tmp RUN git clone git : //github.com/antirez/dump1090.git && \ cd dump1090 && \ make WORKDIR / tmp / dump1090 ENTRYPOINT [ "./dump1090" ]

And build the container via docker build --rm -t dump1090 . It’s now using our Baseimage, pulls the DUMP1090 sources from Github and compiles it. The whole process takes about 5-7 Minutes – so feel free to grab another coffee 🙂

Looks good? Awesome!

My Containers are done – Aircrafts please!

Yeah, easy! So let’s just start our Container and see how it works. We’re exposing port 8080 from our Container to our host system (-p 8080:8080) and starting dump1090 with the –interactive and –net option to enable the web interface. After the start you will be able to access the web interface by opening the url http://<yourpiip>:8080

Run docker run -it -p 8080:8080 dump1090 --interactive --net and let the magic happen.

HUH? WTF?! But you told me everything is in place?!

Yeah, everything is in place – but it’s not accessible by our container! Every container runs in an isolated context. That means that the container has no access to the host machine or to other containers by default. No access to the hard disks, keyboard, mouse, graphics… and, of course, no access to the usb devices…

Now there are two ways to fix this issue:

Using –privileged : this will run the Container in privileged mode. That means that the container has basically complete access to the underlying hardware of the host.

: this will run the Container in privileged mode. That means that the container has basically complete access to the underlying hardware of the host. Using –device=/dev/bus/usb: This is the better options as we’re not exposing the whole host to our container but only the usb devices.

So let’s run it again: docker run -it --device=/dev/bus/usb -p 8080:8080 dump1090 --interactive --net

Awesome! 🙂

Now fire up your browser and connect to the web interface. If you place the antenna at an unobstructed place near the window, it should start showing airplanes after some seconds.

There will be several follow-up blog posts on this topic – showing you how to receive Ships and Text-Messages from Airplanes, so stay tuned 8)

If you have questions, just drop me a line via twitter or in the comments 🙂