Files
config/README.md
T
bastien 872079bafb feat(install): offer /tmp on disk + SSH memory guard, deploy cloudpex helper
/tmp is a RAM-backed tmpfs on Ubuntu (50% of RAM). Agent runs fill it: half
the RAM goes, then every temp-file creation fails with ENOSPC and shells
break. Swap does not lift the cap, so the fix is /tmp on disk.

End-of-install offers (Linux, [y/N], skipped without a terminal, idempotent):
- offer_tmp_on_disk: mask tmp.mount + etc/tmpfiles.d/tmp.conf (wipe at
  boot, 10-day purge, /var/tmp rule kept). Effective at next reboot.
- offer_ssh_memory_guard: the previous server's rules. ssh.service drop-in
  (OOMScoreAdjust=-1000, MemoryMin=256M) + earlyoom with --avoid sshd and
  --prefer node/java. MemoryMin covers sshd only; earlyoom is the real guard.

install_cloudpex deploys the NAS mount helper in the Linux block.
Docs: README steps 12-14 + table, CLAUDE.md layout + lint command.
2026-09-22 16:57:08 +02:00

8.4 KiB

config

Personal dotfiles — vim + bash configuration and a one-shot installer.

Quick start

Install everything (clone + setup) with one command:

curl -fsSL https://git.bchanot.fr/bchanot/config/raw/branch/master/remote-install.sh | bash

(Runs a remote script through bash — see the Install section for what it does and the manual alternative.)

What's inside

Path Purpose
install.sh Installs apt packages + Docker + code-server + RDP (gnome-remote-desktop), backs up old config, deploys vim + bashrc (OS-detected), installs CLI scripts, pipx tools, a low-disk login warning and the cloudpex NAS mount helper; ends by offering two system changes (/tmp on disk, SSH memory guard).
cloudpex/ On-demand SMB mount of the CloudPex NAS share (cloudpex command + its installer). French README inside.
etc/tmpfiles.d/tmp.conf Cleanup rules for a disk-backed /tmp (wiped at boot, 10-day purge). Deployed by the /tmp on disk offer.
etc/systemd/ssh.service.d/override.conf ssh.service drop-in: sshd exempt from the OOM killer + memory reclaim protection. Deployed by the SSH memory guard offer.
etc/default/earlyoom earlyoom arguments: spare sshd/systemd, kill node/java first. Deployed by the SSH memory guard offer.
vim/vimrc Vim config: pathogen, molokai, syntastic (C with -Wall -Werror -Wextra), NERDTree, 42-style canonical class generators (:ClassH, :ClassC).
vim/autoload/ pathogen.vim plugin loader (committed).
vim/colors/ molokai.vim colorscheme (committed).
bash/bashrc-linux bashrc for desktop Linux (git-aware prompt + command timer).
bash/bashrc-osx bashrc for macOS.
bin/dt dtach session manager for claude-in-dtach sessions.
bin/dtach-router Dashboard to resume dtach sessions, shown at the start of every interactive shell (wired into ~/.bashrc by the installer).
bin/claude-provider Switch Claude Code between Anthropic and OpenRouter.
etc/profile.d/disk-usage-warning.sh Login-time warning (bold red) when / or /home cross 85% usage. Deployed to /etc/profile.d/ on Linux.

Install

One-liner (clone + install)

curl -fsSL https://git.bchanot.fr/bchanot/config/raw/branch/master/remote-install.sh | bash

remote-install.sh ensures git is present, clones the repo to ~/config (or pulls if already there), then runs install.sh. Override with env vars: REPO_URL=... CLONE_DIR=... BRANCH=... curl ... | bash.

Piping a remote script into bash runs unreviewed code over the network. Read remote-install.sh first, or use the manual clone below.

Manual

git clone https://git.bchanot.fr/bchanot/config.git && cd config
./install.sh

No argument — the OS is auto-detected.

What it does:

  1. On Debian/Ubuntu, installs a set of CLI/dev packages via apt-get (see below). Skipped automatically where apt-get is absent (macOS).
  2. Sets up Docker's official apt repo (Ubuntu) and installs the engine + compose plugin — skipped if docker is already present.
  3. Moves any existing ~/.vim, ~/.vimrc, ~/.bashrc, ~/.Sublivim to ~/Oldconfig.
  4. Clones the syntastic and nerdtree vim plugins into ~/.vim/bundle/.
  5. Copies the tracked vim files into ~/.vim and symlinks ~/.vimrc.
  6. Picks the bashrc by OS: macOS → bashrc-osx (falls back to bashrc-linux if missing), everything else → bashrc-linux. Copies it to ~/.bashrc.
  7. Installs Python CLIs via pipx (PyMuPDF → pymupdf, Markdown → markdown_py) — skipped if pipx is absent.
  8. Copies the bin/ scripts (dt, dtach-router, claude-provider) into ~/.local/bin. The dtach session-resume menu ships in the deployed bashrc-linux, so every interactive shell offers it — including VS Code Remote-SSH terminals, which are non-login and never read ~/.profile. The installer also strips any older dtach block left in ~/.profile so a plain SSH login doesn't prompt twice.
  9. On Linux, installs etc/profile.d/disk-usage-warning.sh to /etc/profile.d/ (needs sudo) so each login warns when / or /home cross 85% usage.
  10. On Linux, installs code-server (VS Code in the browser) via its vendor script — skipped if already present — and enables the code-server@$USER systemd service.
  11. On Linux, sets up RDP remote login via gnome-remote-desktop (Wayland-native): installs the daemon + openssl, generates a self-signed TLS cert once, and prompts interactively for shared "gate" credentials (skipped when no terminal is attached, or already set). Disables xrdp if present; opens UFW port 3389 only when UFW is already active.
  12. On Linux, installs the cloudpex NAS mount helper to /usr/local/bin via cloudpex/install.sh (nothing is mounted, no credential stored, see cloudpex/README.md).
  13. On Linux, at the very end, offers ([y/N], skipped when no terminal is attached) to move /tmp to disk: Ubuntu mounts /tmp as a RAM-backed tmpfs capped at 50% of RAM, which agent runs fill, halving the RAM and breaking every shell with "No space left on device". Accepting masks tmp.mount and installs etc/tmpfiles.d/tmp.conf (wipe at boot, 10-day purge). Effective at the next reboot.
  14. On Linux, at the very end, offers to keep SSH reachable under memory pressure: installs the ssh.service drop-in (OOMScoreAdjust=-1000, MemoryMin=256M) and earlyoom with etc/default/earlyoom (kills the largest process, node/java first and never sshd, once free RAM and swap both drop under 10%). Restarting ssh keeps open sessions. Note: MemoryMin protects the sshd daemon only; login sessions live in user.slice, so no setting can reserve RAM for a future shell. earlyoom acting in time is the real protection.

Packages installed (apt)

  • Build / VCS / C dev: vim git git-lfs git-filter-repo gcc make pkg-config dkms valgrind shellcheck
  • Net / security / transport: curl gnupg ca-certificates apt-transport-https net-tools openssh-server cifs-utils lftp ftp
  • Shell tooling: unzip tree tmux fzf dtach
  • Runtimes: nodejs python3-pip pipx php-cli
  • Media / doc CLI: ffmpeg weasyprint poppler-utils qpdf webp libavif-bin
  • Docker: docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin (via Docker's repo)
  • Remote access: gnome-remote-desktop openssl (apt) + code-server (via its vendor install script, not apt) — RDP remote login + browser VS Code
  • pipx: PyMuPDF (pymupdf), Markdown (markdown_py)
  • Optional (end-of-install offer, Linux): earlyoom

The script is re-runnable: each run re-backs up to ~/Oldconfig (overwriting the previous backup), re-clones plugins, skips Docker if already installed, and re-deploys the bin/ scripts.

Notes: the package list is Debian/Ubuntu-specific, and the Docker repo step assumes Ubuntu. On macOS the whole apt-get block is skipped — install vim/git/toolchain via Homebrew yourself.

CLI scripts (bin/)

Deployed to ~/.local/bin (the deployed bashrc adds this dir to PATH):

  • dt — manage claude-in-dtach sessions (dt ls|at|kill). Needs dtach + fzf.
  • dtach-router — session dashboard shown at shell startup. It ships in the deployed bashrc and is sourced (not executed) in every interactive shell, so it also fires in VS Code Remote-SSH terminals (non-login shells that skip ~/.profile). Silent no-op when no session exists. Create a session with cc [name], re-open the menu anytime with d (both aliases from the bashrc). Needs dt, dtach, fzf.
  • claude-provider — switch Claude Code between Anthropic and OpenRouter. OpenRouter mode reads the key from $OPENROUTER_API_KEY (never hardcoded). Export it from a private, untracked file, e.g. ~/.bashrc.local:
    export OPENROUTER_API_KEY="<your-openrouter-key>"
    

Requirements

  • bash, git
  • Debian/Ubuntu apt-get for the package step (optional elsewhere)
  • A bash login shell (zsh users: switch to bash for these prompts to apply)

License

GPL-3.0-or-later — see LICENSE.

Copyright (C) 2026 Bastien Chanot.