172 lines
4.5 KiB
Markdown
172 lines
4.5 KiB
Markdown
# arch-dev
|
|
### Riced Neovim IDE · Arch Linux · Stateful · Mobile-Aware
|
|
|
|
> *"Like Gentoo without the compiling."*
|
|
> *I use Arch BTW*
|
|
|
|
Kanagawa Wave · rolling release · AUR-powered · git-snapshotted home
|
|
|
|
---
|
|
|
|
## Branches
|
|
|
|
| Branch | Purpose |
|
|
|---|---|
|
|
| `main` | Latest stable |
|
|
| `v2` | Active development |
|
|
| `v1.7` (tag) | Frozen v1.7 reference |
|
|
|
|
---
|
|
|
|
## What's new in v2.0
|
|
|
|
- **Host UID/GID matching** — `/workspace` permissions just work, no more chowning
|
|
- **Tailscale** baked in (AUR) with `tun` device + `NET_ADMIN`/`NET_RAW`
|
|
- **Image tooling** — ImageMagick, chafa, jp2a
|
|
- **Go** — for go-based tooling
|
|
- **github-cli** (`gh`) — GitHub from terminal
|
|
- **libnewt** — provides `whiptail` for shell TUI scripts (sysmenu)
|
|
- **nvm + LTS Node** — lazy-loaded, baked into skel template
|
|
- **Capabilities settled** — pacman/sudo/tailscale all working post-`cap_drop ALL`
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# First time: create .env with your UID/GID
|
|
cp .env.example .env
|
|
echo "UID=$(id -u)" >> .env
|
|
echo "GID=$(id -g)" >> .env
|
|
|
|
# Build (UID/GID picked up from .env)
|
|
docker compose build
|
|
|
|
# Run
|
|
docker compose run --rm arch-dev
|
|
```
|
|
|
|
First run seeds `/home/dev` from the baked-in skeleton and creates a
|
|
`skeleton` snapshot you can always roll back to.
|
|
|
|
---
|
|
|
|
## Snapshot System
|
|
|
|
Your home is a git repo (state in `~/.arch-dev-state/`). Save good states,
|
|
roll back when things break.
|
|
|
|
```bash
|
|
snap claude-code "Claude Code installed and authed"
|
|
snaps # list snapshots
|
|
snapd # diff vs last snapshot
|
|
rollback claude-code # reset to snapshot
|
|
```
|
|
|
|
---
|
|
|
|
## Tailscale
|
|
|
|
```bash
|
|
# Inside container, first time:
|
|
sudo tailscaled &
|
|
sudo tailscale up # follow auth URL
|
|
snap tailscale "authenticated to tailnet"
|
|
```
|
|
|
|
After that, tailscale state persists in the named volume.
|
|
|
|
**Reminder learned the hard way**: Tailscale default-denies all tailnet
|
|
traffic. ACLs grant exceptions, not restrictions. Check ACLs FIRST when
|
|
peer connections fail silently. (Also: `tailscale ping <peer>` rules out
|
|
ACL issues before you start blaming nftables/routes.)
|
|
|
|
---
|
|
|
|
## Volume Architecture
|
|
|
|
| Path | Type | Purpose |
|
|
|---|---|---|
|
|
| `/workspace` | bind mount → `./workspace` | Project files, host-visible |
|
|
| `/home/dev` | named volume | Stateful user home |
|
|
| `/etc/skel-arch-dev/` | image layer | Read-only template |
|
|
|
|
Reset home to factory: `docker volume rm <project>_arch-dev-home`
|
|
|
|
---
|
|
|
|
## Container Capabilities
|
|
|
|
The container drops ALL capabilities then re-adds only what's needed:
|
|
|
|
| Cap | Why |
|
|
|---|---|
|
|
| `NET_BIND_SERVICE` | Bind to ports < 1024 (mosh) |
|
|
| `SETUID` / `SETGID` | sudo |
|
|
| `AUDIT_WRITE` | sudoers_audit plugin |
|
|
| `NET_ADMIN` / `NET_RAW` | Tailscale |
|
|
| `CHOWN` / `DAC_OVERRIDE` / `FOWNER` | pacman |
|
|
|
|
Plus device pass-through for `/dev/net/tun` (Tailscale kernel mode).
|
|
|
|
---
|
|
|
|
## Multi-Window Workflow
|
|
|
|
`docker exec` does NOT inherit cap_add from compose — it gets default
|
|
capabilities. That means pacman/sudo work in the original `docker compose
|
|
run` window but not in `docker exec` windows.
|
|
|
|
**Best practice:** Use `tmux` inside the container for multiple panes.
|
|
All panes inherit the original session's full caps.
|
|
|
|
```bash
|
|
tmux new -s work
|
|
# Ctrl+Space " split horizontal
|
|
# Ctrl+Space % split vertical
|
|
# Ctrl+Space d detach (container keeps running)
|
|
# tmux attach -t work
|
|
```
|
|
|
|
---
|
|
|
|
## Mobile (Termius)
|
|
|
|
Set `MOBILE=1` in Termius host profile env vars to activate:
|
|
- Single-line minimal starship prompt
|
|
- Auto-attach screen on connect
|
|
- habamax colorscheme (kanagawa needs truecolor)
|
|
- termguicolors disabled in neovim
|
|
- Bufferline disabled
|
|
|
|
With Tailscale, you can reach arch-dev from any device on your tailnet
|
|
without exposing ports — perfect for mobile dev anywhere.
|
|
|
|
---
|
|
|
|
## State Tracking — Two Systems
|
|
|
|
| System | What | Where |
|
|
|---|---|---|
|
|
| **git on branch** | Dockerfile, dotfiles, build recipe | Gitea repo |
|
|
| **`snap` inside container** | Runtime state, installed tools, auth | Docker volume |
|
|
|
|
Both required for full reproducibility — Dockerfile builds the OS,
|
|
snapshots restore the user state on top of it.
|
|
|
|
---
|
|
|
|
## Roadmap
|
|
|
|
### v2.1 (next)
|
|
- ASCIInator integration with chafa workflow refinement
|
|
- Custom neovim dashboard ASCII (using arch-dev's own logo)
|
|
|
|
### v2.2 (in design)
|
|
- Snapshot auto-push to remote (`snap` does `git push`, with override flag)
|
|
- Audit-clean .gitignore for credential paths
|
|
|
|
### v2.3+ (separate repos)
|
|
- **tailscale.nvim** — original FOSS neovim plugin for Tailscale interaction
|
|
- **ASCIInator** — image-to-ASCII tool
|