code-server: [Bug]: code-server (run with docker) will always overwrite PATH variable

Is there an existing issue for this?

  • I have searched the existing issues

OS/Web Information

  • Remote OS: Ubunu
  • Remote Architecture: amd64
  • code-server --version: both v4.7.0 and v4.0.1 are tried

Steps to Reproduce

  1. In a machine with docker installed, run
    mkdir -p ~/.config
    docker run -it --name code-server -p 127.0.0.1:8080:8080 \
    -v "$HOME/.config:/home/coder/.config" \
    -v "$PWD:/home/coder/project" \
    -u "$(id -u):$(id -g)" \
    -e "DOCKER_USER=$USER"  -e "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/some/path" \
    codercom/code-server:latest
    
  2. Login to the browser, launch terminal in vscode and print the PATH echo $PATH
  3. Always get:

Expected

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/some/path with some extra paths appended by code-server.

Actual

/usr/lib/code-server/lib/vscode/bin/remote-cli:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

Logs

No response

Screenshot/Video

No response

Does this issue happen in VS Code or GitHub Codespaces?

  • I cannot reproduce this in VS Code.
  • I cannot reproduce this in GitHub Codespaces.

Are you accessing code-server over HTTPS?

  • I am using HTTPS.

Notes

Though I checked I am using HTTPS, but I actually running locally without HTTPS. I checked it because it is a must and I think HTTPS has nothing to do with the issue.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 23 (23 by maintainers)

Most upvoted comments

I tried the same thing with debian:11 (this is what code-server is based on) and reproduced:

coder@my-dev2:~/docker$ docker run --rm -e "PATH=/usr/bin:/bin:/some-path" -it debian:11 bash
root@25b75f4f2da6:/# printenv PATH
/usr/bin:/bin:/some-path
root@25b75f4f2da6:/# bash -lc 'printenv PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

In /etc/profile there is this:

if [ "$(id -u)" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi

So this could be the cause of the problem.

Can confirm that disabling Terminal › Integrated: Inherit Env prevents the override.

I am not familiar with it. It seems I cannot customize in the demo- mode.

No. But see https://github.com/b-data/jupyterlab-python-docker-stack#run-container


Adapted to your example:

docker run -it --name jupyter-code-server \
  -u root \
  -p 8888:8888 \
  -v $PWD:/home/$USER \
  -e NB_USER=$USER \
  -e NB_UID=$(id -u) \
  -e NB_GID=$(id -g) \
  -e CHOWN_HOME=1 \
  -e CHOWN_HOME_OPTS=-R \
  -e PATH=/opt/TinyTeX/bin/linux:/opt/quarto/bin:/opt/code-server/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/some/path \
  registry.gitlab.b-data.ch/jupyterlab/python/scipy

ℹ️ Run the command in an empty directory so that the container populates it.
👉 -e CHOWN_HOME=1 and -e CHOWN_HOME_OPTS=-R is only required at first run.

I remember looking into this briefly before (#4699) but I have no idea where it happens. disappointed

How did I not find out the previous issue 😲 I searched that…

Prepending /usr/lib/code-server/lib/vscode/bin/remote-cli to PATH is not a bug but by design.

Cross references:

Looks good. These are fine if documented I think.

That seems chill. Maybe we can do the Docker tags like this:

latest         # debian:11 with latest code-server
bullseye       # debian:11 with latest code-server
focal          # ubuntu:focal with latest code-server
4.7.0          # debian:11 with code-server 4.7.0
4.7.0-bullseye # debian:11 with code-server 4.7.0
4.7.0-focal    # ubuntu:focal with code-server 4.7.0

I patterned that after the Python image but maybe in code-server’s case it makes more sense to do it by OS.

latest       # debian:11 with latest code-server
debian       # debian:11 with latest code-server
ubuntu       # ubuntu:focal with latest code-server
4.7.0        # debian:11 with code-server 4.7.0
4.7.0-debian # debian:11 with code-server 4.7.0
4.7.0-ubuntu # ubuntu:focal with code-server 4.7.0

We could also do both.

With inherit env: gets environment by spawning a login shell and overrides current environment

For a login shell, I think the path set in the Dockerfile or pass from the docker run command should be respected. See: image

So I think either vscode modifies the PATH or code-server modifies it. It is more likely that the code-server modifies it as the local instance of vscode runs without this issue.

can it preserve the modified PATH? Inherit Env sounds like getting env from the env that it runs in.

Yeah it looks ilke the “inherit env” name is misleading. It seems to mean that it spawns a login shell to get the environment rather than using the current environment (which sounds backwards from “inherit” to me 🤷 but I guess that is the name they went with).

So to summarize:

  • With inherit env: gets environment by spawning a login shell and overrides current environment
  • Without inherit env: uses the current environment

Oh wait I think I might know what it is! I think VS Code spawns a login shell to get PATH. So basically they run something like bash -lc "printenv PATH" and then set PATH to that. Edit: actually it seems they source the entire environment not just PATH as seen here then merge it with the current environment.

There are some terminal settings like Inherit Env that we might want to play around with to see if we can stop it from doing that.