heartwood every commit a ring

the canopy thins, chromium takes root, init reaps the fallen

2fe394b4 by Isaac Bythewood · 11 days ago

modified CLAUDE.md
@@ -28,7 +28,7 @@ There are no tests, linters, or build steps in this repo — it is pure configur## Architecture- **`dotfiles/`** — Terminal and editor config (bash, git, tmux, neovim). Neovim config is Lua-based with a custom statusline. These get COPYed into the container at build time.- **`containers/webdev/`** — Ubuntu 24.04 dev container running PostgreSQL 16 + Redis via supervisord. Includes Node 22, Python 3 (pip + uv), Bun, Docker-in-Docker, and standard dev tools (neovim, tmux, git, rsync, htop, nmap, unzip, etc.).- **`containers/webdev/`** — Ubuntu 24.04 dev container with Node 22, Python 3 (pip + uv), Bun, Docker-in-Docker, Playwright Chromium (under `/opt/playwright-browsers`, for the Claude playwright MCP), and standard dev tools (neovim, tmux, git, rsync, htop, nmap, unzip, etc.). Stays alive via `sleep infinity`; entered through `docker exec -it ... tmux`. Started with `docker run --init` so PID 1 reaps zombies left behind when tmux exits.- **`hosts/alpine/`** — Production server setup: Caddy reverse proxy (auto HTTPS), Docker Compose for services, restic backups to Backblaze B2, UFW firewall, push-to-deploy via git hooks.## Deployed Projects
modified README.md
@@ -48,8 +48,9 @@ port map, and post-receive hooks all grow from that single file.## The containerAn Ubuntu-based development workstation with everything already in the ground:Python (uv), Node, Bun, PostgreSQL, Redis, Docker, neovim, tmux, and Claude.Managed by supervisord. Enter through tmux.Python (uv), Node, Bun, Docker, neovim, tmux, Claude, and Playwright Chromium(for the Claude playwright MCP). Kept alive with `sleep infinity`; enterthrough `docker exec -it bythewood-webdev tmux`.Build from the repo root so the dotfiles are in the build context:
@@ -61,7 +62,7 @@ docker volume create --name bythewood-claudedocker volume create --name bythewood-sshdocker volume create --name bythewood-resticdocker run --detach --restart unless-stopped --name bythewood-webdev \docker run --detach --init --restart unless-stopped --name bythewood-webdev \    --volume bythewood-code:/home/dev/code \    --volume bythewood-claude:/home/dev/.claude \    --volume bythewood-ssh:/home/dev/.ssh \
modified containers/webdev/Dockerfile
@@ -13,8 +13,9 @@#     docker volume create --name bythewood-ssh#     docker volume create --name bythewood-restic## Start container:#     docker run --detach --restart unless-stopped --name bythewood-webdev \# Start container (--init gives us a proper PID 1 that reaps zombies — without# it, exiting tmux leaves [tmux: server] <defunct> entries hanging around):#     docker run --detach --init --restart unless-stopped --name bythewood-webdev \#         --volume bythewood-code:/home/dev/code \#         --volume bythewood-claude:/home/dev/.claude \#         --volume bythewood-ssh:/home/dev/.ssh \
@@ -76,74 +77,27 @@ ENV DEBIAN_FRONTEND=noninteractive \RUN apt-get update && \    apt-get install -y --no-install-recommends \        # Dev tools        curl git rsync neovim openssh-client tmux whois nmap unzip \        curl git rsync neovim openssh-client tmux whois nmap unzip htop tree sudo \        # Backups        restic \        # System essentials        tzdata ca-certificates sudo \        # Build tools        build-essential \        # Monitoring        htop \        build-essential tzdata ca-certificates \        # Python        python3 python3-pip python3-venv \        # Database and caching        postgresql redis-server \        # Docker        docker.io docker-compose-v2 \        # Process management        supervisor && \        docker.io docker-compose-v2 && \    curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \    apt-get install -y nodejs && \    curl -fsSL https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh && \    curl -fsSL https://bun.sh/install | env BUN_INSTALL=/usr/local bash && \    rm -rf /var/lib/apt/lists/*    curl -fsSL https://bun.sh/install | env BUN_INSTALL=/usr/local bashRUN printf '%s\n' \    'bind 127.0.0.1' \    'protected-mode yes' \    'port 6379' \    'supervised no' \    'daemonize no' \    'logfile ""' \    'dir /var/lib/redis' \    'save ""' \    > /etc/redis/redis.conf && \    mkdir -p /var/lib/redis && \    chown redis:redis /var/lib/redisENV PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsersRUN npx --yes playwright@latest install --with-deps chromium && \    chmod -R a+rx /opt/playwright-browsersRUN ln -snf /usr/share/zoneinfo/UTC /etc/localtime && echo "UTC" > /etc/timezoneRUN service postgresql start && \    sudo -u postgres createuser -s dev && \    service postgresql stopRUN printf '%s\n' \    '[supervisord]' \    'pidfile=/run/supervisord.pid' \    'user=root' \    'nodaemon=true' \    'logfile=/dev/null' \    'logfile_maxbytes=0' \    '' \    '[program:postgresql]' \    'command=/usr/lib/postgresql/16/bin/postgres -D /var/lib/postgresql/16/main -c config_file=/etc/postgresql/16/main/postgresql.conf' \    'autostart=true' \    'user=postgres' \    'stdout_logfile=/dev/fd/1' \    'stdout_logfile_maxbytes=0' \    'redirect_stderr=true' \    '' \    '[program:redis]' \    'command=/usr/bin/redis-server /etc/redis/redis.conf' \    'autostart=true' \    'user=redis' \    'stdout_logfile=/dev/fd/1' \    'stdout_logfile_maxbytes=0' \    'redirect_stderr=true' \    > /etc/supervisord.confRUN useradd -m -G sudo,docker,postgres,redis -s /bin/bash dev && \RUN useradd -m -G sudo,docker -s /bin/bash dev && \    echo "dev ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/devCOPY dotfiles/bash_aliases /home/dev/.bash_aliases
@@ -192,4 +146,4 @@ USER devRUN curl -fsSL https://claude.ai/install.sh | bashCMD ["sudo", "/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]CMD ["sleep", "infinity"]