Coding From My iPhone: How Tailscale, tmux, and Terminus Became My Mobile Dev Setup
February 09, 2026
I was sitting in a waiting room last month when I got a Slack notification about a broken deployment. My laptop was at home, and the fix was a two-line config change that I could have done in thirty seconds from a terminal. Instead, I spent forty-five minutes stressing about it until I got back to my desk. That was the moment I decided I needed a way to reach my home server from anywhere – even from my phone.
What started as a “just in case” experiment turned into a workflow I actually use regularly. The combination of Tailscale for networking, Terminus as an SSH client on my iPhone, and tmux for persistent sessions gave me a surprisingly capable remote coding setup that fits in my pocket.
The Problem: Reaching Your Home Server From Anywhere
The traditional way to SSH into a home machine from the outside world is painful. You need to configure port forwarding on your router, deal with your ISP’s dynamic IP address changing on you, set up dynamic DNS, and then worry about exposing port 22 directly to the internet. I’ve done this before, and it’s a maintenance headache that introduces real security concerns.
What I wanted was simple: open an app on my iPhone, tap a connection, and land on my home server’s terminal as if I were sitting right in front of it. No fiddling with IP addresses, no VPN clients that require a dedicated server, no firewall rules to babysit.
Tailscale: The Networking Layer That Just Works
Tailscale is what finally made this whole setup viable. It creates a mesh VPN using WireGuard under the hood, but the experience is nothing like traditional VPNs. There’s no central server to maintain, no certificates to rotate, and no port forwarding required. You install it on your devices, log in, and they can talk to each other over encrypted connections regardless of what network they’re on.
Setting Up Tailscale on the Home Server
Installation on my Ubuntu server took about sixty seconds:
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
# Start and authenticate
sudo tailscale up
# Verify it's connected
tailscale status
After authenticating through the browser, my server was assigned a stable Tailscale IP address (something like 100.x.y.z) that would never change regardless of what my ISP did with my public IP.
Setting Up Tailscale on iPhone
On the iPhone side, it was even simpler – download Tailscale from the App Store, sign in with the same account, and toggle it on. That’s it. My iPhone and home server were now on the same virtual network.
The key insight with Tailscale is that it uses NAT traversal to establish direct peer-to-peer connections between your devices. Traffic doesn’t route through Tailscale’s servers in most cases – it finds the shortest path between your devices, even through firewalls and NAT. This means latency stays low, which matters when you’re typing into a terminal.
# On the server, verify your iPhone shows up
tailscale status
# You'll see something like:
# 100.64.0.1 home-server linux -
# 100.64.0.2 johns-iphone iOS idle
Why Not Just Use a Traditional VPN?
I ran OpenVPN on a VPS for years. It worked, but it required maintaining a server, keeping certificates current, debugging connection issues when clients updated, and routing all traffic through a single point. Tailscale eliminated every one of those pain points. The mesh topology means my iPhone connects directly to my home server – there’s no intermediate hop adding latency to every keystroke.
Single Point of Failure] VPN --> Server1[Home Server] style VPN fill:#ff9999 end subgraph "Tailscale Mesh VPN" iPhone2[iPhone] -->|Direct WireGuard tunnel
NAT traversal| Server2[Home Server] iPhone2 -.->|Coordination only| Coord[Tailscale
Coordination Server] Server2 -.->|Coordination only| Coord style Coord fill:#99ff99 end
Terminus: The SSH Client That Makes iPhone Coding Tolerable
With the network layer solved, I needed an SSH client on iOS that wouldn’t make me want to throw my phone. I tried several options before landing on Terminus, and the difference was immediate.
Why Terminus Over Other iOS SSH Clients
The thing that sets Terminus apart is its keyboard. Coding over SSH means you need easy access to characters like |, ~, /, {, }, [, ], and Ctrl combinations – characters that are buried deep in the standard iOS keyboard. Terminus adds a customizable extra row above the keyboard with all the special characters and modifier keys you actually need in a terminal session.
The key bindings that matter most:
- Ctrl key readily accessible for tmux prefix and terminal shortcuts
- Tab key for command completion
- Arrow keys for navigating command history and moving through text
- Pipe, tilde, brackets all on the extra row without hunting through iOS keyboard pages
- Esc key for vim users (which becomes essential inside tmux)
Configuring the Connection
Setting up the SSH connection to use my Tailscale network was straightforward:
- Open Terminus and create a new host
- Set the hostname to my server’s Tailscale IP (
100.64.0.x) - Configure SSH key authentication (paste your private key or generate one in-app)
- Set the username and port
I strongly recommend using SSH key authentication instead of passwords. You can generate a key pair directly in Terminus and add the public key to your server’s ~/.ssh/authorized_keys:
# On your server, add the public key from Terminus
echo "ssh-ed25519 AAAA... terminus-iphone" >> ~/.ssh/authorized_keys
The Small Screen Reality
Coding on a 6.7-inch screen isn’t going to replace a proper development setup. But for quick fixes, reviewing logs, restarting services, running deployments, or making targeted config changes, it works far better than you’d expect. Terminus supports pinch-to-zoom for adjusting font size, and landscape mode gives you enough horizontal space for most terminal work.
tmux: The Session Layer That Ties It All Together
Here’s where the setup goes from “I can SSH from my phone” to “I have a persistent development environment I can access from anywhere.” tmux is the critical piece that makes mobile coding practical rather than frustrating.
Why tmux Is Non-Negotiable
Without tmux, every time your SSH connection drops – and on mobile networks, it will drop – you lose everything. Your running processes die, your command history vanishes, and your carefully arranged terminal layout disappears. With tmux, your session lives on the server independent of your SSH connection. You reconnect and pick up exactly where you left off.
This is especially important on an iPhone where:
- You switch to another app and iOS may kill the SSH connection
- You move between WiFi and cellular and the connection resets
- You lock your phone and the background connection times out
- You walk through a dead zone and lose signal for thirty seconds
With tmux, none of these interruptions matter. Your session is always waiting for you.
My tmux Configuration for Mobile
I tuned my tmux config specifically for the mobile workflow. The defaults assume you have a full keyboard, so a few adjustments make life much easier when working from Terminus:
# ~/.tmux.conf
# Use Ctrl-a as prefix instead of Ctrl-b (easier to reach on mobile)
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# Enable mouse support (critical for touch-based terminal use)
set -g mouse on
# Start window numbering at 1 (easier to reach than 0)
set -g base-index 1
setw -g pane-base-index 1
# Increase scrollback buffer
set -g history-limit 50000
# Reduce escape time (prevents lag on mobile connections)
set -sg escape-time 10
# Status bar with useful info
set -g status-right '#[fg=green]#H #[fg=white]%H:%M'
set -g status-left '#[fg=yellow][#S] '
# Easy pane splitting with memorable keys
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# Reload config without restarting
bind r source-file ~/.tmux.conf \; display "Config reloaded"
Essential tmux Commands for Mobile
These are the commands I use constantly when coding from my phone:
# Start a new named session
tmux new -s dev
# Detach from session (or just close Terminus -- same effect)
# Prefix + d (Ctrl-a, then d)
# List existing sessions
tmux ls
# Reattach to a session
tmux attach -t dev
# Create a new window
# Prefix + c
# Split pane horizontally
# Prefix + |
# Split pane vertically
# Prefix + -
# Switch between panes
# Prefix + arrow keys (or tap with mouse mode enabled)
# Resize panes
# Prefix + Alt + arrow keys
Practical Pane Layout for iPhone
On a small screen, I keep my tmux layouts simple. Trying to run four panes on an iPhone is an exercise in frustration. My go-to layouts:
Quick fix mode – single pane, full screen:
┌──────────────────────┐
│ │
│ editor / shell │
│ │
└──────────────────────┘
Monitoring mode – horizontal split with editor on top, logs on bottom:
┌──────────────────────┐
│ editor / shell │
├──────────────────────┤
│ logs / output │
└──────────────────────┘
I avoid vertical splits on the phone entirely. The horizontal space is too precious to divide.
The Complete Workflow
Here’s what the end-to-end experience looks like when I need to code from my iPhone:
WireGuard Tunnel] B -->|Direct Connection| C[Home Server] C --> D[tmux Session] D --> E[Persistent
Terminal Environment] subgraph "iPhone" A1[Terminus App] --> A2[SSH over
Tailscale IP] end subgraph "Home Server" D1[Window 1:
Code Editor] D2[Window 2:
Git / Build] D3[Window 3:
Logs / Monitor] end A1 --> A2 A2 --> B E --> D1 E --> D2 E --> D3
Step by step:
- Enable Tailscale on iPhone (usually already running in the background)
- Open Terminus and tap on my saved home server connection
- Reattach to tmux with
tmux attach -t dev– my session is exactly where I left it - Make the change – edit files, run commands, check logs
- Detach or just close Terminus – the tmux session persists on the server
- Later, from my laptop – SSH in and
tmux attach -t devto continue where I left off
The beauty of this setup is that the tmux session doesn’t care what device connects to it. I can start work on my laptop, continue from my iPhone during lunch, and finish back on my laptop. The session is the constant; the client is interchangeable.
Practical Tips From Daily Use
Keep Tailscale’s MagicDNS enabled. Instead of remembering your server’s Tailscale IP, you can SSH to home-server by name. Terminus supports hostnames, so your connection config becomes cleaner and survives IP changes within the Tailscale network.
Use mosh if latency is a problem. On particularly unreliable mobile connections, mosh (mobile shell) can sit between Terminus and tmux to handle packet loss and latency more gracefully than raw SSH. Terminus supports mosh connections natively.
Set up SSH keep-alives. Add these to your server’s SSH config to prevent idle connections from dropping prematurely:
# /etc/ssh/sshd_config
ClientAliveInterval 60
ClientAliveCountMax 3
Name your tmux sessions descriptively. When you’re fumbling on a phone screen, tmux attach -t blog-fix is much easier to type correctly than trying to remember session numbers.
Enable Tailscale SSH for an even simpler setup. Tailscale has a built-in SSH server feature that uses your Tailscale identity for authentication, eliminating the need to manage SSH keys entirely:
# On your server
tailscale up --ssh
This lets Tailscale handle SSH authentication using your SSO identity rather than traditional SSH keys.
Use .bashrc aliases for common tmux operations. On the server, I have a few shortcuts that save keystrokes on a phone keyboard:
# ~/.bashrc
alias ta='tmux attach -t'
alias tl='tmux ls'
alias tn='tmux new -s'
Now reattaching is just ta dev instead of the full command.
Key Learnings
- Tailscale eliminates the networking complexity – No port forwarding, no dynamic DNS, no exposed ports. Install it, authenticate, and your devices can talk to each other securely from anywhere
- Terminus is the best iOS SSH experience – The extra keyboard row with special characters and modifier keys makes the difference between usable and miserable terminal interaction on a phone
- tmux is non-negotiable for mobile SSH – Mobile connections are inherently unreliable, and persistent sessions mean you never lose work when a connection drops
- Mouse mode in tmux is essential for touch devices – Enabling
set -g mouse onlets you tap to switch panes and scroll through output, which is far easier than keyboard shortcuts on a phone screen - Keep mobile tmux layouts simple – One or two horizontal panes maximum. Vertical splits are unreadable on a phone. Save complex layouts for the laptop
- The session-as-constant pattern is powerful – Your tmux session becomes the persistent workspace and your devices become interchangeable windows into it. Start on a laptop, continue on a phone, finish on a tablet
- This setup is for targeted work, not marathon coding – Don’t try to build features from your phone. Use it for quick fixes, log review, deployments, config changes, and emergencies. It excels at removing the “I can’t do anything until I get to my laptop” bottleneck
The whole setup took me about twenty minutes to configure, and it’s been running reliably for weeks. The real value isn’t that I code from my iPhone every day – it’s that I always can when I need to. That peace of mind alone was worth the twenty-minute investment.