-
Notifications
You must be signed in to change notification settings - Fork 7
Make devcontainer work in WSL and proxy environments #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make devcontainer work in WSL and proxy environments #52
Conversation
| "--volume=/home/${USER}/.cache/uv:/home/user/.cache/uv" | ||
| ], | ||
| "workspaceFolder": "/workspace", | ||
| "postCreateCommand": "bash .devcontainer/setup-proxy.sh", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@opajonk can you please document/explain how the split between devcontainer and features is designed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to #28
| fi | ||
| } | ||
|
|
||
| # Restart Docker with proxy settings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this kill any (unrelated) running dockers on the system?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment is outdated.
lurtz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adds README-PROXY.md with usage and troubleshooting instructions.
I guess this forgotten to be added.
We should talk about this pull request via Slack.
| "--volume=/home/${USER}/.cache/uv:/home/user/.cache/uv" | ||
| ], | ||
| "workspaceFolder": "/workspace", | ||
| "postCreateCommand": "bash .devcontainer/setup-proxy.sh", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused where this script is intended to be run. Per the location it should be run inside the S-CORE devcontainer. But the content assumes that docker is present, which is not installed in the S-CORE devcontainer but on the host instead.
If you intend to run it on the host, you have to use initializeCommand: https://containers.dev/implementors/json_reference/#lifecycle-scripts. However in this case you have to deal with lots of different environments.
Host environments I am aware of so far:
- Ubuntu 20.04, 22.04, 24.04
- do not expect to have root permissions on these
- MacOS
- WSL2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this script reconfiguring my host Docker daemon from inside the S-CORE devcontainer?
| "--volume=/var/run/docker.sock:/var/run/docker.sock", | ||
| "--volume=..:/workspace:cached", | ||
| "--volume=/tmp/.X11-unix:/tmp/.X11-unix", | ||
| "--volume=/home/${USER}/.cache/uv:/home/user/.cache/uv" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is in .cache/uv? It does not exist on my host
| "--env=WORKSPACE_FOLDER=/workspace", | ||
| "--volume=/var/run/docker.sock:/var/run/docker.sock", | ||
| "--volume=..:/workspace:cached", | ||
| "--volume=/tmp/.X11-unix:/tmp/.X11-unix", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would this close the door to wayland users?
| "--env=no_proxy", | ||
| "--env=DISPLAY", | ||
| "--env=WORKSPACE_FOLDER=/workspace", | ||
| "--volume=/var/run/docker.sock:/var/run/docker.sock", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to check how well this works with podman. At the time being I would like to be able to run the container on both docker and podman. The reason is that for being able to run bazels linux-sandbox the container needs to be run with --privileged which gives the container with docker basically root access to my notebook. With podman this can be minimized to my user.
I have so far seen containers as an easy to setup development environment and as a security / safety measure for the host system of my computer. Having to use --privileged is already a big boon to that and seeing the host docker being reconfigured from within the container seems to further tear down this wall.
| "--env=https_proxy", | ||
| "--env=NO_PROXY", | ||
| "--env=no_proxy", | ||
| "--env=DISPLAY", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this read the content of the current variable and assign it to DISPLAY inside the container?
| echo "🔄 Restarting Docker daemon with proxy settings..." | ||
|
|
||
| # Kill existing dockerd if running | ||
| if pgrep dockerd > /dev/null; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docker is not installed inside the container. How can you access it?
| sudo tee /etc/docker/daemon.json > /dev/null << EOF | ||
| { | ||
| "registry-mirrors": [], | ||
| "insecure-registries": [], | ||
| "debug": false, | ||
| "experimental": false, | ||
| "dns": ["8.8.8.8", "1.1.1.1"], | ||
| "dns-search": [], | ||
| "dns-opts": [] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have setup a daemon.json so that docker works in the corporate environment of my company. Would this be overriden, if I were using one of the proxy variables?
| # Prepare buildx command with proxy options | ||
| BUILDX_CMD="docker buildx create --name multiarch --driver docker-container --driver-opt network=host" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now I get very confused. I assume this requires the existence of a Dockerfile. Is this script used to build the S-CORE devcontainer with the other devcontainer of this repository?
I agree we should have a chat. There seems to be a legitimate use-case (as I also heard during the architecture workshop last week). However, re-configuring the docker host (!) significantly - and probably unexpectedly to most other users - is a problem. Maybe we can find a less "intrusive" and still helpful solution? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works on my machine.
Now proxy related environment variables are defined in the container with empty content. I hope no software trips over that.
Have you considered using
"runArgs": [
"--env-file", "proxy_settings.env",
],
In the devcontainer.json? In proxy_settings.env you define the environment variables to be made available inside the container. Maybe even .env as filename is sufficient and no extra arguments needed (was not working for me with an already built container)
In general, I like the .env file approach, but in that case it would mean that users behind proxies would have to create the .env file manually before they can start. The current approach does not need any user interaction, neither from user behind a proxy nor from users with direct internet connection. Regarding the empty environment variables in case of direct internet access: However, I could add a line like
to the devcontainer.json. Does that make sense from your side? |
|
I would appreciate if these are deleted if empty. Then we are sure not to get unintended side effects. I also only checked if some tools work. Would be a waste of time to discover that there is a tool which malfunctions when these variables are set but empty. |
Is addressed with c81e8ed |
|
I get an error, when starting the container: I suspect the problem is that |
| "./s-core-local" | ||
| ], | ||
| "remoteUser": "vscode", | ||
| "postStartCommand": "bash -c 'for var in HTTP_PROXY HTTPS_PROXY http_proxy https_proxy NO_PROXY no_proxy; do [ -z \"${!var}\" ] && unset $var || true; done'", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this still does not work. Execution is now successful, but variables are still present in a new shell:
vscode ➜ /workspaces/inc_mw_com (example_trait_impl) $ cat .devcontainer/devcontainer.json
{
"name": "eclipse-s-core",
// "image": "ghcr.io/eclipse-score/devcontainer:rustup-completion-amd64"
"image": "ghcr.io/eclipse-score/devcontainer:proxy-settings-amd64"
// "image": "ghcr.io/eclipse-score/devcontainer:fix-setting-bazel-version-amd64"
}
vscode ➜ /workspaces/inc_mw_com (example_trait_impl) $ env | grep -i proxy
no_proxy=
https_proxy=
NO_PROXY=
HTTPS_PROXY=
HTTP_PROXY=
http_proxy=
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. The postStartCommand runs in its own shell und unsets the environment variables only there.
The only solution I would have at the moment, would be to append unset commands to .bashrc in the postStartCommand. The .bashrc is then sourced by every new bash shell and every time unsets the environment variables. But it's not a nice solution imho. Would appreciate better proposals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we can use /etc/profile.d/ for this. Here is an example where I removed using it: https://github.com/eclipse-score/devcontainer/pull/51/files#diff-e418ce180663a5c3fc806f1c352a9d737097e60cecaa9cd1724c8236a955a335R64
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed with #102e649a40d7af70dba77453bbb984b659e5ff74
| # gdb (GNU Debugger) | ||
| apt-get install -y gdb="${gdb_version}*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@opajonk Do we really have to specify the tool version, if it just installed via apt-get? E.g. Python tooling is not installed with a specific version either: https://github.com/etas-contrib/score_devcontainer/blob/8aae83706ce51796b85894cdd2c6c0bc29901e84/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh#L41
We already have a Ubuntu release set, which defines the versions of these tools. And thus defining the versions for each tool feels redundant.
|
|
||
| # OpenJDK JRE and CA certificates, via APT | ||
| # Required for Bazel to work with corporate proxy/CA certificates | ||
| apt-get install -y --no-install-recommends ca-certificates-java openjdk-${openjdk_version}-jre-headless |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Specifying the Java version here is IMHO ok, because there are different versions as apt packages available for the same Ubuntu release.
… direct internet connection
Signed-off-by: Oliver Emrich <oliver.emrich2@bosch.com>
…te proxy/CA certificates
8aae837 to
8490b2b
Compare
|
#52 (comment) is still relevant |
|
|
||
| # Proxy arguments for build-time network access | ||
| ARG HTTP_PROXY | ||
| ARG HTTPS_PROXY | ||
| ARG http_proxy | ||
| ARG https_proxy | ||
| ARG NO_PROXY | ||
| ARG no_proxy | ||
|
|
||
| FROM buildpack-deps:${VARIANT}-curl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, there is even more here: there are pre-defined build args in Docker (I did not know before reviewing this PR). Guess what, they are exactly those we are looking for here! Can you test if that works? Maybe the ARG declarations are not needed at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I lean towards having them explicitly. Otherwise someone will also stumble across it and wonder how did this ever work?
Co-authored-by: Oliver Pajonk <oliver@pjnk.de> Signed-off-by: Oliver Emrich <195922963+olivembo@users.noreply.github.com>
opajonk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice job!
Summary
This PR adds robust support for running the devcontainer in environments with or without a corporate proxy, including WSL2 scenarios. The setup is now fully automated and self-healing, ensuring Docker and BuildKit always use the correct proxy settings.
Key changes
Automated proxy detection and configuration
Post-create automation
Build-time and runtime proxy support
WSL2 and host networking compatibility
Documentation and testing
How it works
On container creation, the setup script:
Detects proxy settings.
Configures Docker daemon and BuildKit accordingly.
Verifies Docker and registry access.
Works out-of-the-box for both proxy and non-proxy environments.
Handles proxy changes and container rebuilds gracefully.
Why
Ensures reliable devcontainer builds in corporate, WSL, and direct-internet environments.
Reduces manual setup and troubleshooting for developers.
Makes onboarding and CI/CD more robust.