INTO-CPS-Association / INTO-CPS-Association/workspace
[FEATURE]Multi-platform builds with Python, Java, and TypeScript toolchains
- Dominant language
- Python
- Stars
- 0
- Forks
- 5
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the feature
As a **workspace user on either x86-64 or ARM64 hardware (including Apple Silicon and ARM cloud instances)**, I want to **run natively built workspace images that ship with Python, Java, and TypeScript development toolchains** so that **digital-twin development works out of the box on both architectures without emulation**.
### Describe the problems your feature request solves
1. Multi-platform builds are a stated requirement. The Dockerfile already declares `TARGETARCH`/`TARGETPLATFORM`/`BUILDPLATFORM` build args, but the install scripts must be verified arch-clean: any script that downloads a prebuilt binary with a hard-coded architecture string will silently produce a broken arm64 image (or break the build).
2. The workspace currently ships no managed language toolchains beyond what the base image provides. Users install compilers/runtimes by hand inside their session, which does not survive image rebuilds and diverges between users.
3. Toolchain installers are exactly the scripts most likely to break multi-arch, because vendors encode the architecture differently (`amd64`/`arm64` vs `x64`/`aarch64` vs `x86_64`), so this belongs in one shared helper rather than per-script ad-hoc logic.
### Describe the solution you'd like
**(a) One shared arch-mapping helper**, sourced by every install script:
```bash
# workspaces/src/install/common/arch.sh
#!/bin/bash
set -euo pipefail
# Docker buildx sets TARGETARCH (amd64|arm64); fall back to dpkg for
# non-buildx local builds.
ARCH="${TARGETARCH:-$(dpkg --print-architecture)}"
case "${ARCH}" in
amd64) NODE_ARCH="x64"; JAVA_ARCH="x64"; GO_STYLE_ARCH="amd64" ;;
arm64) NODE_ARCH="arm64"; JAVA_ARCH="aarch64"; GO_STYLE_ARCH="arm64" ;;
*) echo "ERROR: unsupported architecture: ${ARCH}" >&2; exit 1 ;;
esac
export ARCH NODE_ARCH JAVA_ARCH GO_STYLE_ARCH
```
**(b) Python toolchain** (apt-based → inherently multi-arch):
```bash
# workspaces/src/install/toolchains/install_python.sh
#!/bin/bash
set -euo pipefail
source "$(dirname "$0")/../common/arch.sh"
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
python3 python3-venv python3-pip python3-dev build-essential
rm -rf /var/lib/apt/lists/*
# Fast, arch-aware installer/resolver for per-user environments.
# uv publishes native amd64 and arm64 builds; its installer auto-detects.
curl -LsSf https://astral.sh/uv/install.sh | \
UV_INSTALL_DIR=/usr/local/bin sh
python3 --version && pip3 --version && uv --version
```
**(c) Java toolchain** (Eclipse Temurin; per-arch tarball):
```bash
# workspaces/src/install/toolchains/install_java.sh
#!/bin/bash
set -euo pipefail
source "$(dirname "$0")/../common/arch.sh"
JDK_MAJOR=21
JDK_URL="https://api.adoptium.net/v3/binary/latest/${JDK_MAJOR}/ga/linux/${JAVA_ARCH}/jdk/hotspot/normal/eclipse"
mkdir -p /opt/java
curl -fsSL "${JDK_URL}" | tar -xz -C /opt/java --strip-components=1
# System-wide, layer-safe PATH (survives .docker_set_envs snapshot):
ln -s /opt/java/bin/java /usr/local/bin/java
ln -s /opt/java/bin/javac /usr/local/bin/javac
cat > /etc/profile.d/java.sh <<'EOF'
export JAVA_HOME=/opt/java
export PATH="${JAVA_HOME}/bin:${PATH}"
EOF
java -version
```
**(d) TypeScript toolchain** (Node.js per-arch tarball + global npm packages):
```bash
# workspaces/src/install/toolchains/install_typescript.sh
#!/bin/bash
set -euo pipefail
source "$(dirname "$0")/../common/arch.sh"
NODE_VERSION=22.12.0 # pin; update deliberately
NODE_DIST="node-v${NODE_VERSION}-linux-${NODE_ARCH}"
NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_DIST}.tar.xz"
curl -fsSL "${NODE_URL}" -o /tmp/node.tar.xz
# TODO: verify against SHASUMS256.txt for the pinned version
tar -xJf /tmp/node.tar.xz -C /usr/local --strip-components=1
rm /tmp/node.tar.xz
npm install -g typescript ts-node @types/node
node --version && npm --version && tsc --version
```
**(e) Dockerfile wiring** — add a toolchain stage/lines to the `full`
target (or a new `INSTALLATION=devel` target to keep `full` lean):
```dockerfile
FROM configure AS install-full
# ...existing installs...
RUN bash ${INST_DIR}/toolchains/install_python.sh
RUN bash ${INST_DIR}/toolchains/install_java.sh
RUN bash ${INST_DIR}/toolchains/install_typescript.sh
```
All installs go to system locations (`/usr/local`, `/opt`) rather than
`$HOME`, so they survive the profile-clone mechanism and the
`.docker_set_envs` PATH snapshot (see the PATH lessons from issue #87).
**(f) CI: build and test both platforms** with buildx + QEMU:
```yaml
# .github/workflows/docker-build.yml (fragment)
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: ./workspaces
file: ./workspaces/Dockerfile.ubuntu.noble.xfce
platforms: linux/amd64,linux/arm64
build-args: INSTALLATION=full
push: ${{ github.event_name != 'pull_request' }}
```
plus a smoke-test job per platform that runs `python3 --version && java -version && tsc --version` inside the built image.
### Describe alternatives you've considered
- **nvm / SDKMAN / pyenv (per-user version managers)** — flexible, but they install into `$HOME` and rely on shell-rc PATH edits, which is exactly the
pattern that broke `workspace-admin` (build-time `.bashrc` edits do not survive into runtime layers). System-wide pinned installs are the
layer-safe choice; version managers can still be offered *inside* the running workspace for users who need multiple versions.
- **apt for everything** — simplest and automatically multi-arch, but Ubuntu noble's packaged Node.js and JDK lag; acceptable fallback if pinned
upstream tarballs are considered too much maintenance.
- **Per-arch Dockerfiles** — rejected; `TARGETARCH` + a single mapping helper keeps one Dockerfile and one code path.
- **Emulated (QEMU) images for arm64 users** — rejected as a product answer; desktop-in-browser under emulation is unusably slow. QEMU is used only in CI to *build* the arm64 image.
### Additional context
- The three vendor arch vocabularies covered by `arch.sh`: Docker `amd64/arm64`, Node `x64/arm64`, Adoptium `x64/aarch64`.
- All downloads must be version-pinned with checksum verification to keep builds reproducible (same policy as proposed for Filebrowser in the
file-transfer feature request).
- Image-size impact should be measured; if `full` grows too large, introduce `INSTALLATION=devel` as a separate target rather than bloating `full`.
- Interacts with the VS Code extension pre-installation work: language extensions (Python, Java, TypeScript) are only useful if the matching
toolchains exist in the image — these two features should be sequenced together.
### Success Criterion
Checklist:
- [ ] `docker buildx build --platform linux/amd64,linux/arm64` succeeds for both `full` and `minimal` targets
- [ ] `python3`, `pip`, `uv` functional on both architectures
- [ ] `java`, `javac` (Temurin, pinned major) functional on both architectures
- [ ] `node`, `npm`, `tsc`, `ts-node` functional on both architectures
- [ ] All toolchains on PATH for the runtime user (verified after profile-clone and `.docker_set_envs` restore, not just at build time)
- [ ] Shared `arch.sh` helper used by every arch-sensitive install script; no hard-coded architecture strings remain
- [ ] CI builds both platforms and runs per-platform smoke tests
- [ ] Downloads version-pinned with checksum verification
- [ ] Image size impact measured and documented
- [ ] Documentation Updated
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the existing install scripts under workspaces/src/install and workspaces/Dockerfile.ubuntu.noble.xfce, then inspect .github/workflows/docker-build.yml and the profile-clone environment handling. The work is done when both targets build for amd64 and arm64, all three toolchains work at runtime, architecture-sensitive downloads are shared and pinned, smoke tests pass, and image-size impact is documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash, docker, github-actions, java, python, typescript
- Domain
- build-system, ci-cd, developer-experience, devops, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 30/100