Incident 2026-06-24: OOM-uri repetate în cgroup /lxc/171 cauzate de swap nebacked pe host (pvemini fără swap) + acumulare de forks vscode-server orfane și sesiuni logind zombie. - scripts/reap-orphans.sh: reaping conservator (forks ~/.vscode-server orfane >24h + sesiuni closing cu leader mort), rulat din cron la 6h - README: secțiune Memorie & OOM (zram pe host ZFS, reaper, diagnostic), corectat date stale host/RAM/CPU (pvemini, 16GB, 4 cores) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
12 KiB
LXC 171 - Claude Agent (Development Environment)
Director: proxmox/lxc171-claude-agent/
VMID: 171
IP: 10.0.20.171 (intern) | 100.95.55.51 (Tailscale)
Host Proxmox: pvemini (10.0.20.201)
Rol: Mediu de dezvoltare izolat pentru Claude Code
Scripturi Disponibile
| Script | Descriere |
|---|---|
scripts/start-agent.sh |
Pornește/atașează sesiune tmux "agent" |
scripts/work.sh |
Meniu interactiv pentru workflow complet |
scripts/new-task.sh |
Creează branch nou pentru task |
scripts/finish-task.sh |
Finalizează task (commit + push) |
scripts/reap-orphans.sh |
Curăță procese vscode-server orfane + sesiuni zombie (cron, anti-OOM) |
Informații Container
| Parametru | Valoare |
|---|---|
| VMID | 171 |
| Hostname | claude-agent |
| IP intern | 10.0.20.171 |
| IP Tailscale | 100.95.55.51 |
| Host Proxmox | pvemini (10.0.20.201) |
| User | claude |
| Storage | local-zfs (32GB) |
| RAM | 16GB (swap 8GB — vezi nota OOM mai jos) |
| CPU | 4 cores |
Componente Instalate
- Ubuntu 24.04 LTS
- Node.js v20.x (via nvm)
- Claude Code
- tmux
- Git (configurat pentru Gitea)
- Tailscale
Conectare
De pe calculator (rețea internă)
ssh claude@10.0.20.171
De pe telefon/exterior (Tailscale)
ssh claude@100.95.55.51
VS Code Remote SSH
Config în ~/.ssh/config:
Host claude-agent
HostName 10.0.20.171
User claude
Scripturi Workflow
start-agent.sh
Pornește sau se atașează la sesiunea tmux "agent".
~/start-agent.sh
work.sh (recomandat)
Meniu interactiv pentru workflow complet:
- Listează proiectele disponibile în /workspace
- Permite crearea de branch-uri noi
- Continuarea pe branch-uri existente
- Finalizare task (commit + push)
- Vizualizare branch-uri
~/work.sh
new-task.sh
Creează branch nou pentru un task (hardcodat pentru romfastsql).
~/new-task.sh fix/nume-bug
finish-task.sh
Finalizează task-ul curent (commit + push).
~/finish-task.sh
Workflow Complet
De pe telefon (JuiceSSH + Tailscale)
- Conectează-te la
100.95.55.51cu userclaude - Rulează:
~/start-agent.sh # pornește tmux
~/work.sh # meniu interactiv
- Alege proiectul
- Alege acțiunea (task nou / continuă / finalizează)
- Lucrează cu Claude Code
- Când termini:
~/work.sh→ opțiunea 3 (finalizează)
De pe calculator (VS Code)
- VS Code → Remote SSH →
claude-agent - Open Folder →
/workspace/<proiect> - Terminal →
source ~/.nvm/nvm.sh && claude
Structura Directoare pe LXC
/home/claude/
├── .ssh/
│ ├── authorized_keys # Chei SSH pentru acces
│ ├── gitea_ed25519 # Cheie pentru Gitea
│ └── config # Config SSH pentru Gitea
├── .nvm/ # Node Version Manager
├── .claude/
│ └── settings.json # Permisiuni Claude Code
├── .tmux.conf # Configurare tmux
├── start-agent.sh -> /workspace/start-agent.sh
└── work.sh -> /workspace/work.sh
/workspace/
├── start-agent.sh # Script pornire tmux
├── work.sh # Script workflow interactiv
├── new-task.sh # Script creare branch
├── finish-task.sh # Script finalizare task
├── CLAUDE.md # Info agent
├── SETUP-COMPLETE.md # Documentație setup
├── romfastsql/ # Proiect clonat
└── test/ # Alte proiecte
Comenzi tmux Utile
| Comandă | Acțiune |
|---|---|
Ctrl+A, d |
Detașare din sesiune |
Ctrl+A, c |
Fereastră nouă |
Ctrl+A, n |
Fereastră următoare |
Ctrl+A, p |
Fereastră anterioară |
Ctrl+A, [ |
Mod scroll (q pentru ieșire) |
tmux attach -t agent |
Reatașare la sesiune |
tmux ls |
Listare sesiuni |
Git / Gitea
Clonare proiect nou
cd /workspace
git clone git@gitea.romfast.ro:romfast/<nume-repo>.git
Workflow branch-uri
git checkout main
git pull
git checkout -b feature/nume-feature
# ... lucrezi ...
git add .
git commit -m "descriere"
git push -u origin feature/nume-feature
# Creează Pull Request în Gitea
Memorie & OOM (reaping orfane + zram)
Context (incident 2026-06-24)
Containerul a generat OOM-uri repetate, izolate în cgroup-ul /lxc/171 (NU la nivel de
host — host-ul avea memorie liberă). Cauzele combinate:
- Swap fictiv: LXC 171 are
memory: 16384+swap: 8192, dar host-ul pvemini nu avea swap deloc → swap-ul containerului nu era backed de nimic. La atingerea celor 16GB se intra direct în OOM-kill, fără să poată face swap-out. Victimele tipice erau procese mici cuoom_score_adjridicat (systemd,dbus-daemon,at-spi-bus-laun,sd-pam) din sesiunileuser@1000. - Acumulare de fond: forks
~/.vscode-server(servere VS Code Remote-SSH) rămase orfane după ce conexiunea SSH moare — reparentate la init (PPID=1), vechi de zile — plus sesiunisystemd-logindblocate în stareclosing. Un spike ocazional de Chromium/Playwright împingea totalul peste 16GB → OOM.
Fix 1 — zram swap pe host (pvemini)
Root-ul pvemini e pe ZFS, deci NU se folosește swapfile (risc de deadlock). În loc, zram (swap comprimat în RAM):
# pe pvemini (host)
apt install -y zram-tools
cat > /etc/default/zramswap <<'EOF'
ALGO=zstd
SIZE=8192
PRIORITY=100
EOF
systemctl restart zramswap.service # enabled persistent la boot
zramctl; swapon --show # verificare: /dev/zram0 8G zstd
Acum cei 8GB swap din configul LXC 171 au backing real → vârfurile tranzitorii fac
swap-out în loc de OOM-kill instant.
Fix 2 — reaping orfane (scripts/reap-orphans.sh, cron în 171)
Script conservator care rulează ca root în interiorul containerului, la fiecare 6 ore:
- omoară forks
~/.vscode-serverreparentate la init (PPID=1) și mai vechi de 24h (conexiune SSH moartă); - termină sesiunile
logindîn stareclosingcu leader mort (leader=0).
Exclude explicit daemonul de bază /usr/lib/code-server (lansat de ttyd) și procesele
Claude Code (pot fi task-uri lungi legitime). Log în /var/log/reap-orphans.log.
# instalare în container (din host)
pct push 171 reap-orphans.sh /usr/local/sbin/reap-orphans.sh # sau deploy manual
pct exec 171 -- chmod +x /usr/local/sbin/reap-orphans.sh
# cron: /etc/cron.d/reap-orphans -> 0 */6 * * * root /usr/local/sbin/reap-orphans.sh
# rulare manuală + verificare
pct exec 171 -- /usr/local/sbin/reap-orphans.sh
pct exec 171 -- tail /var/log/reap-orphans.log
⚠️ NU folosi
loginctl terminate-sessionpe sesiuniclosingcare auleader != 0— acelea pot fi sesiuni VS Code remote active de lucru. Doar zombiile culeader=0sunt sigure (asta verifică și scriptul automat).
Diagnostic rapid OOM
# pe host: confirmă că OOM e în cgroup-ul containerului, nu pe host
ssh root@10.0.20.201 "journalctl -k --since '1 hour ago' | grep -iE 'oom_memcg|Killed process'"
cat /sys/fs/cgroup/lxc/171/memory.events # oom / oom_kill counters
cat /sys/fs/cgroup/lxc/171/memory.current # consum curent vs memory.max (16G)
# în container: top consumatori + orfani + sesiuni
pct exec 171 -- bash -c "ps -eo pid,ppid,etimes,rss,comm --sort=-rss | head -20"
pct exec 171 -- loginctl list-sessions
Troubleshooting
Claude Code nu pornește
source ~/.nvm/nvm.sh
which claude
claude --version
tmux nu găsește sesiunea
tmux ls
tmux new -s agent -c /workspace
Git clone eșuează
# Testează conexiunea SSH la Gitea
ssh -T git@gitea.romfast.ro
Tailscale nu funcționează
sudo systemctl status tailscaled
sudo tailscale status
tailscale ip
Instalare Claude Code pe LXC nou (de la zero)
1. Creare LXC în Proxmox
# Pe Proxmox host (ex: pveelite)
pct create <VMID> local:vztmpl/ubuntu-24.04-standard_24.04-2_amd64.tar.zst \
--hostname claude-agent \
--memory 4096 \
--cores 2 \
--rootfs local-zfs:32 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--features nesting=1 \
--unprivileged 1
pct start <VMID>
pct enter <VMID>
2. Setup sistem (ca root în LXC)
# Update și pachete de bază
apt update && apt upgrade -y
apt install -y curl git tmux sudo
# Creare user claude
useradd -m -s /bin/bash claude
echo "claude ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/claude
passwd claude # setează parola
# Creare /workspace
mkdir -p /workspace
chown claude:claude /workspace
3. Setup user claude
su - claude
# Instalare nvm + Node.js
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20
nvm alias default 20
# Instalare Claude Code
npm install -g @anthropic-ai/claude-code
# Verificare
claude --version
4. Configurare Claude Code
mkdir -p ~/.claude
cat > ~/.claude/settings.json << 'EOF'
{
"permissions": {
"allow": [
"Bash(git *)",
"Bash(npm *)",
"Bash(node *)",
"Read",
"Write",
"Edit"
],
"deny": []
}
}
EOF
5. Configurare tmux
cat > ~/.tmux.conf << 'EOF'
set -g prefix C-a
unbind C-b
bind C-a send-prefix
set -g mouse on
set -g history-limit 50000
set -g default-terminal "screen-256color"
EOF
6. Configurare Git + SSH pentru Gitea
# Generare cheie SSH
ssh-keygen -t ed25519 -f ~/.ssh/gitea_ed25519 -N ""
# Config SSH
cat > ~/.ssh/config << 'EOF'
Host gitea.romfast.ro
HostName gitea.romfast.ro
User git
IdentityFile ~/.ssh/gitea_ed25519
IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
# Afișează cheia publică (adaug-o în Gitea → Settings → SSH Keys)
cat ~/.ssh/gitea_ed25519.pub
# Config Git
git config --global user.name "Claude Agent"
git config --global user.email "claude@romfast.ro"
git config --global init.defaultBranch main
7. Instalare scripturi workflow
cd /workspace
# Copiază scripturile din acest repo (de pe mașina locală)
# SAU creează-le manual conform secțiunii "Scripturi Disponibile"
# Creare symlink-uri
ln -s /workspace/start-agent.sh ~/start-agent.sh
ln -s /workspace/work.sh ~/work.sh
chmod +x /workspace/*.sh
8. (Opțional) Instalare Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
# Autentifică-te cu contul Tailscale
tailscale ip # notează IP-ul
9. Clonare proiecte
cd /workspace
git clone git@gitea.romfast.ro:romfast/romfastsql.git
# alte proiecte...
10. Test final
~/start-agent.sh
# În tmux:
source ~/.nvm/nvm.sh
claude --version
~/work.sh
Copiere rapidă scripturi (dacă ai alt LXC configurat)
# De pe mașina locală
scp proxmox/lxc171-claude-agent/scripts/*.sh claude@<ip>:/workspace/
ssh claude@<ip> "chmod +x /workspace/*.sh && ln -sf /workspace/start-agent.sh ~/start-agent.sh && ln -sf /workspace/work.sh ~/work.sh"
Legături Utile
- Proxmox Index:
../README.md - Gitea: https://gitea.romfast.ro
Data setup: 2025-12-31 Ultima actualizare: 2026-06-24 (zram swap pvemini + reap-orphans cron, anti-OOM)