There is a lot to love about the current iPad Pro - super-fast CPU, beautiful screen, a keyboard that doesn’t need to be charged separately, long battery life and wide selection of apps. Using iPad Pro as an everyday computing device is very tempting, but can it replace substitute your laptop if you are doing some serious coding? For me “serious” coding involves writing containerized microservices and APIs, in a variety of programming languages. To make the experience pleasant I also need coding to not happen in a browser and/or require high-bandwidth/low latency internet connection (not a reality on the go, yet).

I have been contemplating to find an answer to this question, for a while and have been itching to test-drive a user-friendly solution. I am sure I am not alone, either. If you travel for work a lot, you will understand how tempting it is to just grab your iPad and leave a bulky laptop behind. At this point, most things you need, for work or leisure, can be done on an iPad (especially if your work uses Google Suite for office productivity), but what if you need to write some non-trivial code and have nothing but an iPad with you?

Things for me got real on a recent vacation. Determined to take a break, I consciously left a laptop behind and only grabbed iPad with me. And that’s when temptation descended… Having found a tiny bug in one of my open-source projects – an event store implemented in Go I suddenly felt huge urge to figure the setup out. So instead of enjoying a cheesy crime novel on a Kindle, the pool-side time was re-purposed for turning an iPad into a coding beast machine. What follows is a summary of findings. Spoiler alert: it worked and the result is surprisingly workable/awesome/pleasant.

Necessary Ingredients

  • An iPad Pro with the Apple keyboard. An LTE version is highly recommended so you are not at the mercy of finding a nearby Wi-Fi. Mobile internet connectivity with its instability and low bandwidth is still very usable for the setup, since it does not use much bandwidth and is resilient to intermittent connectivity.
  • An Ubuntu server you can SSH into. This is where your code will actually execute. After all iPad is still a mobile device with extremely sand-boxed access so yes - you do need this, if you need full flexibility and are doing something advanced. You can use any server, but I personally grabbed a $10/mo DigitalOcean droplet (2 GB RAM / 1 CPU, 50 GB SSD disk 2 TB transfer)
  • Termius or Blink Shell as a shell client. Both of them support Mosh protocol, but Termius also has non-Mosh keep-alive implementation. Overall both are great. I personally like Termius slightly better, especially because I like its tabbed interface for multiple connections. Blink will set you back $20 as one time cost, unless you can figure-out how to install the open-source version on an iPad, yourself. Termius uses in-app purchase so you can try it 14 days for free. After that it becomes pretty expensive with a monthly (or annual) subscription. Please note that for ESC key in Termius you can use “CMD+`” combination. Blink Shell allows you to re-purpose Caps Lock as ESC, which is also pretty cool.
  • Textastic is a fantastic code editor, at a surprisingly low $10 that supports SFTP and works very nicely with major programming languages, including Go, Python and JavaScript (my favorites). If you are used to VS Code chances are you will like Textastic. This editor is cleverly resilient to poor network connections as it lets you easily download your entire project, edit it locally and then upload necessary files or folders when you are ready. Overall a very reasonable experience.
  • Since most of the time I write some APIs or microservices using HTTP, a mobile replacement for Postman was a must-have for me and I found a decent one in HttpBot

Server Setup

iPad setup just needs you purchasing the aforementioned apps, so most of the setup is related to setting up your server (I use latest Ubuntu) and connecting the iPad apps to the server properly.

First I installed Mosh on the server. Mosh is an SSH substitute that allows better resilience with intermittent connectivity. Both Termius and Blink Shell support it.

Installing Mosh

> sudo apt-get install python-software-properties
> sudo add-apt-repository ppa:keithw/mosh
> sudo apt-get update
> sudo apt-get install mosh

You may also need to allow the required UDP ports through a firewall:

# For IP Tables:
> sudo iptables -I INPUT 1 -p udp --dport 60000:61000 -j ACCEPT
# Or for UFW:
sudo ufw allow 60000:61000/udp

Please note: while Mosh is generally great, there seems to be some bug with terminal output scroll-back. If you are tailing a large log and need to scroll up (see past messages), I’ve certainly had some issues doing it over a Mosh connection both with Termius and Blink, where doing exact same over an SSH connection was no problem. Please keep that in mind if you run into similar issues.

Installing Docker Toolkit

All code I write these days is containerized. To avoid workspace and environment versioning problems, my code is containerized in local dev environments as well, not just on the servers. Over years I have created Node and Go blueprints to make such development easy. Long story short, the first thing we need to do on our server is get Docker and Docker Compose installed:

> sudo apt-get install build-essential
> sudo apt-get remove docker docker-ce-cli docker-engine docker.io containerd runc
> curl -sSL https://get.docker.com/ | sh
> which docker
> sudo docker-compose ps

By default, on Linux, you can only run docker commands via sudo, which is obviously not great. Per Docker’s own documentation you need to perform additional steps to fix this:

The Docker daemon binds to a Unix socket instead of a TCP port. By default that Unix socket is owned by the user root and other users can only access it using sudo. The Docker daemon always runs as the root user.

If you don’t want to preface the docker command with sudo, create a Unix group called docker and add users to it.

Meaning:

> sudo groupadd docker
> sudo usermod -aG docker <username>

ATTENTION: replace <username> with your desired non-root username (e.g. “irakli” in my case).

Installing Python 3 and AWS CLI

A lot of modern toolkit requires Python 3 installation. Linux distributions universally come pre-installed with Python 2. You cannot just upgrade (shouldn’t) since system tooling depends on Python 2, so there’s a bit of work installing Python 3 on Linux to get things like AWS CLI going.

> sudo apt update
> sudo apt-get install python3
> python3 --version
> sudo apt install software-properties-common
> sudo apt-get install python3-pip

Once you have Python 3 you can install AWS CLI as easily as:

sudo -H pip3 install awscli

While not strictly required, any Python installation would be incomplete and amateur hour :) if it didn’t include virtualenv and “workon” utilities, so here you are:

> sudo -H pip3 install --upgrade pip setuptools wheel
> sudo -H pip3 install virtualenv
> sudo -H pip3 install virtualenvwrapper
> mkdir ~/.virtualenvs

and insert the following lines in your ~/.bashrc:

if [ -f "/usr/local/bin/virtualenvwrapper.sh" ]; then
  export WORKON_HOME=~/.virtualenvs
  export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
  export VIRTUALENVWRAPPER_VIRRTUALENV=/usr/local/bin/virtualenv

  source /usr/local/bin/virtualenvwrapper.sh
fi

Once you run source ~/.bashrc you can create new Python virtual environments simply by executing something like mkvirtualenv p3-sweetproject and you can switch to pre-existing python environments with something like workon p3-sweetproject where “p3-sweetproject” is the name of your python virtual environment. Substitute with whatever name you want to use.

One last thing: Jekyll

If you area Jekyll / Github Pages user, you may appreciate it. To write this blog post on the same iPad and be able to preview my Jekyll-powered blog in comfort, I also added Jekyll to the same Ubuntu server. Here’s what it took:

> sudo apt-get install ruby-full build-essential zlib1g-dev
> echo '# Install Ruby Gems to ~/gems' >> ~/.bash_profile
> echo 'export GEM_HOME="$HOME/gems"' >> ~/.bash_profile
> echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bash_profile
> source ~/.bash_profile
> gem install jekyll bundler

Personal touch.

As a final touch, I also installed my dotfiles on the Ubuntu. You may have your own, or you may be curious enough to see what I use, either way, if you followed along you hopefully have a very capable developer setup on your iPad now (with a bit of help fro Ubuntu and possibly Digital Ocean).

Final Thoughts

Overall, I really enjoyed the experience. The only thing that really bugs me is that Apple didn’t make iPad Pro’s keyboard illuminated so in dark environments you can hardly see what you are typing, especially if you use dark mode applications. But other than that I would say the setup allows you to do a lot. In some ways it is even more capable than installing Docker for Mac on your laptop. Docker for Mac immediately makes your Mac laptop run very hot, reduces battery life from 5-6 hours to less than 2 and causes agitation. In contrast, iPad is just fine (well, thanks to the Ubuntu server but still).

Granted, on iPad you don’t really get multi-window experience, but while I would very much like Apple to fix it in general, it wasn’t a huge issue for code writing.

Enjoy your new power developer machine, hope this write-up was useful.