From e4b8d4e7106f4fef43e2fcb042899d206286aebb Mon Sep 17 00:00:00 2001 From: Patrick de Ruiter Date: Thu, 25 Dec 2025 14:14:44 +0100 Subject: [PATCH] Add Gitea Actions CI/CD pipeline and runner configuration - Add workflow for building and pushing Docker image to Nexus registry - Configure semantic versioning from git tags (v1.0.0 -> 1.0.0, latest) - Add self-hosted runner configuration with Alpine Linux support - Runner uses docker:27-cli image for Docker-in-Docker builds --- .gitea/workflows/build.yaml | 71 ++++++++++++++++++++++++++++ gitea-runner/.env.example | 8 ++++ gitea-runner/README.md | 82 +++++++++++++++++++++++++++++++++ gitea-runner/config.yaml | 57 +++++++++++++++++++++++ gitea-runner/docker-compose.yml | 30 ++++++++++++ 5 files changed, 248 insertions(+) create mode 100644 .gitea/workflows/build.yaml create mode 100644 gitea-runner/.env.example create mode 100644 gitea-runner/README.md create mode 100644 gitea-runner/config.yaml create mode 100644 gitea-runner/docker-compose.yml diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..c9808a4 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,71 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + tags: + - 'v*' + pull_request: + branches: + - main + +env: + REGISTRY: nexus.bsdserver.nl:443 + IMAGE_NAME: enterprise-openldap + +jobs: + build: + runs-on: docker + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Determine version tag + id: version + run: | + if [[ "$GITHUB_REF" == refs/tags/v* ]]; then + # Extract version from tag (v1.0.0 -> 1.0.0) + VERSION="${GITHUB_REF#refs/tags/v}" + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "TAGS=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION},${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_OUTPUT + elif [[ "$GITHUB_REF" == refs/heads/main ]]; then + # Use short SHA for main branch + SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-7) + echo "VERSION=$SHORT_SHA" >> $GITHUB_OUTPUT + echo "TAGS=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$SHORT_SHA" >> $GITHUB_OUTPUT + else + # Pull request - just use SHA + SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-7) + echo "VERSION=$SHORT_SHA" >> $GITHUB_OUTPUT + echo "TAGS=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-$SHORT_SHA" >> $GITHUB_OUTPUT + fi + + - name: Log in to Docker Registry + if: github.event_name != 'pull_request' + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build Docker image + run: | + docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} . + + - name: Tag additional versions + if: github.event_name != 'pull_request' + run: | + IFS=',' read -ra TAGS <<< "${{ steps.version.outputs.TAGS }}" + for TAG in "${TAGS[@]}"; do + docker tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} "$TAG" + done + + - name: Push Docker image + if: github.event_name != 'pull_request' + run: | + IFS=',' read -ra TAGS <<< "${{ steps.version.outputs.TAGS }}" + for TAG in "${TAGS[@]}"; do + docker push "$TAG" + done + + - name: Logout from registry + if: always() && github.event_name != 'pull_request' + run: docker logout ${{ env.REGISTRY }} || true diff --git a/gitea-runner/.env.example b/gitea-runner/.env.example new file mode 100644 index 0000000..1256213 --- /dev/null +++ b/gitea-runner/.env.example @@ -0,0 +1,8 @@ +# Get this token from Gitea: +# - Org runner: https://git.bsdserver.nl/org/wbyc/settings/actions/runners +# - Repo runner: https://git.bsdserver.nl/wbyc/docker-openldap/settings/actions/runners +# - Instance runner: Site Administration -> Actions -> Runners +GITEA_RUNNER_REGISTRATION_TOKEN=your-token-here + +# Optional: Custom runner name +GITEA_RUNNER_NAME=alpine-docker-runner diff --git a/gitea-runner/README.md b/gitea-runner/README.md new file mode 100644 index 0000000..b9a4120 --- /dev/null +++ b/gitea-runner/README.md @@ -0,0 +1,82 @@ +# Gitea Actions Runner + +This directory contains the configuration for a self-hosted Gitea Actions runner that supports Alpine Linux and Docker builds. + +## Setup + +### 1. Get a Registration Token + +Get a runner registration token from one of these locations in Gitea: + +- **Organization runner** (recommended): `https://git.bsdserver.nl/org/wbyc/settings/actions/runners` +- **Repository runner**: `https://git.bsdserver.nl/wbyc/docker-openldap/settings/actions/runners` +- **Instance runner**: Site Administration → Actions → Runners + +Click "Create new Runner" to get a token. + +### 2. Configure Environment + +```bash +cp .env.example .env +# Edit .env and set GITEA_RUNNER_REGISTRATION_TOKEN +``` + +### 3. Start the Runner + +```bash +docker compose up -d +``` + +### 4. Verify Registration + +Check that the runner appears in Gitea under the same location where you got the token. + +## Configuration + +### Labels + +The runner is configured with these labels: + +| Label | Image | Use Case | +|-------|-------|----------| +| `self-hosted` | `alpine:3.21` | Default for self-hosted jobs | +| `alpine` | `alpine:3.21` | Explicit Alpine builds | +| `docker` | `docker:27-cli` | Docker CLI with Alpine base | + +### Using in Workflows + +```yaml +jobs: + build: + runs-on: self-hosted # Uses Alpine + steps: + - uses: actions/checkout@v4 + - run: apk add --no-cache docker-cli + - run: docker build -t myimage . +``` + +## Troubleshooting + +### View Logs + +```bash +docker compose logs -f +``` + +### Re-register Runner + +If the runner fails to connect, delete and recreate: + +```bash +docker compose down -v +docker compose up -d +``` + +### Docker Socket Permissions + +If you see permission errors, ensure the Docker socket is accessible: + +```bash +ls -la /var/run/docker.sock +# Should show: srw-rw---- 1 root docker ... +``` diff --git a/gitea-runner/config.yaml b/gitea-runner/config.yaml new file mode 100644 index 0000000..19d22ef --- /dev/null +++ b/gitea-runner/config.yaml @@ -0,0 +1,57 @@ +# Gitea Actions Runner Configuration +# This file configures the act_runner to use Alpine-based images + +log: + level: info + +runner: + # Runner registration file + file: .runner + # Capacity - how many jobs can run concurrently + capacity: 2 + # Environment variables for all jobs + envs: {} + # Timeout for job execution + timeout: 3h + # Insecure mode - set to true if Gitea uses self-signed certs + insecure: false + # Fetch interval + fetch_timeout: 5s + fetch_interval: 2s + +cache: + enabled: true + dir: /data/cache + +container: + # Network mode for job containers + network: bridge + # Privileged mode - required for Docker-in-Docker builds + privileged: true + # Options for container creation + options: | + # Docker host - use mounted socket + docker_host: unix:///var/run/docker.sock + # Force pull images + force_pull: false + # Valid volumes that can be mounted + valid_volumes: + - /var/run/docker.sock + +host: + # Workdir for the runner + workdir_parent: /data/workdir + +# Label mappings - map workflow labels to container images +# This is where we define Alpine as the default +labels: + # Default self-hosted label uses Alpine with Docker + self-hosted: "docker://alpine:3.21" + # Explicit Alpine label + alpine: "docker://alpine:3.21" + # Docker label - Alpine with Docker CLI pre-installed + docker: "docker://docker:27-cli" + # For compatibility with GitHub Actions workflows + ubuntu-latest: "docker://node:20-bookworm" + ubuntu-22.04: "docker://node:20-bookworm" + ubuntu-20.04: "docker://node:20-bookworm" diff --git a/gitea-runner/docker-compose.yml b/gitea-runner/docker-compose.yml new file mode 100644 index 0000000..b390842 --- /dev/null +++ b/gitea-runner/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3.8' + +services: + gitea-runner: + image: gitea/act_runner:latest + container_name: gitea-runner + restart: unless-stopped + environment: + # Gitea instance URL + GITEA_INSTANCE_URL: https://git.bsdserver.nl + # Runner registration token (get from Gitea admin or repo settings) + GITEA_RUNNER_REGISTRATION_TOKEN: ${GITEA_RUNNER_REGISTRATION_TOKEN:?Set registration token} + # Runner name + GITEA_RUNNER_NAME: ${GITEA_RUNNER_NAME:-alpine-docker-runner} + # Runner labels - defines what jobs this runner can handle + GITEA_RUNNER_LABELS: "self-hosted,alpine,docker" + # Use custom config + CONFIG_FILE: /config.yaml + volumes: + # Mount Docker socket for building images + - /var/run/docker.sock:/var/run/docker.sock + # Mount runner configuration + - ./config.yaml:/config.yaml:ro + # Persist runner data + - gitea-runner-data:/data + # Run as root to access Docker socket (or configure Docker group) + user: "0:0" + +volumes: + gitea-runner-data: