Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenModelica build-deps Docker Images

Build, Release & Publish

The Docker images used to build and deploy OpenModelica with Jenkins.

Images are published to:

  • ghcr.io/openmodelica/build-deps (GitHub Container Registry)
  • docker.openmodelica.org/build-deps (Nexus)

Structure of the Repository

Every image lives on main, keyed by operating system and OS version rather than by OpenModelica version. Each image is a base plus optional, layered add-ons, so the heavy common tooling is built once and reused.

main
├── apt/
│   └── Dockerfile          # multi-stage: all Ubuntu + Debian versions + add-ons
├── apk/
│   └── Dockerfile          # multi-stage: Alpine Linux + add-ons
├── rpm/
│   └── Dockerfile          # multi-stage: AlmaLinux, RHEL, Fedora
├── pacman/
│   └── Dockerfile          # placeholder (not implemented yet)
└── .ci/
    ├── matrix.yml          # source of truth: which images exist
    ├── matrix.py           # matrix.yml -> CI matrix / tag lookup
    ├── build.sh            # build one image (base + add-ons), write GHA cache
    └── publish.sh          # restore GHA cache, push + sign one image
  • Base image — one per OS/OS-version. Contains everything needed to build OpenModelica (distro packages + common tooling: TeX, Qt, Python venv, ccache, …). This is what most CI jobs use.
  • Add-on image — the base plus one thing the distro package manager can't provide or that needs a pinned version (e.g. CMake 4). Realized as an extra build stage (FROM the base stage) in the same Dockerfile, so shared layers are reused from cache.

Ubuntu and Debian share apt/Dockerfile. The DISTRO and VERSION build-args select the base image; the Qt package set is picked from ${ID}:${VERSION_ID} at build time. The base image is the full stage; each add-on is a further stage (e.g. --target cmake-4).

Each image's context, dockerfile, target, build_args and addons (add-on stage names) are declared in .ci/matrix.yml.

To add a new image, create or extend the OS's Dockerfile and list it in .ci/matrix.yml (a new version of an existing OS needs only a matrix entry).

Image naming & tags

One image repository per registry; OS, version and variant are encoded in the tag:

Tag Mutable? Meaning
ubuntu-24.04 moving Latest base image for Ubuntu 24.04
ubuntu-24.04-2.1.0 immutable Pinned base, synthesized from git tag v2.1.0
ubuntu-24.04-cmake-4 moving Latest CMake 4 add-on on the 24.04 base
ubuntu-24.04-cmake-4-2.1.0 immutable Pinned add-on, synthesized from git tag v2.1.0

Releasing is done by pushing a single repo-wide git tag v<MAJOR>.<MINOR>.<PATCH> (e.g. v2.1.0). CI synthesizes the per-image immutable Docker tags from it and publishes all images in one run. Day-to-day CI uses the moving tag; when an OpenModelica release needs a frozen environment it pins the immutable tag.

Currently provided images

OS / version Base tag Add-ons Dockerfile
Ubuntu 26.04 (Resolute) ubuntu-26.04 rust, debug, omsimulator apt/Dockerfile
Ubuntu 24.04 (Noble) ubuntu-24.04 cmake-4, debug, omsimulator apt/Dockerfile
Ubuntu 22.04 (Jammy) ubuntu-22.04 debug, omsimulator apt/Dockerfile
Debian 13 (Trixie) debian-13 cmake-4, debug apt/Dockerfile
Debian 12 (Bookworm) debian-12 cmake-4, debug apt/Dockerfile
Alpine 3.24 alpine-3.24 omsimulator apk/Dockerfile
AlmaLinux 10 almalinux-10 rpm/Dockerfile
AlmaLinux 9 almalinux-9 rpm/Dockerfile
Fedora 44 fedora-44 rpm/Dockerfile
Fedora 43 fedora-43 rpm/Dockerfile

Build locally

Base image — pick the distro and version with DISTRO and VERSION:

# Ubuntu
docker build --pull --no-cache \
  --target full \
  --build-arg DISTRO=ubuntu --build-arg VERSION=24.04 \
  --tag build-deps:ubuntu-24.04 \
  apt

# Debian
docker build --pull --no-cache \
  --target full \
  --build-arg DISTRO=debian --build-arg VERSION=13 --build-arg INTEL_OCL_PKGS= \
  --tag build-deps:debian-13 \
  apt

Add-on image — build the add-on's stage with --target. It reuses the base's cached layers, so it only adds the extra step:

docker build --pull \
  --target cmake-4 \
  --build-arg DISTRO=ubuntu --build-arg VERSION=24.04 \
  --tag build-deps:ubuntu-24.04-cmake-4 \
  apt

Alpine uses the separate apk/Dockerfile context. Alpine has no OpenModelica apk repo, so the build dependencies are installed directly; the only build-arg is VERSION (the Alpine release):

# Base image (the `full` stage)
docker build --pull --no-cache \
  --target full \
  --build-arg VERSION=3.24 \
  --tag build-deps:alpine-3.24 \
  apk

# OMSimulator add-on (reuses the base's cached layers)
docker build --pull \
  --target omsimulator \
  --build-arg VERSION=3.24 \
  --tag build-deps:alpine-3.24-omsimulator \
  apk

Enterprise Linux (AlmaLinux, RHEL) and Fedora share rpm/Dockerfile. DISTRO and VERSION select the base image; EPEL/CRB, Qt5/Qt6, autoconf 2.7x and gcc-toolset are picked from ID/PLATFORM_ID at build time:

# AlmaLinux
docker build --pull --no-cache \
  --target full \
  --build-arg DISTRO=almalinux --build-arg VERSION=10 \
  --tag build-deps:almalinux-10 \
  rpm

# Fedora
docker build --pull --no-cache \
  --target full \
  --build-arg DISTRO=fedora --build-arg VERSION=44 \
  --tag build-deps:fedora-44 \
  rpm

The values to pass (context, --file, --target, --build-arg) for any image are exactly its fields in .ci/matrix.yml.

CI workflow

A single workflow, build.yml, runs the whole pipeline so that a release it creates can publish in the same run (a release created with GITHUB_TOKEN cannot trigger a separate workflow):

discover ─▶ build (all images, no push)
              └─▶ release (tag only) ─▶ publish-ghcr + publish-nexus
  • build — on every push/PR to main (and as the gate before release), builds every base + add-on declared in .ci/matrix.yml (no push).
  • release — on an repo-wide release tag, creates/updates the GitHub Release.
  • publish-ghcr / publish-nexus — build and push the images to GHCR and Nexus. Moving tags (<os>-<version>) are updated on every push to main, the weekly schedule, and workflow_dispatch. Immutable tags (<os>-<version>-<semver>) are pushed on a release tag, and can also be republished via workflow_dispatch when a global v<semver> is supplied. On GHCR the immutable tags are cosign-signed — only on releases (and optionally on workflow_dispatch re-publishes of a release); the moving tag of a released image points at the same digest, so it verifies with the same signature.

A second workflow, cleanup.yml, deletes stale versions of the GHCR package: untagged digests left behind by re-pushed moving tags and orphaned cosign sha256-* signature tags whose image is gone. It keeps all tagged images, anything still referenced by them, and signatures of existing images. It runs automatically after every successful GHCR publish and can also be triggered manually, where it defaults to a dry run — inspect the log, then re-run it with dry-run unchecked. Note that superseded digests are pruned right after each publish, so pulling a moving tag's previous image by digest is not supported.

Releasing a new image version

See RELEASING.md for the step-by-step process.

License

The original Dockerfile was taken from OpenModelica/OpenModelicaBuildScripts. See LICENSE.md.

About

OpenModelica build-deps Docker Image

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages