From 78060d789f0cc7f216379587901a19bda2c10bb4 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Wed, 28 Jan 2026 14:35:25 +0000 Subject: [PATCH 1/3] Use way more uptodate container image --- .devcontainer/devcontainer.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9fdf340..86a8d7d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,11 +1,13 @@ { - "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "image": "mcr.microsoft.com/devcontainers/javascript-node:4-24", "features": { "ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/devcontainers/features/git-lfs:1": { "autoPull": "false" // do not automatically pull LFS files when creating the container }, - "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "moby": "false" // does not work with Debian Trixie based images + }, "ghcr.io/devcontainers-extra/features/pre-commit:2": { "version": "4.2.0" } From 4f5e1254ecb3c7d9eec6dd770b074bfe901bf32b Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Wed, 28 Jan 2026 19:41:31 +0000 Subject: [PATCH 2/3] Restore manpages developers using the installed tools should have correspoding documentation. On the one hand not having the documentation is inconvenient and on the other had other sources might not match the installed tools. --- src/s-core-devcontainer/.devcontainer/s-core-local/install.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh b/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh index 3e830c9..d1d17ca 100755 --- a/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh +++ b/src/s-core-devcontainer/.devcontainer/s-core-local/install.sh @@ -19,6 +19,10 @@ ARCHITECTURE=$(dpkg --print-architecture) apt-get update +# Unminimize the image to include standard packages like man pages +bash -c "yes || true" | unminimize +apt-get install -y man-db manpages manpages-dev manpages-posix manpages-posix-dev + # INSTALL CONTAINER BUILD DEPENDENCIES # Container build dependencies are not pinned, since they are removed anyway after container creation. apt-get install apt-transport-https -y From b48915e279c8b0173d5db25175cad2574a970001 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Wed, 28 Jan 2026 15:11:40 +0000 Subject: [PATCH 3/3] devcontainer architectural overview This explains how the devcontainer is build and why certain decisions were made. It helps new contributors to understand the setup. Co-authored-by: Oliver Pajonk Signed-off-by: lurtz <727209+lurtz@users.noreply.github.com> --- docs/README.md | 81 +++++++++++++++++++ .../.devcontainer/Dockerfile | 13 +-- 2 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..1718917 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,81 @@ +# S-CORE DevContainer Architecture + +This document explains how the S-CORE DevContainer is designed, built and what its requirements are. + +## Overview + +One has to take ones own medicin and for that reason the [S-CORE devcontainer](../src/) is developed using another [simpler devcontainer](../.devcontainer). + +``` + Host + │ + ▼ +┌───────────────────────────────────────────────────────────────────────┐ +│ Outer Dev Container (.devcontainer) │ +│ Base: devcontainers/javascript-node │ +│ Tools: devcontainer CLI, Docker CLI │ +│ │ +│ devcontainer build (scripts/build.sh) │ +│ │ │ +│ │ invokes docker build │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ Build S-CORE DevContainer (src/s-core-devcontainer) │ │ +│ │ - Dockerfile (Ubuntu base image) │ │ +│ │ - Pre-existing features (Git, LLVM/Clang, Rust, …) │ │ +│ │ - S-CORE local feature (available at /devcontainer/features/…) │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ run validation (scripts/test.sh) │ +│ │ │ +│ │ on success | +│ ▼ | +│ Publish image → ghcr.io/eclipse-score/devcontainer: | +└───────────────────────────────────────────────────────────────────────┘ +``` + +This [simpler devcontainer](../.devcontainer) must be able to run [the devcontainer command](https://github.com/devcontainers/cli), which is a nodejs application and Docker. +To achieve that, [javascript-node](https://github.com/devcontainers/images/tree/main/src/javascript-node) as base image and the [Docker-in-Docker](https://github.com/devcontainers/features/tree/main/src/docker-in-docker) feature were chosen. + +## The S-CORE DevContainer + +[DR-001-Infra: Integration Strategy for External Development Tools](https://github.com/eclipse-score/score/blob/main/docs/design_decisions/DR-001-infra.md) +and +[DR-003-Infra: Devcontainer Strategy for S-CORE](https://github.com/eclipse-score/score/blob/main/docs/design_decisions/DR-003-infra.md) +require that all tools / code inside the devcontainer are pinned and that it will be used by developers and CI. +Developers and CI should only need to download prebuild container images. +The container images should be able to build all of S-CORE without extra setup. +This requires that the needed tools are preinstalled, but not too much either to keep container image download times in check. + +To achieve this, a small base image [based on Ubuntu is chosen](https://github.com/docker-library/buildpack-deps/blob/master/ubuntu/noble/curl/Dockerfile). +To this image, the tools needed to build S-CORE and run its tests are added - either via pre-existing devcontainer features, or our own [S-CORE feature](../src/s-core-devcontainer/.devcontainer/s-core-local/). +The tools also need to support typical IDE features like enabling code completion. +All of these tools could have been added via a `Dockerfile` as well, but features are the mechanism to achieve composable devcontainer implementations and are preferred instead. + +The decision whether to use a pre-existing feature or to add a tool using the S-CORE feature is based on the tradeoff between build time and maintainability. +The chosen features are installed quickly, without us having to maintain them. +Other tools installed via the S-CORE feature either have no corresponding feature, or their feature took so much time to install, that it was quicker done using our own code (example: Python feature). + +### Proxy environments + +To support proxy environments, environment variables are set in the [`Dockerfile`](../src/s-core-devcontainer/.devcontainer/Dockerfile) and unset if empty to not interfere with non-proxy environments. + +## Tests + +After an image build, tests check that each tool expected to be in the image is installed with the specified version for [pre-existing features](../src/s-core-devcontainer/test-project/test.sh) and the [S-CORE feature](../src/s-core-devcontainer/.devcontainer/s-core-local/tests/test_default.sh). +This may seem overly complex at first, but prevents (1) accidentially wrong versions, (2) completely broken tools that cannot even execute. +Both cases can happen and have happened in the past already, e.g. due to unexpected interactions between devcontainer features. + +However it is not tested, if S-CORE can be build with that image. +The expectation is that **pinned-in-source-code** devcontainer versions are used by S-CORE repositories. +Updates of devcontainer versions thus are explicit pull-requests (which can be auto-generated via Dependabot or Renovate). +If such an image update fails to build/test/... a certain module, the version bump pull-request will fail in the CI and investigation can start. +Note that this **does not impact** the regular development of that module. + +## Why this setup + +This setup is predictable and fast because a pre-built image avoids per-repo Docker builds and ensures everyone shares the same toolchain. +It strengthens the supply chain by pinning versions and hashes, sourcing features from trusted catalogs, and gating publication via CI builds and tests. +Pre-built images have a higer availability than the set of all tools which are installed (one download from a location controlled by S-CORE vs. many downloads from "everywhere"). +Pre-built images can be easily archived anywhere, e.g. for reproducibility of builds in real production use-cases. +It also enforces a clear separation of concerns: general tooling is delivered through reusable features, S-CORE–specific logic lives in a dedicated feature, and image composition plus publishing are centralized. diff --git a/src/s-core-devcontainer/.devcontainer/Dockerfile b/src/s-core-devcontainer/.devcontainer/Dockerfile index 39be3b3..b838f86 100644 --- a/src/s-core-devcontainer/.devcontainer/Dockerfile +++ b/src/s-core-devcontainer/.devcontainer/Dockerfile @@ -1,6 +1,4 @@ -ARG VARIANT="noble" - -FROM buildpack-deps:${VARIANT:-noble}-curl +FROM buildpack-deps:noble-curl # Proxy arguments for build-time network access ARG HTTP_PROXY="" @@ -24,11 +22,4 @@ LABEL dev.containers.features="common" COPY unset-proxy.sh /etc/profile.d/unset-proxy.sh RUN chmod +x /etc/profile.d/unset-proxy.sh -ARG VARIANT -RUN if [ "$VARIANT" = "noble" ]; then \ - if id "ubuntu" &>/dev/null; then \ - echo "Deleting user 'ubuntu' for $VARIANT" && userdel -f -r ubuntu || echo "Failed to delete ubuntu user for $VARIANT"; \ - else \ - echo "User 'ubuntu' does not exist for $VARIANT"; \ - fi; \ - fi +RUN userdel -f -r ubuntu