devcontainers / devcontainers/cli

Dockerfile `ENV` mutates system-wide `/etc/environment`

Abierto
#1,231 1 comentario 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
3k
Forks
457
Merge medio
13 h 17 min
PR fusionados (30 d)
6

Descripción

Problem: Extremely surprising that DevContainers mutates system-wide `/etc/environment` at all.

This is a pretty insane architectural choice for a few reasons:

1. fails rule of lease surprises
2. is a breaking-change compared to other container runners, doesn't match deployment of a target container
3. major security concern for per-user secrets, or build-time only secrets, getting injected into the system environment where every user (e.g. daemon web applications, databases, etc.) now potentially has these secrets in their environment

Reproduce this issue, create a Dockerfile:

```Dockerfile
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

# Layer 1: Locale + Timezone
RUN apt-get update && apt-get install -y --no-install-recommends \
locales tzdata \
&& sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
&& locale-gen \
&& ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*

ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 TZ=America/Los_Angeles

# Switch to picard user for all per-user tool installs
USER picard
WORKDIR /home/picard

# Layer: Rust (stable via rustup)
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \
-y --default-toolchain stable --profile default
ENV PATH="/home/picard/.cargo/bin:$PATH"
```

Just opening a container using VsCode will edit the `/etc/environment`:

https://github.com/devcontainers/cli/blob/65f98a518a1f62355a08e6f38e9d6bfb9a0d8ac9/src/spec-common/injectHeadless.ts#L750-L761

```sh
# Open a shell inside the container
docker compose exec claude-dev zsh
```

From the container:

```console
cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"

ANTHROPIC_API_KEY="sk-ant-your-key-here"
OPENAI_API_KEY="sk-your-key-here"
GEMINI_API_KEY="your-key-here"
PATH="/home/picard/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
DEBIAN_FRONTEND="noninteractive"
LANG="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
TZ="America/Los_Angeles"
```

In this repro, it means that every user's Rust bin will be served from the `picard` user's home directory. That's just not how this should work.

I don't believe this is the intention for the `ENV` directive of a Dockerfile!
https://docs.docker.com/reference/dockerfile/#env

When you run `docker exec`, the container runtime reads the same image config and passes the `ENV` vars via `execve` to the new process, regardless of which user it runs as (`--user`). So every docker exec session gets them. But this is very different than injecting it into `/etc/environment` where the change is persisted for any user logging into the container (e.g. `ssh`) and not limited to `docker exec`.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.