Implement gitlab-runner helper concrete image variant

Create a new "concrete" base image that has a portable git distribution.

Problem

We need a git binary that runs on any Linux distribution — from minimal busybox/scratch containers to FIPS-mandated enterprise environments like RHEL 8/9. The challenges:

  1. No guaranteed system dependencies — target environments may have no shell, no package manager, no shared libraries at all
  2. FIPS compliance — on regulated systems, we must use the host's FIPS-validated OpenSSL rather than shipping our own
  3. OpenSSL ABI split — OpenSSL 1.1 and 3.x are binary-incompatible (different sonames), and both are actively deployed (RHEL 8 ships 1.1, RHEL 9+ ships 3.x)
  4. Multi-architecture — must support amd64, arm, arm64, s390x, ppc64le, and riscv64

Approach

We build git once and bundle everything it needs to run, with runtime detection to adapt to the host environment.

Bundled glibc and dependencies

Rather than statically linking (which prevents using host OpenSSL) or depending on the host's libc (which varies across distros), we ship our own glibc, libcurl, libz, libpcre2, etc. alongside git. A bundled ld-linux dynamic linker loads these via --library-path, making the installation fully relocatable.

Single git binary, two libcurls

Git itself never touches OpenSSL directly. The dependency chain is git → git-remote-https → libcurl → libssl. Since only libcurl has a direct OpenSSL dependency, we ship two copies of libcurl.so.4: one linked against OpenSSL 3.x (from the system package) and one built from source against OpenSSL 1.1. Everything else is shared.

Static Go wrapper

Each git ELF binary is renamed to git.real and replaced by a small, fully static Go binary (no libc dependency at all). At runtime, the wrapper:

  • Checks /etc/ld.so.cache and common library paths to detect the host's OpenSSL version
  • Selects the appropriate --library-path to load the right libcurl
  • Sets GIT_EXEC_PATH and GIT_TEMPLATE_DIR relative to its own location
  • Invokes the bundled ld-linux with --argv0 to preserve multicall dispatch

Runtime behavior

Host environment libcurl used OpenSSL used FIPS?
Has OpenSSL 3.x Bundled (ossl3) Host's libssl.so.3 Yes, if host is FIPS
Has OpenSSL 1.1 Bundled (ossl1) Host's libssl.so.1.1 Yes, if host is FIPS
No OpenSSL Bundled (ossl3) Bundled libssl.so.3 No

Size optimizations

  • All ELF binaries and shared libraries are stripped
  • Git built with NO_PERL, NO_PYTHON, NO_GITWEB, NO_GETTEXT, NO_TCLTK
  • Duplicate binaries in libexec/git-core/ (git's multicall pattern) are symlinked rather than copied
  • Unnecessary templates, hooks, and mergetools removed

Git LFS

Included as a pre-built static binary from the official releases. No wrapper needed since it has zero runtime dependencies.

Future: dropping OpenSSL 1.1 support

When RHEL 8 reaches EOL (2029) or is no longer a target, removing 1.1 support is a clean cut:

  1. Delete lib/ossl1-curl/ from the distribution
  2. Remove the OpenSSL 1.1 and curl-from-source build steps from the Dockerfile
  3. Remove the "1.1" case from the Go wrapper

No git rebuild required.

Relates to gitlab-org/gitlab-runner#39286 (closed)

Edited by Arran Walker

Merge request reports

Loading