Skip to content

App CI Integration

Applicative teams interact with imglife through two commands:

  • imglife check — verify that their base image is current before building.
  • imglife register — record the build in the Package Registry after pushing.

Neither command requires access to the full imglife.yaml from the base-images project. Applicative projects only need a minimal config pointing to the Package Registry.

Create imglife.apps.yaml (or similar) in the applicative project:

# imglife.apps.yaml — applicative project config
# Only the registry section is needed.
registry:
url: https://gitlab.example.com
project_id: 42 # base-images project ID (for check auto-derive)

This gives imglife access to the base-images Package Registry to fetch the latest base version and EOL data.

ARG BASE_IMAGE
FROM ${BASE_IMAGE}
# ... your application layers ...

Pass BASE_IMAGE as a build argument. This allows CI to control which base image version is used and enables imglife check to read the OCI label:

Terminal window
docker build \
--build-arg BASE_IMAGE=registry.example.com/bases/alpine:3.21.3-core1.0.0 \
-t registry.example.com/apps/myservice:1.2.0 \
.

imglife build injects org.opencontainers.image.base.name as an OCI label, which imglife register uses to auto-detect the base.

# .gitlab-ci.yml — applicative project
variables:
BASE_IMAGE: registry.example.com/bases/alpine:3.21.3-core1.0.0
IMGLIFE_CONFIG: imglife.apps.yaml
stages:
- check
- build
- register
# Verify base image is current
check-base:
stage: check
image: registry.gitlab.com/imglife-project/imglife:latest
script:
- |
imglife check \
--base "$BASE_IMAGE" \
--strict
rules:
- if: $CI_COMMIT_TAG
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# Build the applicative image
build:
stage: build
image: docker:26
services:
- docker:26-dind
variables:
DOCKER_TLS_CERTDIR: /certs
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
script:
- |
docker build \
--build-arg BASE_IMAGE="$BASE_IMAGE" \
--build-arg GIT_REVISION="$CI_COMMIT_SHA" \
-t "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG" \
.
docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG"
rules:
- if: $CI_COMMIT_TAG
# Record the build
register:
stage: register
image: registry.gitlab.com/imglife-project/imglife:latest
script:
- |
imglife register \
--image "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG" \
--base "$BASE_IMAGE" \
--revision "$CI_COMMIT_SHA" \
--project "$CI_PROJECT_PATH"
rules:
- if: $CI_COMMIT_TAG
.gitea/workflows/release.yml
on:
push:
tags: ["v*"]
env:
BASE_IMAGE: gitea.example.com/myorg/bases/alpine:3.21.3-core1.0.0
IMGLIFE_CONFIG: imglife.apps.yaml
jobs:
check-base:
runs-on: ubuntu-latest
container:
image: registry.gitlab.com/imglife-project/imglife:latest
steps:
- uses: actions/checkout@v4
- run: imglife check --base "$BASE_IMAGE" --strict
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
build-push:
needs: check-base
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: gitea.example.com
username: ${{ gitea.actor }}
password: ${{ secrets.GITEA_TOKEN }}
- run: |
docker build \
--build-arg BASE_IMAGE="$BASE_IMAGE" \
-t gitea.example.com/myorg/apps/myservice:${{ gitea.ref_name }} \
.
docker push gitea.example.com/myorg/apps/myservice:${{ gitea.ref_name }}
register:
needs: build-push
runs-on: ubuntu-latest
container:
image: registry.gitlab.com/imglife-project/imglife:latest
steps:
- uses: actions/checkout@v4
- run: |
imglife register \
--image gitea.example.com/myorg/apps/myservice:${{ gitea.ref_name }} \
--base "$BASE_IMAGE" \
--revision "${{ gitea.sha }}" \
--project "${{ gitea.repository }}"
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
  1. Use a fixed variable — define BASE_IMAGE as a CI variable. Update it whenever a new base image is published. The check-base job will catch outdated values before they ship.

  2. Automate updates — the base-images team can trigger applicative pipelines when a new base is ready. Or use a dependency bot to open MRs updating BASE_IMAGE.

  3. Fail fast with --strict — with --strict, check-base fails if the base is outdated. Teams must update BASE_IMAGE to unblock their release.

If --strict is too aggressive initially, use the default mode (warn, don’t fail):

Terminal window
imglife check --base "$BASE_IMAGE"
# Exits 0 always, but logs warnings for outdated/EOL bases

This gives teams visibility into the status without blocking releases.

Add any useful metadata to the build record:

Terminal window
imglife register \
--image "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG" \
--revision "$CI_COMMIT_SHA" \
--project "$CI_PROJECT_PATH" \
--field pipeline_url="$CI_PIPELINE_URL" \
--field deployer="$GITLAB_USER_LOGIN"

Custom fields appear in imglife app list --detailed and --output json.