Gitea is an open source git GUI, CI/CD, project management, documenation, package repository in one alternative for Github.
It’s open core and can run locally meaning no need to pay for extra ci/cd runner minutes

Installation

Installation can easily be done in a docker container:
Heres my configuration for docker swarm deployment
This includes default passwords and usernames it’s best practice to change them

version: "3"
networks:
  gitea:
    driver: overlay
services:
  gitea:
    image: docker.gitea.com/gitea:1.24.3
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=db:5432
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=gitea
    restart: always
    networks:
      - gitea
    volumes:
      - /nfs/cluster/gitea:/data
      - /etc/timezone:/etc/timezone:syd
      - /etc/localtime:/etc/localtime:syd
    ports:
      - "5001:3000"
      - "222:22"
 
  db:
    image: docker.io/library/postgres:17
    restart: always
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=gitea
      - POSTGRES_DB=gitea
    networks:
      - gitea
    volumes:
      - /nfs/cluster/postgres:/var/lib/postgresql/data

Adding gitea runners:

version: "3"
services:
  gitea_runner:
    image: docker.io/gitea/act_runner:latest
    environment:
      CONFIG_FILE: /config.yaml
      GITEA_INSTANCE_URL: "https://git.***.net"
      GITEA_RUNNER_REGISTRATION_TOKEN: "TOKEN"
      GITEA_RUNNER_NAME: "linuxRunner"
    volumes:
      - /nfs/cluster/gitearunner/config/config.yaml:/config.yaml
      - /nfs/cluster/gitearunner/data:/data
      - /var/run/docker.sock:/var/run/docker.sock

Make sure to generate the config file using the command
docker run --entrypoint="" --rm -it docker.io/gitea/act_runner:latest act_runner generate-config > config.yaml

Inside the config.yaml is the labels specifying which containers can be ran inside

log:
  # The level of logging, can be trace, debug, info, warn, error, fatal
  level: info
runner:
  # Where to store the registration result.
  file: .runner
  # Execute how many tasks concurrently at the same time.
  capacity: 1
  # The labels of a runner are used to determine which jobs the runner can run, and how to run them.
  # Like: "macos-arm64:host" or "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
  # Find more images provided by Gitea at https://gitea.com/docker.gitea.com/runner-images .
  labels:
    - "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
    - "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"
    - "ubuntu-20.04:docker://docker.gitea.com/runner-images:ubuntu-20.04"
    - "debian-latest:docker://docker.io/debian:bullseye-slim"

Labels is the main section specifying the available images to run actions on