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 |
|---|---|
| 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:
- SSH to host:
ssh ovh5 - Create LXC container (clone from template or create fresh Ubuntu 24.04):
lxc-create -n {containername} -t download -- -d ubuntu -r noble -a amd64 - 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 - 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} - Add UFW rules for the new ports:
ufw allow {sshport}/tcp comment "{containername} SSH" ufw allow {mosh_start}:{mosh_end}/udp comment "{containername} mosh" - 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 " - Create the
devuser and configure bash and tmux with a unique status bar color:Copy thelxc-attach -n {containername} -- bash -c " useradd -m -s /bin/bash dev echo 'dev ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/dev ".bashrcand.tmux.conftemplates 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. - Set up
.login-gateway.shfor 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
- Add a ttyd service for web terminal access. Create
/etc/systemd/system/ttyd-{containername}.serviceon the host:Enable and start:[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.targetsystemctl enable --now ttyd-{containername} - Update the nginx config for web terminal routing. Add a location block to the term.ipnoelp.io server:
Reload nginx: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"; }systemctl reload nginx
Step 2: SSH Key Setup
- Add the developer’s public key to
~/.ssh/authorized_keyson 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 " - 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 - Test:
ssh {containername}should connect and display the login gateway menu.
Step 3: Mosh Setup (Recommended)
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
- Developer creates a GitHub account (or uses existing). OmelasAI naming convention:
{name}AtOmelasor{name}omelasai. - Admin invites them to the OmelasAI org:
- Go to https://github.com/orgs/OmelasAI/people
- Click “Invite member”
- Enter their GitHub username
- Set role to “Member”
- Developer accepts the invitation (via email or GitHub notification).
- On their container, authenticate the GitHub CLI:
Select: GitHub.com, HTTPS protocol, authenticate via browser (or paste token).gh auth login - Verify access:
gh auth status gh repo list OmelasAI --limit 5
Step 5: Claude Code Setup
- Claude Code should already be installed as part of the standard toolchain (Step 1). Verify:
claude --version - Developer runs
claudeto start their first session. They will need to authenticate with Anthropic. - Standard configuration:
- Model: Opus 4.6 with high effort
- Auto-approve common tools: Bash, Read, Edit, Write, Glob, Grep
- 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.
- Create the configuration directory and file:
For containers on Contabo Singapore,mkdir -p ~/.claude-net cat > ~/.claude-net/config.json << 'EOF' {"machine":"{containername}","sshHost":"local"} EOFsshHostis"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. - The MCP server for Claude Net should already be configured in Claude Code settings. If not, add it to
~/.claude/settings.jsonundermcpServers. - Test from within Claude Code:
claude_net_machines()– should list online instancesclaude_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.
- 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)
- The developer can then access their terminal at:
https://term.ipnoelp.io/{containername}/ - 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.mdfiles - [ ] Access GitHub:
gh auth statusshows authenticated - [ ] Clone repos:
gh repo clone OmelasAI/{any-repo}succeeds - [ ] Send a Claude Net message:
claude_net_send("managerclaude", "test") - [ ] Run
/start-sessionin 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 |