- Published on
Portable Programming: Navigating the Challenging Terrain of Coding on an iPad
TL;DR
I use an SSH app on my iPad over a VPN tunnel to connect to self-hosted Linux VMs to compile and localhost applications. Vscode.dev, Github Workspaces, and other cloud-based tools are potential alternatives but have their own limitations.
Introduction
Apple's current lineup of iPads delivers phenomenal performance; their flagship device, the iPad Pro, is powered by the same Apple Silicon CPUs that power MacBook Airs and Pros.
While the machines I compare them to run the macOS operating system, iPad tablets run on iPadOS, an operating system where apps can only be installed via Apple's App Store. This positions the iPad closer to a giant cellphone than a proper laptop running macOS.
Developing code on these machines is challenging. Essential development tools, integrated development environments, and development features - for the most part - are non-existent or incompatible on iPadOS. For example, running local servers, virtual machines, or even command-line tools like software package managers lack support for use on an iPad.
It's not easy but it's not impossible.
In this article, I'll cover how I developed this site from the discomfort of an Apple iPad.
Table of Contents
Motivation
When I travel, I tend to leave my laptop at home. If I'm out and about and out of my house, on a flight or on vacation, I'll most likely have the iPad with me.
However, there are those inevitable lulls where I find myself restless, seeking distraction. Solace is found in firing up a terminal to work on a personal project.
During a recent trip this past year, I found myself in that exact position. I had been wanting to start a blog - yet I was constrained by the restrictions of the Apple App Store.
This article will cover the development of this blog, which was built using my iPad.
For simplicity's sake I will forgo the VPN aspect which enables remote development (to the home lab), but this concept is not new and heavily documented online. I'll post some resources at the end if you'd like to read further.
My Workflow
In general, my workflow looks like this:
- Open the Termius App on my iPad
- Open a remote session into the Ubuntu jump box (configured in Termius)
ssh
from the jump box to the lab/dev host for my project- Open or attach to a
tmux
session - Navigate to my project root
git pull
to update any changes- Code, run locally, unit test, etc.
git commit
andgit push
up my changes to Github.
This article will cover the tools and setup I used to make this workflow possible.
Vercel Web Hosting
As I'm using Vercel to host my blog, a new version/build is triggered automatically when I push to the main
branch. This means I can see my changes live on the internet within a few minutes of pushing.
While not necessary, I think it's the easiest way right now to to the internet.
Tools and Setup
The goal is straightforward. Develop and host an application that I can launch on my home lab.
Core Components
Key players in this endeavor are:
- An iPad, obviously.
- Termius, an app downloadable from the app store, free edition.
- Proxmox, a free virtual machine hypervisor.
- A private Github repo, for version control.
Termius
Termius is an iPad app for connection to remote servers via SSH.
The free version allows only one host configuration. This will work for us as we get around it by setting a jump box as the single host configuration permitted.
Github
I've chosen Github due to its ease-of-use with Vercel, which I'm using to host my blog.
It solves the problem of version control, so you can backup, restore, and version your source code. In reality any system that fulfills that purpose works here.
Proxmox
Proxmox is a bare metal virtual machine (VM) hypervisor. I think of it as the modern open source VMWare ESXi.
I run Proxmox on a an old repurposed desktop PC, connected to a network switch over ethernet.
I have at any time at least two VM's running on this host. One VM serves as a dedicated jump box and another as a lab machine which I use for development.
The lab machines are built using configuration management with Salt. While not necessary or required, it's a good practice that helps in case I need to rebuild - which I often do.
Why not Docker or Kubernetes? Absolutely. There's a solid argument here for containerization. However, the problem I'm solving for here is meant to highlight the lateral movement across a network remotely.
In a later article, I will most definitely dive deep into containerization and orchestration through technologies like docker, docker-compose, and kubernetes.
Web Hosting
- A Vercel account
This area is optional, but I recommend it. With Vercel, you'll be able to host an application directly off of a Github repository.
However, hosting locally allows failing faster as you can run commands such as npm run build
depending on the web framework/code being built.
In this article, we will continue with deploying locally.
Theory Wrap-up
I've outlined above the key tools and technologies used in this project. With these tools, I can develop, test, and deploy my blog application remotely.
While the setup is not ideal, it's a good starting point for a more complex setup in the future.
The next section will cover the development and configuration of the project.
Configuration
Here's what my systems architecture, at a high level, looks like:
Proxmox VMs
- The jump box, so I can use that as my "transportation hub" of sorts.
- The lab VM which I'll use to install all my languages, tools, and runtime environments.
Jump box
The jump box is a simple Ubuntu Server LTS VM with SSH enabled.
We need to configure this jump box in Termius.
We can do this by:
- Open Termius
- Click the
+
in the top right corner - Select
SSH Host
- Fill in the details:
- Hostname: The IP address of the jump box
- Port: 22
- Username: Your username
- Password: Your password
- Name: A name for the host
- Click
Save
Now, using the Termius app, we can connect to the jump box by simply clicking on the host we just created. This will open a terminal session to the jump box where we can then ssh
into the lab VM.
Lab VM
Again, we can use Ubuntu Server LTS.
We need to make sure we have the right tools installed.
sudo apt update && sudo apt install tmux vim -y
The above command will update the package list and install tmux
and vim
.
The following sections contain configuration steps for each of these tools.
Vim
I use Vim as my text editor of choice. It's lightweight and its source application, vi
is available on most systems. The command above ensures the vim
(a.k.a vi improved) package is installed.
Tmux
tmux
is a terminal multiplexer. It allows you to run multiple terminal sessions in a single terminal window and is critical for keeping a session alive even if you disconnect from the server.
In practice, what this means is that you can run a tmux
session, run your shell in the session, and then disconnect from the server. When you reconnect, you can reattach to the tmux
session and your shell will be right where you left it.
It's the perfect tool for what we are going to be doing, as there is a change we will be connecting and disconnecting from the server frequently.
All you have to do to start a tmux
session is run tmux
in the terminal.
tmux
- To detach from the session, press
Ctrl+b
and thend
. - To reattach to the session, run
tmux attach
.
SSH Key for Github
If you're planning on keeping your code in a private repository, you'll need to authenticate with Github to retrieve, pull, and push your codebase.
I've personally discontinued the use of username/password logins to my repositories - and I recommend you do too.
The alternative connection method I use is via SSH keys.
Run the below to set yours up:
cd ~
ssh-keygen
You'll be prompted to accept a few prompts, validating the location of the key pair to be created. If you've created the key with no extra options, run the following to retrieve the public key, else replace the path with what the public key was named:
cat ~/.ssh/id_ed25519.pub
You'll add this to your Github account under your Settings > SSH and GPG Keys. Official documentation on this process can be found here.
Now we need to install our web application's relevant runtime.
Node
To install Node, we'll want to install nvm
, the Node Version Manager.
As of time of writing, Node v22.13.1 is the latest long term support (LTS) release. We like LTS because it's stable and has a longer support cycle than say, even v23 of node.
It's codename is Jod
and can be installed if you run these in order:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install --lts:Jod
Now, verify with the following commands:
node --version
npm --version
An Example App
The above is really the point of the article, but I can't just leave you without a practical example now can I?
I chose to use a Next.js starter blog template to get started on this blog. It's a simple, clean, and easy to use template that I have customized to my liking.
To get started with your own, you can clone the repository from Github:
git clone https://github.com/timlrx/tailwind-nextjs-starter-blog.git
Now enter The directory and install the dependencies
cd tailwind-nextjs-starter-blog
npm install
Finally, run the development server
npm run dev
As this is running on a VM within your local network, you can access the application by navigating to http://<IP_OF_LAB_VM>:3000
Lessons Learned
I really do like hosting my own application in a local network. Running the webapp on my Ubuntu lab VM, sitting in my local network, means I can simply go to 192.168.100.101:3000
to reach my application from any device in the house.
Though the drawbacks are plentiful. First and foremost, the requirement of having a second machine which hosts my deployments.
If I had only the iPad, I would not be able to perform the above. I would need to look into Github Workspaces, or possibly just a combination of vscode.dev and Vercel.
Vim. I see this less of a drawback than others mentioned, however I feel it needs to be said. Not everyone is comfortable outside of something like VSCode, PyCharm, or Eclipse. Vim means you need to learn vim motions, setup an LSP (for code completion, definitions, etc.), and operate without a mouse.
Conclusion
To put it simply, coding on an iPad is not ideal.
The iPad is not a development machine, at least not for code.
Tools exist which help you get there - but in the end, you're not really coding on your iPad. The iPad itself is just acting as another TTY terminal which you use to access an actual development environment.
While I chose a bare-metal jump box solution as I found it easiest at the time, opportunities exist for other tools to take its place.
Online Github Workspaces, AWS, and other cloud-based runtime environments are awesome too, and in many cases a bit simpler than what I've outlined above.