commit 2130d099b19f627010687a723c456cabc44989c6 Author: nerpa Date: Mon Sep 14 11:01:34 2026 +0300 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f1703eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.env +.docker +*.pem +docker-compose.yaml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a2a2414 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM docker.gitea.com/runner-images@sha256:fd911d7417bfbf0f454530e447da95b58001e1df41bbc5e1a8dd35d432575aae + +COPY gitea-ca.pem /usr/local/share/ca-certificates/gitea-ca.crt +RUN update-ca-certificates + +ENV NODE_OPTIONS="--use-system-ca" + +# 192.168.1.33 is static Gitea address +RUN git config --system url."https://192.168.1.33/gitea/".insteadOf "https://192.168.1.33/" + +RUN apt-get update && \ + apt-get install -y --no-install-recommends openjdk-17-jdk-headless && \ + rm -rf /var/lib/apt/lists/* + +ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +ENV PATH="${JAVA_HOME}/bin:${PATH}" diff --git a/cache/.gitkeep b/cache/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.template b/docker-compose.template new file mode 100644 index 0000000..12f1b7f --- /dev/null +++ b/docker-compose.template @@ -0,0 +1,2 @@ +services:$cache_server$runners$xray +volumes: $volumes \ No newline at end of file diff --git a/gen.py b/gen.py new file mode 100644 index 0000000..5e2e521 --- /dev/null +++ b/gen.py @@ -0,0 +1,154 @@ +from string import Template +import argparse + +CACHE_SERVER_TEMPLATE = """ + cache-server: + image: $gitea_image + entrypoint: ["/usr/local/bin/gitea-runner"] + command: ["cache-server", "-c", "/config.yaml"] + environment: + HTTP_PROXY: socks5://$proxy:10808 + HTTPS_PROXY: socks5://$proxy:10808 + ALL_PROXY: socks5://$proxy:10808 + NO_PROXY: localhost,127.0.0.1,192.168.1.33,192.168.1.90,$proxy,xray + ports: + - "8088:8088" + volumes: + - ./cache/config.yaml:/config.yaml + - ./.docker/cache-data:/data + - ./.docker/secrets/cache.key:/secrets/cache.key:ro + restart: unless-stopped""" + +RUNNER_TEMPLATE = """ + runner-$runner_id: + image: $gitea_image + environment: + CONFIG_FILE: /config.yaml + GITEA_INSTANCE_URL: "$${INSTANCE_URL:?INSTANCE_URL is required}" + GITEA_RUNNER_REGISTRATION_TOKEN: "$${REGISTRATION_TOKEN:?TOKEN is required}" + GITEA_RUNNER_NAME: "big-runner-1" + GITEA_RUNNER_INSECURE: true + HTTP_PROXY: socks5://$proxy:10808 + HTTPS_PROXY: socks5://$proxy:10808 + ALL_PROXY: socks5://$proxy:10808 + NO_PROXY: localhost,127.0.0.1,192.168.1.33,192.168.1.90,$proxy,xray + tmpfs: + - /tmp:size=3G,exec + volumes: + - ./runner/config.yaml:/config.yaml + - ./.docker/runner-data-$runner_id:/data + - ./.docker/secrets/cache.key:/secrets/cache.key:ro + - /run/docker-$runner_id.sock:/var/run/docker.sock + - go-cache-$runner_id:/root/.cache/go-build + - go-mod-$runner_id:/root/go/pkg/mod + restart: unless-stopped""" + +XRAY_TEMPLATE = """ + xray: + image: $xray_image + container_name: xray-runner + ports: + - "10808:10808" + volumes: + - ./xray/config.json:/usr/local/etc/xray/config.json + restart: unless-stopped""" + +VOLUME_TEMPLATE = """ + go-cache-$runner_id: + driver_opts: {type: tmpfs, device: tmpfs, o: "size=2g,exec"} + go-mod-$runner_id: + driver_opts: {type: tmpfs, device: tmpfs, o: "size=2g,exec"}""" + +GITEA_RUNNER_TEMPLATE = """ +log: + level: debug +runner: + capacity: 1 + insecure: true + labels: + - "ubuntu-latest:docker://$action_runner" +cache: + external_server: "http://$proxy:8088/" + external_secret_file: "/secrets/cache.key" +container: + options: "--add-host xray:$proxy --tmpfs /root/.cache/go-build:size=2g,exec --tmpfs /root/go/pkg/mod:size=2g,exec --tmpfs /tmp:size=3g,exec" +host: +health_check: +metrics: +""" + +GITEA_CACHE_TEMPLATE = """ +log: + level: debug +runner: +cache: + dir: "/data/actcache" + port: 8088 + external_secret_file: "/secrets/cache.key" + v2: true +container: +host: +health_check: +metrics: +""" + +def main() -> None: + parser = argparse.ArgumentParser(description="Generate docker-compose.yaml from template") + parser.add_argument("--runners", type=int, default=3, help="Number of runners to generate (default: 3)") + parser.add_argument("--gitea-image", type=str, default="gitea/runner@sha256:ae746f2d74e43d853c8b2eb426dee3cc99717a144868dadf969e585b81f24534", help="Gitea runner image") + parser.add_argument("--xray-image", type=str, default="192.168.1.33/rkp/xray-core-awg:26.7.28-awg1", help="Xray image") + parser.add_argument("--action-runner", type=str, default="192.168.1.90/gitea/runner:ubuntu-latest-self-ca", help="Gitea Actions runner image") + parser.add_argument("--runner-config-template", type=str, default="runner/config.yaml", help="Runner config template file name") + parser.add_argument("--proxy", type=str, default="192.168.1.91", help="Proxy server address") + parser.add_argument("--output", type=str, default="docker-compose.yaml", help="Output file name") + parser.add_argument("--template", type=str, default="docker-compose.tmpl.yaml", help="Template file name") + parser.add_argument("--dry-run", action="store_true", help="Print the generated docker-compose.yaml to stdout instead of writing to file") + args = parser.parse_args() + + gitea_image = args.gitea_image + xray_image = args.xray_image + runners_n = args.runners + proxy = args.proxy + + cache_server = Template(CACHE_SERVER_TEMPLATE) + rendered_cache_server = cache_server.substitute(gitea_image=gitea_image, proxy=proxy) + runner = Template(RUNNER_TEMPLATE) + rendered_runners = "".join( + runner.substitute(gitea_image=gitea_image, runner_id=i, proxy=proxy) for i in range(1, runners_n + 1) + ) + volume = Template(VOLUME_TEMPLATE) + rendered_volumes = "".join( + volume.substitute(runner_id=i) for i in range(1, runners_n + 1) + ) + xray = Template(XRAY_TEMPLATE) + rendered_xray = xray.substitute(xray_image=xray_image) + with open(args.template, "r") as f: + content = f.read() + + docker_compose_template = Template(content) + rendered_docker_compose = docker_compose_template.substitute( + cache_server=rendered_cache_server, + runners=rendered_runners, + volumes=rendered_volumes, + xray=rendered_xray + ) + + gitea_runner_config = Template(GITEA_RUNNER_TEMPLATE) + rendered_gitea_runner_config = gitea_runner_config.substitute(action_runner=args.action_runner, proxy=proxy) + + if args.dry_run: + print(rendered_docker_compose) + print("-" * 40) + print(rendered_gitea_runner_config) + else: + with open(args.output, "w") as f: + f.write(rendered_docker_compose) + + with open("runner/config.yaml", "w") as f: + f.write(rendered_gitea_runner_config) + + with open("cache/config.yaml", "w") as f: + f.write(GITEA_CACHE_TEMPLATE) + +if __name__ == "__main__": + main() diff --git a/runner/.gitkeep b/runner/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/systemd/containerd@.service b/systemd/containerd@.service new file mode 100644 index 0000000..ddfb8e2 --- /dev/null +++ b/systemd/containerd@.service @@ -0,0 +1,24 @@ +# /etc/systemd/system/containerd@.service +[Unit] +Description=containerd (instance %i) +After=network-online.target local-fs.target +Wants=network-online.target + +[Service] +Type=notify +ExecStart=/usr/bin/containerd \ + --root /var/lib/containerd-%i \ + --state /run/containerd-%i \ + --address /run/containerd-%i/containerd.sock +Delegate=yes +KillMode=process +Restart=always +RestartSec=5 +LimitNOFILE=infinity +LimitNPROC=infinity +LimitCORE=infinity +TasksMax=infinity +OOMScoreAdjust=-999 + +[Install] +WantedBy=multi-user.target diff --git a/systemd/docker@.service b/systemd/docker@.service new file mode 100644 index 0000000..2195c07 --- /dev/null +++ b/systemd/docker@.service @@ -0,0 +1,34 @@ +# /etc/systemd/system/docker@.service +[Unit] +Description=Docker Application Container Engine (instance %i) +Documentation=https://docs.docker.com +After=network-online.target containerd@%i.service +Requires=containerd@%i.service +Wants=network-online.target + +[Service] +Type=notify +ExecStartPre=-/sbin/ip link add name docker%i type bridge +ExecStartPre=-/sbin/ip link set docker%i up +ExecStart=/usr/bin/dockerd \ + --host=unix:///run/docker-%i.sock \ + --data-root=/var/lib/docker-%i \ + --exec-root=/run/docker-%i \ + --pidfile=/run/docker-%i.pid \ + --containerd=/run/containerd-%i/containerd.sock \ + --exec-opt native.cgroupdriver=systemd \ + --bridge=docker%i \ + --default-address-pool base=10.%i.0.0/16,size=24 +ExecReload=/bin/kill -s HUP $MAINPID +LimitNOFILE=infinity +LimitNPROC=infinity +LimitCORE=infinity +TasksMax=infinity +TimeoutStartSec=0 +KillMode=process +Restart=on-failure +StartLimitBurst=3 +StartLimitInterval=60s + +[Install] +WantedBy=multi-user.target