EduIDE is built with this project.
This repository is a fork of the Eclipse Theia IDE project, tailored for computer science education.
Main Theia Repository — Eclipse Theia IDE Repository
EduIDE provides browser-based, language-specific IDE environments for higher education. Students open a full IDE in their browser — no local installation required — pre-configured with the compiler, language server, linter, and editor settings appropriate for their course.
Instructors select a matching image in Artemis when creating a programming exercise. EduIDE handles the rest.
| Language | Image | Language server & autocomplete |
|---|---|---|
| Java 17 | ghcr.io/eduide/eduide/java-17 |
✔️ |
| Python | ghcr.io/eduide/eduide/python |
✔️ |
| C | ghcr.io/eduide/eduide/c |
✔️ |
| JavaScript | ghcr.io/eduide/eduide/javascript |
✔️ |
| Rust | ghcr.io/eduide/eduide/rust |
✔️ |
| Swift | ghcr.io/eduide/eduide/swift |
✔️ |
| OCaml | ghcr.io/eduide/eduide/ocaml |
✔️ |
| Haskell | ghcr.io/eduide/eduide/haskell |
❌ |
All images share a common two-tier build:
base-ide— Compiles the Theia application from source, downloads core plugins (Git, Markdown, Scorpio/Artemis integration), and produces a slim runtime layer.- Language images — Each starts from the
base-idelayer, adds a language compiler/runtime (via apt), and downloads language-specific VS Code extensions from Open VSX.
This means Theia is only built once. Adding or updating a language image does not require rebuilding the IDE.
- Docker with BuildKit enabled (Docker Desktop 4.x or Docker Engine 23+)
- Docker Compose v2.x
Pull and run any language image directly:
docker run --rm -p 3000:3000 ghcr.io/eduide/eduide/java-17:latestThen open http://localhost:3000/ in your browser.
The repository includes docker-compose.images.yml which builds all images and wires them together. Language images automatically consume the locally-built base-ide via additional_contexts.
Build everything (base first, then all language images in parallel):
docker compose -f docker-compose.images.yml buildBuild a single language image (base is rebuilt or reused from cache):
docker compose -f docker-compose.images.yml build java-17Start a specific IDE and open it in the browser:
docker compose -f docker-compose.images.yml up java-17
# → http://localhost:3003/Port mapping per service:
| Service | Host port | URL |
|---|---|---|
base-ide |
3000 | http://localhost:3000/ |
c |
3001 | http://localhost:3001/ |
haskell |
3002 | http://localhost:3002/ |
java-17 |
3003 | http://localhost:3003/ |
javascript |
3004 | http://localhost:3004/ |
ocaml |
3005 | http://localhost:3005/ |
python |
3006 | http://localhost:3006/ |
rust |
3007 | http://localhost:3007/ |
swift |
3008 | http://localhost:3008/ |
images/
base-ide/ # Builds Theia from source (BaseDockerfile)
<lang>/ # One directory per language (ToolDockerfile)
ToolDockerfile
package.json.patch # Plugin overrides merged on top of root package.json
project/.vscode/settings.json # Workspace settings loaded by Theia on startup
applications/browser/ # Browser target (compiled into base-ide)
theia-extensions/product/ # Custom branding extension (included in all images)
scripts/ # Utility scripts (update-theia-version, make-files-writeable)
docker-compose.images.yml # Local build and run
.github/workflows/build.yml # CI: builds and pushes all images to GHCR
-
Create
images/<lang>/with three files:ToolDockerfile— copyimages/c/ToolDockerfileas a starting point and replace the apt packages and plugin download step with your language's tooling.package.json.patch— declare only the plugin overrides. The file is deep-merged with the rootpackage.jsonat build time:{ "theiaPlugins": { "my-publisher.my-extension": "https://open-vsx.org/api/my-publisher/my-extension/1.0.0/file/..." }, "theiaPluginsExcludeIds": [ "vscode.php" ] }Browse plugins at open-vsx.org.
project/.vscode/settings.json— workspace settings Theia loads on startup. At minimum include:{ "extensions.ignoreRecommendations": true, "files.exclude": { "**/.theia": true, "persisted": true, "lost+found": true }, "telemetry.telemetryLevel": false } -
Add the service to
docker-compose.images.ymlfollowing the existing pattern (includeadditional_contextsso local builds use the locally-built base):<lang>: image: theia-<lang>:local build: context: . dockerfile: images/<lang>/ToolDockerfile args: BASE_IMAGE: theia-base:local additional_contexts: base-ide: "service:base-ide" depends_on: - base-ide ports: - "30XX:3000"
-
Add a matrix entry to
.github/workflows/build.ymlunder thebuild-and-pushjob so CI publishes the image. -
Test locally before opening a PR:
docker compose -f docker-compose.images.yml build <lang> docker compose -f docker-compose.images.yml up <lang> # open http://localhost:30XX/ and verify the IDE starts and the language tools work
All @theia/* packages must stay in sync. Use the provided script:
yarn update:theia <new-version>
# example:
yarn update:theia 1.69.0Then rebuild and test locally before pushing.
The GitHub Actions workflow (.github/workflows/build.yml) runs on every pull request, push to main, and release:
- PRs produce images tagged
pr-<number>andpr-<number>-<sha>— useful for review testing. mainproduceslatestandlatest-<sha>.- Releases produce a semver tag and a SHA-tagged variant.
The base-ide image is always built first. All language images are built in parallel afterwards, receiving BASE_IDE_TAG as a build argument so they pull the matching base.
Arm64 builds are included for all events except PRs (to keep PR feedback fast).
"Theia" is a trademark of the Eclipse Foundation — https://www.eclipse.org/theia