Chapter 04Lesson 05~165 minutes

Checkpoint Lab — GitLab Runner Architecture, Registration, Runner Managers, Job Execution, and Lifecycle

The checkpoint provisions and retires one disposable runner end to end. You will prove exact job routing, distinguish runner configuration from runner manager, exercise pause/stop/resume states, preserve lifecycle evidence, unregister the manager, remove the runner configuration, and finish with an organizational rollout control checklist rather than leaving hidden CI infrastructure behind.

Checkpoint labProvisionRouteObserveRetire

Learning objectives

  • Provision one disposable project runner and one manager with a unique routing tag and an exact recorded Runner version.
  • Predict and verify runner/manager status changes during register, route, pause, stop, resume, unregister, and delete operations.
  • Prove one trusted job ran on the intended manager using source SHA, job ID, runner ID, manager identity where available, version, executor, and tag evidence.
  • Retire the manager and runner configuration without deleting unrelated runners or leaving reusable authentication material behind.
  • Produce an evidence packet and a concise control checklist required before scaling the pattern to group or instance scope.
Checkpoint objective. Prove the complete lifecycle of one disposable runner configuration and one manager: create → register → contact → route one trusted job → pause → resume → stop → restart → unregister manager → delete runner → destroy local state. Every step must have observable evidence and exact resource guards.

1. Scenario and acceptance boundary

You are preparing a runner pattern for a small engineering team, but before proposing group-wide rollout you must demonstrate it in a disposable project. The lab runner has no production credentials, no private-network access, no host Docker socket, no privileged containers, and accepts only a unique tagged synthetic job.

Mandatory path: GitLab Free-compatible project runner plus a local disposable manager container. If your GitLab role does not permit runner creation, complete the lifecycle as a read-only simulation using the screenshots/expected-state table and do not ask an administrator to weaken policy for the course.

2. Preflight and predictions

LAB_TAG="ch04-checkpoint"
RUNNER_NAME="ch04-checkpoint-manager"
RUNNER_CONTAINER="ch04-checkpoint-runner"
RUNNER_VOLUME="ch04-checkpoint-config"
EVIDENCE="ch04-checkpoint-evidence"
mkdir -p "$EVIDENCE"

git status --short --branch
git rev-parse HEAD | tee "$EVIDENCE/source-before.txt"
docker ps -a --filter "name=^/${RUNNER_CONTAINER}$"
docker volume ls --filter "name=^${RUNNER_VOLUME}$"

Predict before acting:

  1. The runner configuration exists before any manager contacts GitLab.
  2. After registration/start, one manager system ID becomes visible and online.
  3. Only a job requesting ch04-checkpoint can route to it because untagged jobs are disabled.
  4. Pausing blocks new jobs while the manager can remain online.
  5. Stopping the manager makes it offline while the runner can remain unpaused.
  6. Unregistering the manager does not necessarily delete the runner configuration.

3. Create and register with exact version evidence

Create a disposable project runner in GitLab with tag ch04-checkpoint, “run untagged” disabled, and a clear disposable description. Record the runner ID and settings before using the authentication token.

read -rsp "Runner authentication token: " RUNNER_AUTH_TOKEN
printf '
'

docker volume create "$RUNNER_VOLUME"

docker run --rm \
  -v "$RUNNER_VOLUME:/etc/gitlab-runner" \
  gitlab/gitlab-runner:v19.3.1 register \
  --non-interactive \
  --url "https://gitlab.com/" \
  --token "$RUNNER_AUTH_TOKEN" \
  --executor shell \
  --description "$RUNNER_NAME"

unset RUNNER_AUTH_TOKEN

docker run -d \
  --name "$RUNNER_CONTAINER" \
  --restart no \
  -v "$RUNNER_VOLUME:/etc/gitlab-runner" \
  gitlab/gitlab-runner:v19.3.1 run

docker exec "$RUNNER_CONTAINER" gitlab-runner --version

Record the manager system ID/version/platform/architecture from GitLab when visible. Do not copy config.toml into the evidence packet because it contains the runner authentication token.

4. Build the tagged identity-evidence job

stages: [inspect]

checkpoint_runner_probe:
  stage: inspect
  tags:
    - ch04-checkpoint
  script:
    - printf 'pipeline_id=%s
' "$CI_PIPELINE_ID"
    - printf 'job_id=%s
' "$CI_JOB_ID"
    - printf 'source=%s
' "$CI_PIPELINE_SOURCE"
    - printf 'sha=%s
' "$CI_COMMIT_SHA"
    - printf 'runner_id=%s
' "$CI_RUNNER_ID"
    - printf 'runner_description=%s
' "$CI_RUNNER_DESCRIPTION"
    - printf 'runner_tags=%s
' "$CI_RUNNER_TAGS"
    - printf 'runner_version=%s
' "$CI_RUNNER_VERSION"
    - printf 'runner_revision=%s
' "$CI_RUNNER_REVISION"
    - printf 'runner_arch=%s
' "$CI_RUNNER_EXECUTABLE_ARCH"
    - printf 'sha=%s
runner_id=%s
version=%s
' "$CI_COMMIT_SHA" "$CI_RUNNER_ID" "$CI_RUNNER_VERSION" > runner-proof.txt
  artifacts:
    when: always
    expire_in: 1 day
    paths: [runner-proof.txt]

Create a disposable branch/commit and run the pipeline only if authorized. Preserve the exact SHA, pipeline ID, job ID, assigned runner ID/description/version, and artifact. Confirm no other runner could satisfy the unique tag.

5. Lifecycle test A — pause and resume

Pause the runner in GitLab while leaving the manager process running. Trigger another uniquely tagged job. Record:

  • runner is paused;
  • manager can still show recent contact/online state;
  • new job remains pending;
  • job YAML and tag are unchanged.

Resume the runner and verify the pending job becomes eligible. This proves a GitLab-side scheduling-state transition without any host modification.

6. Lifecycle test B — stop and restart the manager

docker stop "$RUNNER_CONTAINER"
docker ps -a --filter "name=^/${RUNNER_CONTAINER}$"
# Wait for GitLab to reflect lack of contact; record status/time.

docker start "$RUNNER_CONTAINER"
docker logs --tail 80 "$RUNNER_CONTAINER"

Record the transition from contacted/online to offline and back, subject to GitLab status-update timing. The runner configuration remains the same object. Do not create a second runner to recover from an intentional stop.

7. Lifecycle test C — unregister manager, then delete runner configuration

docker exec "$RUNNER_CONTAINER" gitlab-runner list

docker exec "$RUNNER_CONTAINER" \
  gitlab-runner unregister --name "$RUNNER_NAME"

docker exec "$RUNNER_CONTAINER" gitlab-runner list

Verify the manager is removed/disconnected while the GitLab runner configuration can remain. Then delete that exact disposable runner configuration in the GitLab UI. Record the runner ID before deletion so the evidence proves which object was retired.

8. Remove exact local resources

docker rm -f "$RUNNER_CONTAINER" 2>/dev/null || true

docker volume inspect "$RUNNER_VOLUME" >/dev/null 2>&1 && \
  docker volume rm "$RUNNER_VOLUME"

docker ps -a --filter "name=^/${RUNNER_CONTAINER}$"
docker volume ls --filter "name=^${RUNNER_VOLUME}$"

Do not use broad docker system prune for this lab. It can remove unrelated images/containers/build cache and makes cleanup non-auditable.

9. Required evidence packet

  • Source: disposable branch/ref and exact commit SHA.
  • Runner configuration: runner ID, project scope, tag, run-untagged/protected/paused settings, creation/deletion timestamps.
  • Manager: system ID when visible, Runner v19.3.1, revision/platform/architecture, executor, first/last contact/status transitions.
  • Routing proof: pipeline ID, job ID, requested tag, assigned runner metadata and runner-proof.txt.
  • Pause evidence: pending job while manager remains available, then successful routing after resume.
  • Stop evidence: manager offline without changing runner configuration, then contact after restart.
  • Retirement: unregister result, runner deletion verification, local container/volume absence.
  • Assumptions: GitLab offering/tier/role, verification date, Runner image/version, disposable-project boundary.

10. Before organizational rollout: required controls

Control Question to answer before group/instance scope
Ownership Which team owns runner policy, patching, capacity, incident response and retirement?
Trust population Which projects/refs/users can cause code to execute on the runner?
Isolation What can one job read/write on the host, network, cache and following jobs?
Credentials Which secrets/tokens/cloud identities are reachable and how are they rotated?
Routing Are tags, untagged policy, protected refs and assignments explicit and tested?
Versioning How are Runner/helper/executor updates canaried and tracked?
Observability Where are runner-manager logs, queue/utilization metrics and system IDs retained?
Capacity/cost What are concurrency/autoscaling bounds and failure modes?
Retirement How are managers unregistered, runner configs deleted and host secrets/storage destroyed?

11. Checkpoint result and bridge to Chapter 05

You have now treated GitLab Runner as infrastructure rather than an invisible pipeline detail. You proved scope/routing, manager identity, registration/authentication, pause and process availability, exact job assignment, version state, unregister semantics, and resource retirement.

Chapter 05 moves from the runner-manager lifecycle into the executor boundary itself: Shell, Docker, Docker Autoscaler, Kubernetes, SSH, and custom execution models. The same evidence discipline carries forward, but the isolation and worker-lifecycle consequences become the main design problem.

Next lesson

Next: Runner Executors: Shell, Docker, Docker Autoscaler, Kubernetes, SSH, and Custom Execution Models: Concepts, Architecture, and Mental Model

Continue with the next lesson in the course sequence and carry forward the evidence-first GitLab CI/CD operating model.

Knowledge check

What are the two most important identities in the checkpoint evidence?

Why is “run untagged” disabled in the checkpoint?

What should happen to a new tagged job while the runner is paused but the manager remains online?

Why unregister before deleting local volume state?

What must be reviewed before converting the pattern into a group runner?

Official references and version notes

  • Runners — runner categories, job scheduling, GitLab-hosted versus self-managed runners, and execution flow.
  • Manage runners — project/group/instance scope, creation workflow, ownership and pause/resume operations.
  • Configure runners — tags, run_untagged, protected runners, authentication-token rotation, and routing behavior.
  • Registering runners and new runner creation workflow — current runner authentication-token registration and deprecated legacy registration-token behavior.
  • GitLab Runner commands — register, list, verify, run, stop, and unregister lifecycle commands.
  • Runner fleet planning — manager system_id identity and modern unregister/delete distinctions.
  • Runners API — runner details, managers, status, pause, job history, authentication-token reset, and deletion semantics.
  • Security for self-managed runners — remote-code-execution trust, Shell executor risk, persistent-runner residue, isolation, and credential exposure.
  • GitLab Runner documentation — current compatibility guidance recommends keeping Runner major.minor aligned with GitLab; GitLab.com users should keep self-managed runners current.
Version and compatibility note

Version-sensitive statements were rechecked against current primary GitLab documentation and the GitLab Runner release history on 2026-09-11. The latest stable Runner tag visible in the upstream release history at that verification point is v19.3.1 (2026-08-24); GitLab 19.4 is scheduled after this guide-authoring date, so executable examples pin gitlab/gitlab-runner:v19.3.1 instead of a moving latest tag. The legacy runner-registration-token workflow is deprecated and scheduled for removal in GitLab 20.0; this chapter uses runner authentication tokens and the modern creation workflow.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.