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.
Minimal config for applicative projects
Section titled “Minimal config for applicative projects”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.
Dockerfile pattern
Section titled “Dockerfile pattern”ARG BASE_IMAGEFROM ${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:
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 example
Section titled “GitLab CI example”# .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 currentcheck-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 imagebuild: 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 buildregister: 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_TAGGitea Actions example
Section titled “Gitea Actions example”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 }}Keeping BASE_IMAGE up to date
Section titled “Keeping BASE_IMAGE up to date”-
Use a fixed variable — define
BASE_IMAGEas a CI variable. Update it whenever a new base image is published. Thecheck-basejob will catch outdated values before they ship. -
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. -
Fail fast with
--strict— with--strict,check-basefails if the base is outdated. Teams must updateBASE_IMAGEto unblock their release.
Without --strict
Section titled “Without --strict”If --strict is too aggressive initially, use the default mode (warn, don’t fail):
imglife check --base "$BASE_IMAGE"# Exits 0 always, but logs warnings for outdated/EOL basesThis gives teams visibility into the status without blocking releases.
Custom fields in build records
Section titled “Custom fields in build records”Add any useful metadata to the build record:
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.