[ jd303 ]

Greetings, fellow silicon soldiers. Today we're installing Claude Code on the Pi we set up in part 1 so it runs as a persistent session you can SSH into from anywhere. Your dev environment, always on, always where you left it. This is part 3 of the CTLab Homelab series.

Again, these are detailed instructions on how to do this for the wannabe wizards. If you want to be a lame voodoo programmer you can also just skip to the warez section and use the bootstrap to get this all running immediately.

Most of this you are going to be familiar with if you went through the Getting Started with Claude Code article, but there's a few more nifty things for running on a pi.

[ jd303 ]

Why Run Claude Code on the Pi

It's Thursday evening. I'm watching Jeopardy, keeping track of my Coryat score when I have this brilliant idea for a new blog post. Or maybe it was something I remembered I needed to fix. Or was it a calendar entry that needed updating? Whatever. I realized that I have to go ALL THE WAY DOWNSTAIRS to my computer running Claude to update whatever it was I was updating.

If you know me in real life, you know that I am very lazy. I do not want to go up and down the stairs. I am getting old. This is not enjoyable for me.

I need access to Claude from my phone1, from my upstairs laptop, from any place I have a terminal. It is just much more convenient.

Running Claude Code on your local machine means your session dies when you close the terminal. Running it on the Pi means it keeps going. SSH in from your laptop, your phone, or a machine at work and you get the same session, same context, and same working directory. Pair it with tmux and you have a persistent AI-assisted dev environment that survives disconnects.

The Pi 5 has enough headroom for this alongside the rest of the stack. Claude Code itself is lightweight. The API calls do the heavy lifting, not the local process.

[ claude ]

Setup Steps

  • Install nvm + Node.js (LTS)
  • Install Claude Code (npm install -g @anthropic-ai/claude-code)
  • Configure API key
  • Install tmux
  • Set up a persistent tmux session
  • Test SSH + attach workflow from another machine
  • Optional: add tmux auto-attach to .zshrc
[ claude ]

Install nvm + Node.js

Everything from here on happens on the Pi. SSH in first if you are not already there:

ssh raspberrypi

Claude Code runs on Node.js. The easiest way to manage Node versions on Linux is nvm. It installs Node in your home directory so you never need sudo for global packages.

Install nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash

The version above may be out of date by the time you read this. Check the latest:

curl -s https://api.github.com/repos/nvm-sh/nvm/releases/latest | grep '"tag_name"' | cut -d'"' -f4

The installer adds the nvm initialization lines to your .zshrc automatically. Reload your shell to pick them up:

source ~/.zshrc

Install the current LTS release and set it as default:

nvm install --lts

Verify:

node --version
npm --version

You should see version numbers for both. If nvm: command not found appears after reloading, check that the installer added the init block to ~/.zshrc and not ~/.bashrc.

[ claude ]

Install Claude Code

With Node in place, install Claude Code globally:

npm install -g @anthropic-ai/claude-code

Verify the install:

claude --version
[ jd303 ]

Configure API Key

You need an Anthropic API key. If you do not have one yet, go read the Getting Started with Claude Code post and come back when you are done. I will wait.

If you already have one from your other machine, just run claude on the Pi. It will ask for the key on first launch and store it in ~/.claude.

[ jd303 + claude ]

Pull Your Config from GitHub

Your CLAUDE.md files and context documents are sitting in your claude-config repo from the Getting Started post. Let's get them on the Pi.

The claude auth step already created ~/.claude/ with your credentials in it. We need to back those up, clone your repo into that directory, then put the credentials back.

Back up your credentials first:

cp ~/.claude/.credentials.json ~/claude-credentials.bak

Remove the directory so git can clone into it cleanly:

rm -rf ~/.claude

Clone your config repo:

git clone https://YOUR_USERNAME@github.com/YOUR_USERNAME/claude-config.git ~/.claude

Git will prompt for your GitHub password, use the Personal Access Token you created in the Getting Started post, not your GitHub account password.

Restore your credentials:

cp ~/claude-credentials.bak ~/.claude/.credentials.json
rm ~/claude-credentials.bak

Your CLAUDE.md, context files, and memory are now on the Pi. Claude Code will pick them up automatically on the next run.

If you are using the ct-homelab repo, restore_claude.sh does all of the above interactively, prompts for your username and PAT so nothing ends up in shell history.

Update your CLAUDE.md for this machine.

Your config was written on another machine, if it describes your environment (OS, shell, paths), add a note for the Pi so Claude knows where it is. For example, if your CLAUDE.md says WSL2/zsh, add a line like main-laptop: WSL2/zsh and a new one for the Pi: homelab-pi: Raspberry Pi OS/zsh, Node via nvm, working in /home/yourname. You can also just tell Claude to do this when you first run it on the Pi, it will update its own config.

Clone or copy over any projects Claude needs.

If your contexts reference local project paths (~/projects/conspicuoustechnologist, ~/blog-writings, etc.), clone those repos on the Pi too, or rsync them over if they are not in version control. If rsyncing, don't exclude .git, without it you lose history and any per-repo git config you have set. Claude can't work on files that aren't there.

You will also need to re-auth GitHub on the Pi separately, run gh auth login and follow the prompts. Your credentials from your other machine do not transfer.

Remember that any deployment functions in your .zshrc might also need updating. For me, ctpi from part 1 has been renamed to ctdev, and what was a remote host is now just a local directory. If you built your own version, the generic form is:

ctdev() {
  ( cd /path/to/your/site && \
    your-build-command && \
    rsync -av --delete your-output-dir/ $MAIN_SITE_DIR/ && \
    docker restart nginx )
}

Install dev tools for your projects.

The projects you cloned have build tool dependencies that won't install themselves. Node is already there from nvm, but anything else needs manual setup before Claude can actually work on your code. Remember other things like Hugo, Python, or other utilities in your dev workflow.

[ claude ]

Install tmux

[ jd303 ]
If you're old enough to remember screen, the GNU-era terminal multiplexer that predates tmux by about a decade, this is the same idea, just less awful to configure.

tmux is a terminal multiplexer. It keeps sessions alive after you disconnect, lets you split the terminal into panes, and is the piece that makes the persistent Claude workflow actually work.

sudo apt install -y tmux

Set Up a Persistent Session

Create a named session in the background:

tmux new-session -d -s claude

The -d flag starts it detached (no terminal attached yet). The -s claude names it. You can use any name. claude is used here because that is what you will be attaching to.

Verify it is running:

tmux ls

You should see claude: 1 windows. This session persists until the Pi reboots. To start Claude Code inside it, attach and run it:

tmux attach -t claude
claude

Detach without stopping anything: Ctrl+b, then d. The session keeps running. Claude keeps running. Come back to it anytime. This also means if you get disconnected, the session survives. Just SSH back in and attach.

[ claude ]

Test SSH + Attach from Another Machine

From your laptop (or any machine with SSH access to the Pi):

ssh raspberrypi

Once connected, check that the session is there:

tmux ls

Attach:

tmux attach -t claude

You should land directly in your Claude Code session, same context, same working directory as when you left it. Detach again with Ctrl+b d and your SSH session ends cleanly.

[ claude ]

Auto-Attach on SSH (optional)

If you want to land directly in the tmux session every time you SSH into the Pi, add this to the bottom of ~/.zshrc:

if [ -z "$TMUX" ] && [ -n "$SSH_CONNECTION" ]; then
  tmux attach -t claude 2>/dev/null || tmux new-session -s claude
fi

The $SSH_CONNECTION check limits this to SSH logins only. It will not fire if you open a local terminal on the Pi directly. If the claude session exists, you attach to it. If not (e.g. after a reboot), a new one is created.

Reload your shell to apply:

source ~/.zshrc

Test it by exiting and SSHing back in. You should drop straight into tmux.

[ jd303 ]
That's all there is to it. Claude Code is always on, always where you left it. If you have a network hiccup, it's still there with your full context. This is my actual setup, too, not just a demo. Next up: sharing folders off the Pi with Samba so your whole network can get to them.
[ out of band ]
1. SSH from your phone. We will cover this in a later installment. Any SSH client works (Termius is popular on iOS and Android). Once you have it configured, the attach workflow is identical to the laptop. ↩︎