Bastion Server Setup

The bastion server is where the real work happens. It runs Claude Code and provides the compute power that makes the cyberdeck genuinely useful rather than just a novelty. This page covers server setup, Claude Code installation, tmux configuration, and secure remote access.

Server Requirements

Claude Code itself doesn't need much local compute — the AI runs on Anthropic's servers. Your bastion mainly needs to handle the terminal session, file operations, and any development tools you run locally.

Minimum Specifications

CPU Any modern x86_64 or ARM64
RAM 2GB minimum, 4GB+ recommended
Storage 20GB+ for OS, tools, and projects
OS Linux (Ubuntu 22.04+, Debian 12+, or similar)
Network Stable internet connection, SSH access

Server Options

☁️ VPS / Cloud
£3-10/month

Hetzner, Linode, DigitalOcean, Vultr. Always on, accessible from anywhere. The practical choice for most people.

🏠 Home Server
Existing hardware

Raspberry Pi 4/5, old laptop, NUC, or proper server. Requires port forwarding or VPN for external access.

🔒 Tailscale Exit Node
Best of both

Home server via Tailscale. No port forwarding needed, encrypted tunnel, works through NAT.

Base Server Setup

Starting from a fresh Ubuntu/Debian installation:

Initial Server Setup
# Update system
sudo apt update && sudo apt upgrade -y

# Install essential tools
sudo apt install -y \
    git \
    curl \
    wget \
    vim \
    htop \
    tmux \
    mosh \
    build-essential \
    unzip

# Create non-root user (if not exists)
sudo adduser developer
sudo usermod -aG sudo developer

# Set up SSH key authentication
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Add your public key from the cyberdeck
echo "ssh-ed25519 AAAA... cyberdeck@sailfish" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

# Harden SSH (optional but recommended)
sudo vim /etc/ssh/sshd_config
# Set: PasswordAuthentication no
# Set: PermitRootLogin no
# Set: PubkeyAuthentication yes
sudo systemctl restart sshd

Installing Claude Code

Claude Code is Anthropic's terminal-based AI coding assistant. It understands your codebase and can execute commands, edit files, and help with development tasks.

Installation Methods

Claude Code Installation
# Method 1: Native installer (recommended)
curl -fsSL https://claude.ai/install.sh | bash

# Method 2: NPM (requires Node.js 18+)
npm install -g @anthropic-ai/claude-code

# Verify installation
claude --version
claude-code version 2.x.x

# First run - will prompt for authentication
claude
Welcome to Claude Code!
Please authenticate...

Authentication Options

Claude Code supports multiple authentication methods:

Method Best For Setup
Claude.ai Account Pro/Max subscribers OAuth login on first run
Anthropic Console API users (pay-per-use) OAuth or API key
API Key Automated/headless setups Set ANTHROPIC_API_KEY env var
API Key Setup (if using)
# Add to ~/.bashrc or ~/.zshrc
export ANTHROPIC_API_KEY="sk-ant-api..."

# Or create .env in project directory
echo 'ANTHROPIC_API_KEY=sk-ant-api...' > ~/projects/.env

# Reload shell
source ~/.bashrc
API Costs

Using Claude Code with the Anthropic API is pay-per-use and can become expensive with heavy usage. For regular use, a Claude Pro or Max subscription is more economical — it includes Claude Code access at a fixed monthly cost.

tmux Configuration

tmux is essential for persistent sessions. Your work continues even if the SSH connection drops, and you can detach/reattach at will.

Basic tmux Setup

~/.tmux.conf
# Remap prefix from Ctrl-b to Ctrl-a (easier to reach)
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

# Split panes with | and -
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %

# Reload config with prefix + r
bind r source-file ~/.tmux.conf \; display "Reloaded!"

# Enable mouse support (useful for scrolling)
set -g mouse on

# Start windows and panes at 1, not 0
set -g base-index 1
setw -g pane-base-index 1

# Increase history limit
set -g history-limit 50000

# Faster escape time (important for vim)
set -sg escape-time 10

# 256 colour support
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",*256col*:Tc"

# Status bar styling
set -g status-style 'bg=#1a1a1a fg=#00ff41'
set -g status-left '[#S] '
set -g status-right '%H:%M '
set -g status-left-length 20

# Active window highlighting
setw -g window-status-current-style 'fg=#00ffff bold'

# Pane borders
set -g pane-border-style 'fg=#333333'
set -g pane-active-border-style 'fg=#00ff41'

tmux Workflow

tmux Commands
# Create a new named session
tmux new -s main

# Detach from session (prefix + d)
Ctrl-a d

# List sessions
tmux ls
main: 1 windows (created ...)

# Attach to existing session
tmux attach -t main

# Create new window (prefix + c)
Ctrl-a c

# Switch windows (prefix + number)
Ctrl-a 1
Ctrl-a 2

# Split horizontal (prefix + |)
Ctrl-a |

# Split vertical (prefix + -)
Ctrl-a -

# Navigate panes (prefix + arrow)
Ctrl-a ←/→/↑/↓

# Kill session
tmux kill-session -t main
Recommended Workflow

Create a dedicated tmux session for Claude Code work. When you SSH in from the cyberdeck, attach to this session. When you're done or connection drops, the session persists. Next time, just reattach and continue where you left off.

Tailscale Setup

Tailscale creates a secure mesh VPN, giving your devices private IP addresses that work from anywhere. No port forwarding, no dynamic DNS, no firewall holes.

Tailscale on Bastion Server
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh

# Start and authenticate
sudo tailscale up
To authenticate, visit:
https://login.tailscale.com/a/...

# Check status
tailscale status
100.x.x.1    bastion        linux   -
100.x.x.2    cyberdeck      linux   -

# Get this machine's Tailscale IP
tailscale ip -4
100.x.x.1

# Enable SSH via Tailscale (optional, extra security)
sudo tailscale up --ssh

Once both the bastion and cyberdeck are on your Tailnet, you can SSH using the Tailscale IP addresses. This works through NAT, firewalls, mobile networks — anywhere you have internet.

Mosh Server Setup

Mosh handles the connection better than SSH for mobile use — it survives network changes, high latency, and brief disconnections.

Mosh Setup
# Install mosh on the server
sudo apt install mosh

# Open UDP ports if using ufw firewall
sudo ufw allow 60000:61000/udp

# If using Tailscale, no firewall changes needed
# Tailscale handles the routing

# Connect from cyberdeck
mosh user@100.x.x.1

# Or connect and attach to tmux in one command
mosh user@100.x.x.1 -- tmux attach -t main

Project Structure

Organise your bastion for comfortable development:

Suggested Directory Layout
~/
├── projects/           # Your code projects
│   ├── project-a/
│   ├── project-b/
│   └── .env           # Shared env vars (API keys etc)
│
├── .config/
│   └── claude/        # Claude Code config
│
├── .ssh/
│   ├── authorized_keys
│   └── config
│
├── .tmux.conf         # tmux configuration
├── .bashrc            # Shell configuration
└── .gitconfig         # Git configuration

Convenience Aliases

Add to ~/.bashrc on both bastion and cyberdeck:

~/.bashrc additions
# === ON CYBERDECK ===

# Quick connect to bastion with tmux
alias b='mosh bastion -- tmux attach -t main || mosh bastion -- tmux new -s main'
alias bs='ssh bastion'

# === ON BASTION ===

# Quick Claude Code in projects dir
alias c='cd ~/projects && claude'
alias cc='claude'

# tmux shortcuts
alias ta='tmux attach -t'
alias tl='tmux ls'
alias tn='tmux new -s'

# Project navigation
alias p='cd ~/projects'
alias pa='cd ~/projects/project-a'
alias pb='cd ~/projects/project-b'

# Git shortcuts
alias gs='git status'
alias gd='git diff'
alias gc='git commit'
alias gp='git push'
alias gl='git log --oneline -20'

Security Considerations

Security Best Practices

Your bastion is internet-accessible. Take security seriously:

fail2ban Setup
# Install fail2ban
sudo apt install fail2ban

# Create local config
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Enable and start
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Check status
sudo fail2ban-client status sshd

Complete Connection Flow

Putting it all together — from picking up the cyberdeck to working in Claude Code:

Typical Session
# 1. Open cyberdeck, launch terminal

# 2. Connect to bastion (alias from .bashrc)
b
[mosh connecting to bastion...]
[tmux session "main" attached]

# 3. Navigate to project
cd ~/projects/my-project

# 4. Start Claude Code
claude

╭─────────────────────────────────────────╮
│  Claude Code                            │
│  ~/projects/my-project                  │
╰─────────────────────────────────────────╯

> 

# 5. Work with Claude...
> review the authentication module and suggest improvements

# 6. When done, detach tmux (Ctrl-a d)
[detached from session main]

# 7. Close cyberdeck, session persists on bastion
# 8. Next time, reconnect and pick up where you left off