@@ -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
@@ -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"]