← Back 02

Architectural Topology: Independent Execution Stack

May 2026 · Part 2 of 5: Mapping the New CI/CD Infrastructure

Structural Dependency Analysis (Legacy vs. Target States)

1. Legacy Managed Service Architecture (GitHub-Centric)

In the legacy configuration, the orchestration lifecycle was completely dependent on external service providers. Source code hosting, pipeline execution, and container image storage were centralized within a single third-party infrastructure layer.

github.com source
GitHub Actions runners
GHCR ghcr.io
deploy external pull
GKE Cluster
backend frontend

Under this model, engineering visibility was limited to the target Kubernetes cluster layer. Upstream infrastructure degradation—such as runner queue latency, container registry packet loss, or unacknowledged webhook drops—halted the delivery pipeline. Direct system diagnostics were blocked due to the lack of underlying host access, leaving engineering dependent on external status indicator boards.

2. Target Self-Hosted Topology (Forgejo on GKE)

The refactored state decouples compilation and deployment dependencies from external hosting providers. Source tracking shifts to Codeberg, while execution and artifact management transition to internal network boundaries.

codeberg.org source
Forgejo Runner on GKE
runner 1CPU / 1.5Gi DinD 6CPU / 6Gi
GAR GCP
deploy internal push
K8s secrets from Codeberg org
GKE Cluster
staging pods production pods

The runtime runner, network paths, and container registry reside within the same Google Cloud Platform (GCP) regional IAM boundary. Cryptographic strings transition directly from Codeberg organizational definitions into cluster-native Kubernetes secrets, eliminating intermediary routing services. System anomalies are diagnosed directly through cluster log aggregators, removing dependency on third-party support ticket queues.

Node Pool Resource Allocation Matrix

The underlying compute architecture partitions processing workloads across three distinct Google Kubernetes Engine (GKE) node pools to enforce scheduling isolation and control monthly operational expenditures.

Node Pool NamespaceVirtual Machine TypePreemption Model (Spot)Autoscaling Limits (Min / Max)Operational Workspace PurposeEstimated Cost (Monthly)
ci-spot-poole2-highcpu-8 (8 vCPU / 8 GB)Enforced (Yes)0 / 3Execution of CI runner daemons~$3.00
staging-spot-poole2-standard-2 (2 vCPU / 8 GB)Enforced (Yes)0 / 2Staging environment workloads~$7.00
production-pool-8gbe2-standard-2 (2 vCPU / 8 GB)Standard (No)2 / 4Production-grade cluster layer~$48.00

Runner Container Specifications

The execution engine runs as an isolated pod containing two tightly coupled, co-scheduled service layers. Resource constraints are explicitly defined to optimize memory allocations and prevent host-level node resource exhaustion.

Scheduling Invariant Constraints

The runner pod manifest enforces specific runtime placement boundaries via strict Kubernetes scheduling instructions:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: cloud.google.com/gke-nodepool
          operator: In
          values:
          - ci-spot-pool
tolerations:
- key: "ci-workload"
  operator: "Exists"
  effect: "NoSchedule"

The execution limit is capped at a maximum of two concurrent pipeline instances. Expanding concurrency parameters beyond this threshold on highly volatile spot compute instances increases the mathematical probability of node preemption events mid-transaction.

Job Graph & Lifecycle Timeline

The execution pipeline maps to a directed acyclic graph (DAG) divided into three distinct execution barriers. Automated deployment phases trigger immediately upon code delivery to the target repository tracking branch.

Phase 1 · Validation
lint-backend ~3 min
test-backend 8 workers · ~7 min
test-frontend ~2 min
Phase 2 · Compilation
build-backend ~3 min
build-frontend ~2 min
Phase 3 · Delivery
deploy-staging ~3 min

The total duration from delivery notification to staging cluster update spans between 12 and 15 minutes. This execution speed is maintained by leveraging heavily multicore spot instances configured to minimize platform overhead costs.

Execution Window Metrics

Phase LayerFunctional Target StepEstimated Processing Window
Phase 1: Validationlint-backend~3 min
Phase 1: Validationtest-backend (8 parallel workers)~7 min
Phase 1: Validationtest-frontend~2 min
Phase 2: Compilationbuild-backend~3 min
Phase 2: Compilationbuild-frontend-staging~2 min
Phase 3: Deliverydeploy-staging~3 min
← Why We Left GitHub Next: What Broke →