GitLab Runners - Oracle Centralization
GitLab Runners — Oracle Centralization
Status: Production — ALL 123 repos route to Oracle self-hosted runners CI Minutes Used: ZERO (self-hosted runners only) Group: blueflyio (ID: 87749026)
Architecture
All CI/CD jobs across the blueflyio GitLab organization run on self-hosted Oracle runners. Shared (SaaS) runners are disabled and unoverridable at the group level.
Active Runners
| Runner | ID | Executor | Tags | Concurrency | Purpose |
|---|---|---|---|---|---|
| Oracle Docker Runner (ARM64) | 52006808 | Docker | oracle, local | 5 | Build, test, lint, scan |
| Oracle Shell Runner | 51772781 | Shell | oracle-vm, oracle-deploy | 2 | Host-level deploys (pm2, docker, kubectl) |
Decommissioned
- Local Mac runners (7 runners on 2 Macs) — Removed. All work moved to Oracle.
- GitLab SaaS shared runners — Disabled at group level (
disabled_and_unoverridable).
How It Works
Three entry-point components ensure ALL jobs get the oracle tag:
1. [object Object] Component
# templates/base-runner/template.yml default: tags: - oracle .base-runner: tags: - oracle allow_failure: false
Used by: ~14 repos via minimal-ci, plus repos that explicitly include it.
Include: - component: $CI_SERVER_FQDN/blueflyio/agent-platform/tools/gitlab_components/base-runner@release/v0.1.x
2. [object Object] Component
# templates/drupal-master/template.yml default: tags: - oracle
Used by: 28 Drupal module repos.
Include: - component: $CI_SERVER_FQDN/blueflyio/agent-platform/tools/gitlab_components/drupal-master@release/v0.1.x
3. [object Object] Component
# templates/golden/template.yml default: tags: - ${CI_USE_LOCAL_RUNNERS}
Used by: 3 repos.
CI_USE_LOCAL_RUNNERS is set to oracle at the group level.
How [object Object] Propagates
The default: keyword in GitLab CI applies to ALL jobs in the pipeline that don't explicitly set their own tags:. When a component includes default: tags: [oracle], every job — including Auto DevOps template jobs (SAST, dependency scanning, code_quality, secret detection) — inherits the oracle tag.
Group Variables
| Variable | Value | Purpose |
|---|---|---|
CI_USE_LOCAL_RUNNERS | oracle | Used by golden template's default tags |
GITLAB_COMPONENTS_VERSION | release/v0.1.x | Component version ref for consumer repos |
DRUPAL_SIMPLE_VERSION | release/v0.1.x | Drupal simple component version ref |
Set at: https://gitlab.com/groups/blueflyio/-/settings/ci_cd → Variables
Coverage
| Category | Count | Entry Point |
|---|---|---|
| NPM/TypeScript repos | ~14 | base-runner (via minimal-ci or golden) |
| Drupal module repos | 28 | drupal-master |
| Platform service repos | ~7 | base-runner (explicit include) |
| OSSA repos | 2 | explicit default: tags: [oracle] in .gitlab-ci.yml |
| No CI (inactive/deletion) | 28 | N/A |
| Total | 123 | |
| Stuck pipelines | 0 |
Deploy Jobs
Jobs that need host-level access (pm2, docker, kubectl) use the Shell executor:
deploy:oracle: tags: - oracle-deploy # Shell executor on Oracle VM
The oracle-deploy and oracle-vm tags route to the Oracle Shell Runner (ID: 51772781).
Troubleshooting
Job stuck "pending"
- Shared runners are disabled. The job MUST have a tag matching an active runner.
- Check:
tags:in job definition or inherited fromdefault:/extends:. - Fix: Ensure the repo's CI includes one of the three entry-point components.
Auto DevOps template jobs stuck
- GitLab's built-in templates (SAST, dependency scanning, etc.) don't use
.base-runner. - They rely on
default: tags:to inherit the oracle tag. - Fix: Ensure
default: tags: [oracle]exists in the pipeline config.
Empty [object Object] key
- An explicit
tags:with no value overridesdefault:and results intags=[]. - Fix: Either remove the empty
tags:key or add- oracleunder it.
Maintenance
Adding a new repo
- Include one of:
base-runner,drupal-master, orgoldencomponent. - Or add
default: tags: [oracle]to the repo's.gitlab-ci.yml. - Trigger a pipeline and verify all jobs show
tags=['oracle'].
Runner health
# Check runner status via API curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "https://gitlab.com/api/v4/runners/52006808" | jq '{status, active, description, tag_list}'
Verify no stuck pipelines
# Scan all repos for jobs with empty tags # (This was automated during the 2026-02-28 centralization)