DocHub
End-to-end onboarding process for setting up a new OmelasAI developer with their own LXC container, Claude Code, GitHub access, skills, and Claude Net messaging

New Developer Setup Guide

A new developer at OmelasAI gets:

  • Their own LXC container on Contabo Singapore (62.72.47.64) with a persistent Claude Code session
  • GitHub access to the OmelasAI organization
  • Claude Code with 18 shared skills and the project map
  • SSH/mosh access from their laptop, plus browser-based web terminal access
  • Claude Net messaging to communicate with other instances

This guide walks through the complete setup from container creation to verification.

Prerequisites

Before starting, the admin (Chas) needs:

Item Details
Email The developer’s @omelasai.com email address
GitHub username Their existing or newly created GitHub account
SSH public key ed25519 preferred (ssh-keygen -t ed25519)

The admin must have SSH access to the Contabo Singapore host (ssh ovh5).

Step 1: Container Setup (Admin – on Contabo Singapore host)

If using an existing container (seanclaude, jazclaude, managerclaude), skip to Step 2.

For a new container:

  1. SSH to host: ssh ovh5
  2. Create LXC container (clone from template or create fresh Ubuntu 24.04):
    lxc-create -n {containername} -t download -- -d ubuntu -r noble -a amd64
    
  3. Configure networking – assign an IP in the 10.0.3.x range and add to the lxcbr0 bridge. Edit /var/lib/lxc/{containername}/config:
    lxc.net.0.type = veth
    lxc.net.0.link = lxcbr0
    lxc.net.0.ipv4.address = 10.0.3.{N}/24
    lxc.net.0.ipv4.gateway = 10.0.3.1
    
  4. Add iptables DNAT rules for SSH port and mosh UDP range. Append to /etc/rc.local:
    iptables -t nat -A PREROUTING -p tcp --dport {sshport} -j DNAT --to-destination 10.0.3.{N}:22
    iptables -t nat -A PREROUTING -p udp --dport {mosh_start}:{mosh_end} -j DNAT --to-destination 10.0.3.{N}:{mosh_start}-{mosh_end}
    
  5. Add UFW rules for the new ports:
    ufw allow {sshport}/tcp comment "{containername} SSH"
    ufw allow {mosh_start}:{mosh_end}/udp comment "{containername} mosh"
    
  6. Start the container and install the standard toolchain:
    lxc-start -n {containername}
    lxc-attach -n {containername} -- bash -c "
      curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
      apt-get install -y nodejs docker.io tmux mosh git gh
      npm install -g @anthropic-ai/claude-code
    "
    
  7. Create the dev user and configure bash and tmux with a unique status bar color:
    lxc-attach -n {containername} -- bash -c "
      useradd -m -s /bin/bash dev
      echo 'dev ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/dev
    "
    
    Copy the .bashrc and .tmux.conf templates from an existing container, updating the tmux status bar color. Each container has a distinct color to prevent confusion about which machine a developer is working on.
  8. Set up .login-gateway.sh for the welcome menu. This script runs on SSH login and presents options:
    • [1] Attach to Claude Code tmux session
    • [2] Open a new terminal
    • [q] Disconnect
  9. Add a ttyd service for web terminal access. Create /etc/systemd/system/ttyd-{containername}.service on the host:
    [Unit]
    Description=ttyd for {containername}
    After=network.target
    
    [Service]
    ExecStart=/usr/bin/ttyd -p {ttydport} -W lxc-attach -n {containername} -- su - dev
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
    Enable and start: systemctl enable --now ttyd-{containername}
  10. Update the nginx config for web terminal routing. Add a location block to the term.ipnoelp.io server:
    location /{containername}/ {
        proxy_pass http://127.0.0.1:{ttydport}/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    
    Reload nginx: systemctl reload nginx

Step 2: SSH Key Setup

  1. Add the developer’s public key to ~/.ssh/authorized_keys on their container:
    lxc-attach -n {containername} -- su - dev -c "
      mkdir -p ~/.ssh && chmod 700 ~/.ssh
      echo '{public_key}' >> ~/.ssh/authorized_keys
      chmod 600 ~/.ssh/authorized_keys
    "
    
  2. On the developer’s laptop, add an SSH config entry (~/.ssh/config):
    Host {containername}
        HostName 62.72.47.64
        Port {sshport}
        User dev
        IdentityFile ~/.ssh/{keyname}
        IdentitiesOnly yes
    
  3. Test: ssh {containername} should connect and display the login gateway menu.

Mosh provides persistent connections that survive network changes, laptop lid-closes, and brownouts. Install mosh on the developer’s laptop:

# Ubuntu/Debian
sudo apt install mosh

# macOS
brew install mosh

Create a connection script (e.g., ~/bin/connect-{containername}.sh):

#!/bin/bash
ssh -o ConnectTimeout=5 {containername} 'pkill mosh-server' 2>/dev/null && sleep 1
mosh -p {mosh_start} --ssh="ssh -p {sshport}" dev@62.72.47.64

Make it executable: chmod +x ~/bin/connect-{containername}.sh

Each container has a dedicated mosh UDP range (10 ports). The ranges are:

Container SSH Port Mosh UDP Range
chasclaude 2211 60011-60020
infoclaude 2212 60021-60030
seanclaude 2213 60031-60040
jazclaude 2214 60041-60050
managerclaude 2215 60051-60060

Step 4: GitHub Access

  1. Developer creates a GitHub account (or uses existing). OmelasAI naming convention: {name}AtOmelas or {name}omelasai.
  2. Admin invites them to the OmelasAI org:
  3. Developer accepts the invitation (via email or GitHub notification).
  4. On their container, authenticate the GitHub CLI:
    gh auth login
    
    Select: GitHub.com, HTTPS protocol, authenticate via browser (or paste token).
  5. Verify access:
    gh auth status
    gh repo list OmelasAI --limit 5
    

Step 5: Claude Code Setup

  1. Claude Code should already be installed as part of the standard toolchain (Step 1). Verify:
    claude --version
    
  2. Developer runs claude to start their first session. They will need to authenticate with Anthropic.
  3. Standard configuration:
    • Model: Opus 4.6 with high effort
    • Auto-approve common tools: Bash, Read, Edit, Write, Glob, Grep
  4. The typical workflow is to run Claude Code inside a tmux session so it persists across disconnects. The login gateway’s [1] option handles this automatically.

Step 6: Skills Installation

Skills are automatically installed by the propagation script. To verify they are present:

ls ~/.claude/commands/

This should show 18 .md files. If skills are missing, the admin runs propagation from the Contabo Singapore host:

ssh ovh5 "bash /root/code/ClaudeSkills/infrastructure/propagate-from-host.sh"

Also verify that projects.yaml (the single source of truth for all projects, servers, and credentials) is present:

cat ~/code/ClaudeSkills/projects.yaml | head -5

If the ~/code/ClaudeSkills/ directory does not exist, clone it:

mkdir -p ~/code && cd ~/code
gh repo clone OmelasAI/claude-skills ClaudeSkills

Step 7: Claude Net Configuration

Claude Net is the inter-instance messaging system that lets Claude Code instances communicate with each other.

  1. Create the configuration directory and file:
    mkdir -p ~/.claude-net
    cat > ~/.claude-net/config.json << 'EOF'
    {"machine":"{containername}","sshHost":"local"}
    EOF
    
    For containers on Contabo Singapore, sshHost is "local" because they communicate directly with the hub at 10.0.3.1:3500. For machines outside the server (laptops, ser8), use "ovh5" to tunnel via SSH.
  2. The MCP server for Claude Net should already be configured in Claude Code settings. If not, add it to ~/.claude/settings.json under mcpServers.
  3. Test from within Claude Code:
    • claude_net_machines() – should list online instances
    • claude_net_send("managerclaude", "Hello from {containername}") – should deliver

Step 8: Clone First Project

With GitHub authenticated and skills installed, the developer can start working:

cd ~/code
gh repo clone OmelasAI/{repo-name}
cd {repo-name}

Then run /start-session inside Claude Code. This skill reads the project’s HANDOVER.md, loads context from projects.yaml, reviews recent git history, and outputs a summary of the current state and what to work on next.

Step 9: Web Terminal Access (Optional)

Web terminals provide browser-based access to a container’s tmux session without needing SSH configured locally.

  1. Admin adds the developer’s @omelasai.com email to the Cloudflare Access policy:
    • Go to Cloudflare Zero Trust dashboard
    • Navigate to Access > Applications > term.ipnoelp.io
    • Add the email to the allowed list (or ensure the @omelasai.com domain policy covers it)
  2. The developer can then access their terminal at:
    https://term.ipnoelp.io/{containername}/
    
  3. Authentication is via Google OAuth with their @omelasai.com account. Sessions last 30 days.

Access restrictions:

  • Chas (chas@omelasai.com): All containers
  • Sean (sean@omelasai.com): seanclaude and managerclaude only
  • Jaz (jaz@omelasai.com): jazclaude and managerclaude only

Verification Checklist

After onboarding, the developer should be able to complete every item:

  • [ ] SSH into their container: ssh {containername}
  • [ ] Start Claude Code: claude (or attach to existing tmux session via login gateway)
  • [ ] See all 18 skills: ls ~/.claude/commands/ shows 18 .md files
  • [ ] Access GitHub: gh auth status shows authenticated
  • [ ] Clone repos: gh repo clone OmelasAI/{any-repo} succeeds
  • [ ] Send a Claude Net message: claude_net_send("managerclaude", "test")
  • [ ] Run /start-session in a project directory and get a context summary

Access Matrix

Resource Chas Sean Jaz
All containers (SSH) Yes Own only Own only
All servers (SSH) Yes No* No*
GitHub (push) Yes Yes Yes
Web terminals All seanclaude + managerclaude jazclaude + managerclaude
Cloudflare dashboard Yes No No
DocHub (browser) Yes Yes Yes
Dashboard (admin.ipnoelp.io) Yes Yes Yes

*Developers access production servers only through their container’s Claude Code with explicit permission, or through the deployment skills (/deploy). Direct SSH to production servers is reserved for the admin.

Troubleshooting

Problem Solution
SSH “too many authentication failures” Add IdentitiesOnly yes to the SSH config entry
Mosh connection hangs Ensure UDP ports are open: sudo ufw status on host
Claude Code not found Reinstall: npm install -g @anthropic-ai/claude-code
Skills missing after propagation Check ~/.claude/commands/ ownership – must be owned by dev
Claude Net times out Verify hub is running: ssh ovh5 "systemctl status claude-net"
Web terminal 403 Email not added to Cloudflare Access policy
gh auth fails Try token auth instead of browser: gh auth login --with-token