In my article “iPad for the Enterprise (2020)”, I shared my workaround to enable offline (local) software development on the iPad. This involved the use of a Raspberry Pi 4, acting as a portable Linux server running Docker.

This article will explain how I achieved this setup, which is not something I would necessarily recommend, but was a fun little technology project.

First, why is this workaround even required? Unfortunately, due to Apple iPadOS restrictions, it is almost impossible to set up, customise and run a local development environment (e.g. Node.js, Ruby) on the iPad. Some applications do let you execute code locally (e.g. Pythonista), but these are often limited to prototyping, automation or simple code snippets.

The simplest workaround to this restriction would be to connect to a remote development environment, for example, AWS, Google Cloud, Azure, Heroku, etc. However, this would require a persistent Internet connection, which is not something I can always guarantee (especially when travelling). Therefore, I desire a local development environment that can be used offline, without an external power source.

When developing on the iPad, I use the following applications:

When combined, these applications enable a reasonable developer workflow (still limited by PC standards).

  1. Clone git repository from GitHub using Working Copy.
  2. Access the cloned repository via Apple Files.
  3. Modify the required files (Coda and/or iA Writer).
  4. Push the changes back to GitHub using Working Copy.
  5. Trigger the remote build process (if required) using Termius.

My frustration was step 5, the remote build process, which is what I mitigated through the use of a Raspberry Pi 4, acting as portable Linux server running Docker.

iPad Pro and Rspberry Pi 4

The Raspberry Pi 4 is well-positioned for this job, as it is small, light and cheap, but also very capable (Quad-Core CPU, 4GB RAM, SD-Card Reader). Thanks to the USB-C port, it is also possible to set up a physical network connection and power the device directly from the iPad. This is the “unique” selling point that removes the need for an external network (e.g. Wireless) and an external power source.

NOTE: I have only tested this setup using an iPad Pro (4th Generation - 2020), which comes equipped with a USB-C port. I suspect it would not be possible to replicate with an iPad equipped with a Lightning port.

Hardware Requirements

To get started, I purchased the following hardware.

Although not required in the long-term, I also purchased the following peripherals to help with the initial setup.

The total cost was approximately £60, which is not bad when you consider this is a one-time payment, compared against the ongoing compute/storage costs associated with running a Linux VM in the cloud.

The build process is very easy, simply insert the PCB into the case and load the Micro SD Card. For the initial setup, I connected a Power Supply, USB Mouse, USB Keyboard and HDMI monitor. Once the setup is complete, the peripherals can be removed.

Software Setup

I chose to install Raspbian Buster on the Raspberry Pi 4. The installation process is very simple, made even easier if you purchase a Micro SD Card from “The PiHut”, which comes preinstalled the NOOBS Raspberry Pi operating system.

Once complete, I executed the following eleven steps (leveraging Ben Hardill’s guide) to configure the Raspbian Pi to support SSH and network connectivity over USB-C. The entire process took approximately 15mins.

Add dtoverlay=dwc2 to the /boot/config.txt.

Add modules-load=dwc2 to the end of /boot/cmdline.txt.

Enable ssh by creating an empty file called ssh in /boot.

Add libcomposite to /etc/modules.

Add denyinterfaces usb0 to /etc/dhcpcd.conf.

Install dnsmasq with sudo apt-get install dnsmasq.

Create /etc/dnsmasq.d/usb with following content.

interface=usb0  
dhcp-range=10.10.0.2,10.10.0.6,255.255.255.248,1h  
dhcp-option=3  
leasefile-ro  


Create /etc/network/interfaces.d/usb0 with the following content.

auto usb0  
allow-hotplug usb0  
iface usb0 inet static  
  address 10.10.0.1  
  netmask 255.255.255.248  


Create /root/usb.sh with the following content.

#!/bin/bash  
cd /sys/kernel/config/usb_gadget/  
mkdir -p pi4  
cd pi4  
echo 0x1d6b > idVendor # Linux Foundation  
echo 0x0104 > idProduct # Multifunction Composite Gadget  
echo 0x0100 > bcdDevice # v1.0.0  
echo 0x0200 > bcdUSB # USB2  
echo 0xEF > bDeviceClass  
echo 0x02 > bDeviceSubClass  
echo 0x01 > bDeviceProtocol  
mkdir -p strings/0x409  
echo "fedcba9876543211" > strings/0x409/serialnumber  
echo "Ben Hardill" > strings/0x409/manufacturer  
echo "PI4 USB Device" > strings/0x409/product  
mkdir -p configs/c.1/strings/0x409  
echo "Config 1: ECM network" > configs/c.1/strings/0x409/configuration  
echo 250 > configs/c.1/MaxPower  
# Add functions here  
# see gadget configurations below  
# End functions  
mkdir -p functions/ecm.usb0  
HOST="00:dc:c8:f7:75:14" # "HostPC"  
SELF="00:dd:dc:eb:6d:a1" # "BadUSB"  
echo $HOST > functions/ecm.usb0/host_addr  
echo $SELF > functions/ecm.usb0/dev_addr  
ln -s functions/ecm.usb0 configs/c.1/  
udevadm settle -t 5 || :  
ls /sys/class/udc > UDC  
ifup usb0  
service dnsmasq restart  


Make /root/usb.sh executable with chmod +x /root/usb.sh.

Add sh /root/usb.sh to /etc/rc.local before exit 0.

Once complete, I shut down the Raspberry Pi and connected it via a USB-C to USB-C cable to the iPad Pro. The Rasberry Pi booted automatically and after a few minutes was accessible from the iPad via SSH using the previously configured IP Address (10.10.0.1).

At this point, the Raspberry Pi can be used like any other Linux based server, installing any required software, etc. To further expand the value, I also configured screen sharing and file sharing, which opens the door to other use cases outside of software development (e.g. file backup, screen sharing, media server, etc.)

There are multiple ways to leverage this setup to complete offline (local) software development on the iPad. I have been following the developer workflow outlined below.

  1. Clone git repository from GitHub using Working Copy.
  2. Access the cloned repository via Apple Files.
  3. Modify the required files (Coda and/or iA Writer).
  4. Copy the files to a working directory on the Raspberry Pi.
  5. Trigger the build process (if required) on the Raspberry Pi using Termius.
  6. Push the changes back to GitHub using Working Copy.

As stated in the introduction, I would not necessarily recommend this setup, as anyone looking to develop offline (local) would be better served by a budget Windows/Linux laptop. However, it does demonstrate what is possible if forced to use an iPad.