Fix sandbox dotfiles path, terminal type, and PyPI access

- Bind-mount dotfiles at node's own $HOME/dotfiles too, not just the
  host-path mount needed for the ~/.claude/hooks symlink: node's $HOME is
  /home/node, which broke clipboard-copy and anything else in this repo
  assuming ~/dotfiles.
- Forward the host's real TERM into the container instead of letting
  Docker's tty allocation default to a generic xterm, which was breaking
  the Ctrl-H/Backspace disambiguation the tmux config sets up.
- Add pypi.org/files.pythonhosted.org to the firewall's default allowlist
  so mason's pip-installed Python tools (ruff, basedpyright, debugpy) can
  actually install; verified with a real venv pip install.
This commit is contained in:
2026-07-19 03:23:11 -07:00
parent a2be0e5678
commit 18e111b00c
3 changed files with 19 additions and 2 deletions
+3 -1
View File
@@ -82,7 +82,9 @@ On start, the container runs an allowlist-only `iptables`/`ipset` firewall
(`init-firewall.sh`), matching the reference dev container. Allowed by
default: DNS resolution via Docker's embedded resolver (loopback only, so
never leaves the container), the Docker host itself (not its whole subnet),
GitHub's published IP ranges, `registry.npmjs.org`, `api.anthropic.com`, and
GitHub's published IP ranges, `registry.npmjs.org`, `pypi.org` and
`files.pythonhosted.org` (mason's Python-based LSP tools - `ruff`,
`basedpyright`, `debugpy` - install via pip), `api.anthropic.com`, and
whatever hosts `GITEA_SSH_HOST`/`GITEA_API` resolve to — that last group
isn't port-restricted, so git-over-ssh to GitHub/Gitea works without a
separate blanket "port 22 to anywhere" rule. Set `ALLOWED_DOMAINS`
+13
View File
@@ -20,6 +20,13 @@ services:
ALLOWED_DOMAINS: ${ALLOWED_DOMAINS:-}
SSH_AUTH_SOCK: /ssh-agent
ENABLE_FIREWALL: ${ENABLE_FIREWALL:-1}
# Docker's own tty allocation defaults to a generic TERM (e.g. plain
# "xterm", dropping 256-color and any extended-keys terminfo bits),
# not whatever the host's actual terminal/tmux session is using.
# Forward the real value so nvim negotiates key sequences (e.g. the
# Ctrl-H/Backspace disambiguation config/tmux.conf sets up) against
# the terminfo entry the rest of the chain actually expects.
TERM: ${TERM:-xterm-256color}
volumes:
# Mounted at the same absolute path as on the host (rather than a
# fixed /workspace) so Claude Code's project/session-history keying
@@ -33,6 +40,12 @@ services:
# in the container too. Read-only: hooks are only ever read/executed
# from here, never written.
- ${HOME}/dotfiles:${HOME}/dotfiles:ro
# Also mount at node's own $HOME/dotfiles: node's actual $HOME is
# /home/node (not the host user's $HOME above), and plenty of this
# repo's own config (nvim's clipboard-copy path, vimrc sourcing, etc.)
# assumes dotfiles lives at $HOME/dotfiles for whichever user it's
# running as.
- ${HOME}/dotfiles:/home/node/dotfiles:ro
- claude-code-bashhistory:/commandhistory
- nvim-data:/home/node/.local/share/nvim
- nvim-state:/home/node/.local/state/nvim
+3 -1
View File
@@ -63,7 +63,9 @@ done < <(echo "$gh_ranges" | jq -r '(.web + .api + .git)[]' | aggregate -q)
for domain in \
"registry.npmjs.org" \
"api.anthropic.com" \
"gitlab.com"; do
"gitlab.com" \
"pypi.org" \
"files.pythonhosted.org"; do
echo "Resolving $domain..."
ips=$(dig +noall +answer A "$domain" | awk '$4 == "A" {print $5}')
if [ -z "$ips" ]; then