Ditching my MacBook Pro on Business Trips for an iPad Pro+Raspberry Pi
By: Brian O'Connor
Tags: iPad, Linux, Bioinformatics, Science, Raspberry Pi

The Steps

Setup Raspberry Pi Connecting over USB-C Install Python, Jupyter notebooks, and other stuff Preparing an exFAT external drive (optional) Play!

Setting up the Raspberry Pi 🥧

To get started I bought my Raspberry Pi (version 4) on Amazon along with an microSD card, USB-C cable, and nice minimal aluminum enclosure. I also bought a USB-C hub so I could connect the Raspberry Pi to my iPad and charge at the same time. Setup was pretty easy, I just connected the microSD to my desktop computer, downloaded the Raspberry Pi Imager, and used it to choose the Raspberry Pi OS Lite image (since I didn’t need a full desktop).

After the card was setup, I went ahead and remounted it on my desktop. This gave me access to the /boot partition. I used the guide from Ben Hardill to setup networking over the USB-C port on the Raspberry Pi. I needed to do two key things to make this work: 1) create an empty file named “ssh” in the boot partition (this ensures that ssh is active on boot) and 2) when I put the card in the Raspberry Pi and booted for the first time, I made sure I plugged in ethernet so I’d have a way to reach the Raspberry Pi. By connecting the ethernet port to my network, I was able to ssh to the Raspberry Pi to complete the setup in Ben’s guide. That allowed me to continue the configuration using the raspi-config as well. For example, I setup WiFi so the Raspberry Pi will connect to my home wifi when available (I just have to plug it into any USB-C charger and I can use it without a direct connection to my iPad). I also changed the default password too, something that’s important since it’s now on my wifi network. I didn’t have a micro HDMI to HDMI cable available so being able to do all of this configuration over an SSH connection was great!

raspi-config

Connecting Over USB-C

At this point all the setup was done and I shutdown the Raspberry Pi (sudo poweroff) and unplugged it from ethernet. I then plugged in my USB-C hub to my iPad, connected it to power and the Raspberry Pi over it’s USB-C cable, and it promptly booted. You can see in Tech Craft’s video it shows up as a Ethernet device:

The USB-C ethernet config in the iPad’s System Settings

So my iPad has an IP address of 10.55.0.5 on this self-contained network. You can probably see where this is going, I can now ssh to Raspberry Pi using this network (if you’re connecing over wifi you’re going to need to figure out what IP address it gets from your home network, most routers let you see the devices on the network, look for “raspberry”). I use Blink, an absolutely fantastic SSH client for iOS. Totally worth the price, I can’t recommend it enough!

So the moment of truth, I open up Blink and type:

blink> ssh pi@10.55.0.1

And I’m in!

Installing Stuff

At this point I’ve got a working Raspberry Pi happily connected to my iPad! This is where Tech Craft and Ben’s instructions leave me and I pick up with my own configuration.

Mosh

The first thing I really love to install on a new Linux box/VM is Mosh. This nifty little tool works on top of SSH and ensures flakey connections are stable and can be automatically reconnected if they drop. It’s super robust, you can put your iPad to sleep and, hours later, resume the connection automatically to your remote VM/Linux host. Really nifty! Of course, it’s not really required here since I’m connecting over a USB-C cable. But still, why not! On my Raspberry Pi:

pi@raspberrypi:~ $ sudo apt install mosh

To test this, here’s how I connected via Mosh instead of ssh from my Blink session:

blink> mosh pi@10.55.0.1

Now I can put my iPad to sleep when I need to and when I switch back to Blink my connection is automatically restored.

Git, Python3, and Jupyter Notebooks

These days I don’t really code in large, shared projects. Really I do light prototyping, hacking, some shell and Python scripts, and Jupyter Notebooks mainly. So my development needs on my Rapsberry Pi are very modest.

I’ll start with Git, Python, some Python libraries, and some dev tools. I mosh’d to my Raspberry Pi and used apt to install:

pi@raspberrypi:~ $ sudo apt install git tmux python3-numpy python3-pandas python3-sklearn python3-matplotlib python3-seaborn python3-jupyter-core python3-pip python3-notebook jupyter

Conda

On my desktop I use Anaconda (and the bundled conda command) to setup distinct Python environments for every script I work with. This really helps compartmentalize things in case a given script has different requirements than another project. But it doesn’t exactly look well supported on the Raspberry Pi. Seems like there’s miniconda, which looks like it was last updated in 2015, and berryconda, which is no longer being updated. Still, I went ahead and installed miniconda, I found Data Addict’s guide extremely useful here.

pi@raspberrypi:~ $ wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-armv7l.sh pi@raspberrypi:~ $ sudo md5sum Miniconda3-latest-Linux-armv7l.sh # this should be a01cbe45755d576c2bb9833859cf9fd7 pi@raspberrypi:~ $ sudo /bin/bash Miniconda3-latest-Linux-armv7l.sh

The miniconda installer will ask where you want to install conda to, like Data Addict’s guide, I used /home/pi/miniconda3. I then made sure the bin directory was added to the pi user’s path and that the miniconda directory was owned by pi:

pi@raspberrypi:~ $ sudo chown -R pi:pi miniconda3

pi@raspberrypi:~ $ echo 'export PATH="/home/pi/miniconda3/bin:$PATH"' >> /home/pi/.bashrc

So this provides Python 3.4.3 but to get 3.5 and 3.6 I had to use berryconda (again, this makes me nervous since it’s no longer maintained):

pi@raspberrypi:~ $ conda config --add channels rpi

Anyway, I’m now able to create a self-contained conda environment and use that for Python script development:

pi@raspberrypi:~ $ conda create --name py366 python=3.6.6

And to activate the environment I do:

pi@raspberrypi:~ $ source activate py366

I can go crazy at this point and install whatever I want with pip, ensuring I’m not going to break another Python dependency for another tool or script.

Docker

No development environment would be complete without Docker. Again, I’m following the guide by Data Addict which uses the install script from Docker Inc.

pi@raspberrypi:~ $ curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh

pi@raspberrypi:~ $ sudo usermod -aG docker pi

I had to reboot after the usermod command above to get everything to work. I was then able to run the following command which showed everything was working correctly:

pi@raspberrypi:~ $ docker run hello-world

Preparing an exFAT external drive

I had a SanDisk USB-C hard drive and I wanted to format this as exFAT so I could use it on Linux, Windows, and MacOS. I needed to install the exFAT utils to get this to work, see this tutorial from PyMyLifeUp:

pi@raspberrypi:~ $ sudo apt-get install exfat-fuse exfat-utils

I then looked for the device the Raspberry Pi used for the hard drive when I plugged it into the USB port on the Pi.

pi@raspberrypi:~ $ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

sda 8:0 0 1.8T 0 disk

└─sda1 8:1 0 1.8T 0 part

mmcblk0 179:0 0 366.8G 0 disk

├─mmcblk0p1 179:1 0 256M 0 part /boot

└─mmcblk0p2 179:2 0 366.6G 0 part /

And from that info I was able to format the hard drive:

pi@raspberrypi:~ $ sudo mkfs.exfat /dev/sda1

mkexfatfs 1.3.0

Creating... done.

Flushing... done.

File system created successfully.

It should be automatically mounted when plugged in but, if it’s not, the tutorial above has instructions on mounting and also adding to the /etc/fstab file that allows you to easily mount in the future. Key command is ‘sudo blkid’ to get the drive’s ID which you can then put in an fstab line like this one (replace the UUID with what you got from blkid):

UUID="0E13-5B5D" /media/exfat exfat defaults,uid=1000,gid=1000,nofail,noauto 0 0

And then I just mounted using the command:

pi@raspberrypi:~ $ sudo mount /media/exfat

Play!

At this point, I can finally try out my little development environment. I’m going to spin up a Jupyter Notebook server and run a basic notebook that’s used in several tutorials online.

pi@raspberrypi:~ $ jupyter notebook --ip 10.55.0.1

This will print a URL to connect to, I then opened http://10.55.0.1:8888… using the URL that was printed and was able to use Jupyter Notebook to create a new notebook. I then used code snippets from an online tutorial to test out the various libraries I installed earlier. Unfortunately, I can’t seem to find the link to this tutorial but you can see below I was able to run through it and things like matplotlib and numpy worked as expected!