Building a Hardened, Containerized CI/CD Pipeline - 1

Renesas ARM Cortex-M Firmware using GitLab and Docker

Posted by yuanhang on June 02, 2026

Modern firmware development demands the same rigor, repeatability, and speed as cloud-native software engineering. Relying on local, vendor-specific IDEs for compilation introduces the classic "it works on my machine" anti-pattern.

To bridge this gap, this article walks through a production-grade, 4-step implementation to architect, deploy, and automate a dedicated GitLab CI/CD pipeline tailored for Renesas Synergy / ARM Cortex-M architectures.

Using Agile milestones, we structured this transformation into four discrete, actionable phases:

  1. Infrastructure Deployment: Launching a containerized GitLab Runner via Docker Compose.

  2. Runner Provisioning: Securely registering the runner with specialized hardware routing tags.

  3. Toolchain Containerization: Automating the build of a standardized GCC cross-compiler Docker image.

  4. Pipeline Orchestration: Configuring a sequential 3-stage (lintbuildtest) verification pipeline.

Phase 1: Deploying a Shared GitLab Runner via Docker Compose

To maintain a clean host system and ensure configuration predictability, the GitLab Runner is deployed as a containerized service using Docker Compose. This treats our build infrastructure strictly as code (IaC).

Host Infrastructure Configuration

We start by ensuring our dedicated Docker network exists on the host machine to allow isolated, secure communication:

docker network create gitlab-network

Next, we create the configuration tracking directory on the host (/srv/gitlab-runner/config) and define our docker-compose.yml.

version: '3.8'
services:
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    container_name: gitlab-runner
    restart: always
    networks:
      - gitlab-network
    volumes:
      - /srv/gitlab-runner/config:/etc/gitlab-runner
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
       - TZ=Europe/Berlin
     extra_hosts:
      - "gitlab-tae.zofre.de:host-gateway" # the key step: map the gitlab domain to bridge gateway of Docker in host server
networks:
  gitlab-network:
    external: true

 

💡 Key Architectural Choices

  • /var/run/docker.sock Mount: Maps the host's Docker daemon into the runner container. This enables the Docker Executor to spawn sibling containers dynamically for execution workloads.

  • extra_hosts Routing: Maps our internal self-hosted GitLab instance domain (gitlab-tae.zofre.de) directly to the host's bridge gateway (host-gateway), ensuring worker containers bypass external routing hoops.

To start the background service and verify its persistent runtime status:

docker compose up -d
docker compose ps