Merwyn Carrillos
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:

  1. Open the Termius App on my iPad
  2. Open a remote session into the Ubuntu jump box (configured in Termius)
  3. ssh from the jump box to the lab/dev host for my project
  4. Open or attach to a tmux session
  5. Navigate to my project root
  6. git pull to update any changes
  7. Code, run locally, unit test, etc.
  8. git commit and git 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:

High level workflow

Proxmox VMs

  1. The jump box, so I can use that as my "transportation hub" of sorts.
  2. 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:

  1. Open Termius
  2. Click the + in the top right corner
  3. Select SSH Host
  4. 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
  5. 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 then d.
  • 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.