Skip to content

Make /etc/hosts write non-fatal for non-root container execution#3985

Merged
lpcox merged 2 commits intomainfrom
fix/non-root-container-hosts-write
Apr 16, 2026
Merged

Make /etc/hosts write non-fatal for non-root container execution#3985
lpcox merged 2 commits intomainfrom
fix/non-root-container-hosts-write

Conversation

@lpcox
Copy link
Copy Markdown
Collaborator

@lpcox lpcox commented Apr 16, 2026

Context

Companion to gh-aw#26658, which adds --user $(id -u):$(id -g) to the MCP gateway Docker run command so log files written via /tmp bind mounts are readable by downstream redaction and upload steps.

Problem

run_containerized.sh runs with set -e and unconditionally writes to /etc/hosts (line 289):

echo "$HOST_IP   host.docker.internal" >> /etc/hosts

When the container runs as a non-root user, this write fails with EACCES, aborting the entire gateway startup.

Fix

Wrap the /etc/hosts write in an if-else so failure produces a warning instead of aborting. With --network host (which the gateway always uses), the host.docker.internal mapping is unnecessary since localhost works directly.

Changes

File Change
run_containerized.sh Make /etc/hosts write non-fatal; log warning on failure

make agent-finished

gh-aw PR #26658 adds --user $(id -u):$(id -g) to the MCP gateway
Docker run command so log files are readable by downstream steps.
With set -e, the echo >> /etc/hosts in configure_host_dns() would
abort the gateway when running as non-root.

Fix: wrap the write in an if-else so failure is a warning, not fatal.
With --network host the host.docker.internal mapping is unnecessary
anyway since localhost works directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 16, 2026 20:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts the containerized gateway startup script to avoid aborting when running as a non-root user in the container, by making the /etc/hosts update best-effort instead of fatal under set -e.

Changes:

  • Makes the host.docker.internal append to /etc/hosts conditional on write success and logs a warning on failure.
Show a summary per file
File Description
run_containerized.sh Makes /etc/hosts write non-fatal and logs a warning if it can’t be written (e.g., non-root container user).

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread run_containerized.sh Outdated
Comment on lines +288 to +292
if echo "$HOST_IP host.docker.internal" >> /etc/hosts 2>/dev/null; then
log_info "DNS mapping configured: $HOST_IP -> host.docker.internal"
else
log_warn "Cannot write to /etc/hosts (running as non-root?); host.docker.internal mapping skipped"
fi
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2>/dev/null here will not reliably suppress the “Permission denied” message when >> /etc/hosts fails, because the shell attempts the >> redirection before applying the stderr redirect. In non-root runs this can still emit noisy stderr even though you log a warning. Consider redirecting stderr for a grouped command (or pre-checking writability) so redirection/open errors are also silenced.

Copilot uses AI. Check for mistakes.
@lpcox
Copy link
Copy Markdown
Collaborator Author

lpcox commented Apr 16, 2026

@copilot update the pr with this feedback #3985 (review)

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

@copilot update the pr with this feedback #3985 (review)

Updated in commit 9459dd3. I changed the /etc/hosts append to use grouped redirection (if { echo ... >> /etc/hosts; } 2>/dev/null; then) so shell redirection/open permission errors are suppressed cleanly in non-root runs while preserving the warning path. No UI changes were involved.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /tmp/go-build3554956550/b514/launcher.test /tmp/go-build3554956550/b514/launcher.test -test.testlogfile=/tmp/go-build3554956550/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build3554956550/b401/vet.cfg 1.80.0/internal/resolver/delegatingresolver/delegatingresolver.go -I x_amd64/vet --gdwarf-5 nal/encoding/jso-atomic -o x_amd64/vet -plu�� g_.a 8128236/b288/ x_amd64/vet -plugin-opt=-pas/opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -plugin-opt=-pas-atomic -plugin-opt=-pas-bool x_amd64/vet (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: /tmp/go-build3554956550/b496/config.test /tmp/go-build3554956550/b496/config.test -test.testlogfile=/tmp/go-build3554956550/b496/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build3554956550/b395/vet.cfg g_.a om/go-logr/logr@-nolocalimports x_amd64/vet --gdwarf-5 --64 -o x_amd64/vet 8128�� g_.a bshGWuxII x_amd64/vet -I cii -I x_amd64/vet (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build3554956550/b514/launcher.test /tmp/go-build3554956550/b514/launcher.test -test.testlogfile=/tmp/go-build3554956550/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build3554956550/b401/vet.cfg 1.80.0/internal/resolver/delegatingresolver/delegatingresolver.go -I x_amd64/vet --gdwarf-5 nal/encoding/jso-atomic -o x_amd64/vet -plu�� g_.a 8128236/b288/ x_amd64/vet -plugin-opt=-pas/opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -plugin-opt=-pas-atomic -plugin-opt=-pas-bool x_amd64/vet (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build3554956550/b514/launcher.test /tmp/go-build3554956550/b514/launcher.test -test.testlogfile=/tmp/go-build3554956550/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build3554956550/b401/vet.cfg 1.80.0/internal/resolver/delegatingresolver/delegatingresolver.go -I x_amd64/vet --gdwarf-5 nal/encoding/jso-atomic -o x_amd64/vet -plu�� g_.a 8128236/b288/ x_amd64/vet -plugin-opt=-pas/opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -plugin-opt=-pas-atomic -plugin-opt=-pas-bool x_amd64/vet (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build3554956550/b523/mcp.test /tmp/go-build3554956550/b523/mcp.test -test.testlogfile=/tmp/go-build3554956550/b523/testlog.txt -test.paniconexit0 -test.timeout=10m0s -I .cfg rg/x/oauth2@v0.3main x_amd64/vet --gdwarf-5 g/grpc/grpclog -o x_amd64/vet .cfg�� 8128236/b458/_pkgo1.25.8 -trimpath x_amd64/vet -I contextprotocol/--version -I x_amd64/vet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@lpcox lpcox merged commit 68ce183 into main Apr 16, 2026
3 checks passed
@lpcox lpcox deleted the fix/non-root-container-hosts-write branch April 16, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants