Configuring Stable Gitea Actions: A Powerful Self-Hosted Alternative to GitHub Actions
Introduction: The Shift Toward Self-Hosted CI/CD
In the modern software development lifecycle, Continuous Integration and Continuous Deployment (CI/CD) pipelines serve as the backbone of engineering velocity. For years, GitHub Actions has been the dominant force in this space, offering a seamless, cloud-integrated automation framework. However, shifting market dynamics, escalating cloud costs, stringent data sovereignty regulations, and the absolute necessity for offline, air-gapped environments have driven enterprises to seek viable on-premises alternatives.
Enter Gitea Actions. Introduced in Gitea v1.19, Gitea Actions is a built-in CI/CD solution designed to be highly compatible with GitHub Actions workflow syntax. By using Gitea Actions, organizations can leverage their existing knowledge of YAML workflows while maintaining absolute ownership over their infrastructure, code, and execution data. This guide provides an architectural blueprint for configuring a stable, production-grade Gitea Actions environment tailored for enterprise workloads.
---Understanding the Gitea Actions Architecture
Before deploying infrastructure, it is critical to understand how Gitea Actions operates. The architecture relies on a decoupled, asynchronous execution model comprising two primary components:
- The Gitea Core Instance: Acts as the central orchestrator, parsing repository YAML workflows, managing permissions, scheduling jobs, and displaying real-time execution logs.
- act_runner: An independent, lightweight daemon process written in Go. It connects to the Gitea instance via a secure gRPC protocol, polls for available jobs, executes them inside isolated environments, and streams the results back to the master instance.
Because act_runner is based on the open-source nektos/act project, it natively understands GitHub Actions syntax. This means that transition costs are exceptionally low, as most standard workflow definitions require minimal to no modification to run seamlessly on your local hardware.
Hardware Sizing and Environment Provisioning
Achieving stability starts with proper resource allocation. Unlike centralized cloud solutions where compute scaling is abstract, a self-hosted environment demands deliberate planning. CI/CD workloads are inherently bursty; they require intense CPU and I/O performance during compilation and testing phases, followed by periods of complete dormancy.
Recommended Infrastructure Specifications
For a medium-sized engineering team (20–50 developers) running parallel integration tests and container builds, the following baseline configuration is recommended:
| Component | Gitea Core Instance | Dedicated act_runner Node |
|---|---|---|
| CPU | 4 vCPUs (Compute Optimized) | 8 to 16 vCPUs (High Single-Core Performance) |
| RAM | 8 GB RAM | 16 to 32 GB RAM (Scale based on parallel jobs) |
| Storage | SSD/NVMe with daily automated backups | High-throughput NVMe SSD (Crucial for Docker layer caching) |
| OS | Linux (Ubuntu LTS / Rocky Linux) | Linux with Docker Engine installed |
Pro Tip: Never run the act_runner on the same virtual machine or physical server as your core Gitea instance. Intensive compilation processes can exhaust system memory or CPU cycles, leading to Gitea web interface timeouts and dropped git connections.---Step-by-Step Configuration for Maximum Stability
To establish a resilient deployment, follow this structured configuration methodology. This setup assumes a Linux-based environment utilizing Docker for job isolation.
1. Enabling Actions in Gitea
By default, Gitea Actions may be disabled to conserve system resources. To enable it globally, modify your app.ini configuration file:
[actions]
ENABLED = trueRestart your Gitea service to apply changes. Once active, navigate to the admin panel or repository settings to obtain the Registration Token required to link your runners.
2. Structuring the act_runner Configuration File
Do not rely on the default runner configuration for production workloads. Generate a custom configuration file using the command: act_runner generate-config > config.yaml. Open this file and optimize the following parameters:
- runner.capacity: Define how many jobs the runner can execute concurrently. A good rule of thumb is
(Total vCPUs / 2)to prevent heavy builds from throttling each other. - runner.timeout: Set a hard limit on job execution time (e.g.,
2h) to prevent zombie processes or hung integration tests from blocking the queue indefinitely. - container.network: Ensure the runner uses a secure, isolated bridge network to communicate with external dependencies without exposing host network interfaces.
3. Establishing Secure Runner Execution Modes
Gitea Actions supports multiple execution environments: Docker, Host, and Virtual Machines. For enterprise stability, Docker execution is highly recommended. It ensures that every job starts from a clean, predictable base image, completely preventing configuration drift caused by preceding builds.
When mapping labels in your config.yaml, map standard GitHub labels to stable, explicit Docker images:
runner:
labels:
- "ubuntu-latest:docker://node:20-bullseye"
- "ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04"---Crucial Optimizations for Enterprise Production
Setting up the runner is only the first step. To achieve an experience that truly matches the reliability of GitHub Actions, implementing optimization strategies is essential.
Implementing Robust Dependency Caching
One of the primary complaints regarding self-hosted CI/CD is slow build times due to downloading dependencies (e.g., node_modules, Maven repository files) repeatedly. Gitea Actions supports standard actions/cache mechanisms, but it requires a backend storage solution. Configure an on-premises, S3-compatible storage system such as MinIO to serve as your central cache repository. Update Gitea’s app.ini config to direct cache actions to this secure storage bucket.
Managing the Lifecycle of Docker Layers
If your workflows heavily involve building and pushing Docker images via docker buildx, disk consumption on the runner node will grow exponentially. Implement an automated cron job on the runner host to prune dangling images, builders, and volumes periodically:
0 2 * * * /usr/bin/docker system prune -af --volumesThis cron job executes daily at 2:00 AM, ensuring the runner node never fails a build due to an "Out of Disk Space" error.
---Security Hardening and Isolation Best Practices
Running arbitrary code submitted via git pull requests presents a distinct security vector. To safeguard your internal infrastructure, adopt a strict security posture:
- Enforce Non-Root Execution: Ensure the
act_runnerdaemon runs under a dedicated, unprivileged system user account, not asroot. - Restrict Privileged Containers: Avoid setting
privileged: truein your workflow configurations or runner setups unless absolutely mandatory (such as Docker-in-Docker scenarios). Instead, favor rootless Docker execution. - Network Segregation: Place the runner nodes within an isolated Demilitarized Zone (DMZ) or a dedicated VLAN. The runners require outbound network access to the Gitea server's API and external package registries, but they should never have inbound access to sensitive internal databases or production environments.
Conclusion: A Resilient, Independent CI/CD Future
Transitioning to Gitea Actions provides organizations with the exact autonomy, privacy, and cost predictability required in today's compliance-heavy landscape. By strategically segregating your compute resources, utilizing strict Docker isolation, optimizing layer caching, and adhering to rigorous security protocols, your team can enjoy a high-throughput, stable automation environment that rivals cloud-hosted platforms. Gitea Actions proves that moving away from public cloud ecosystems does not mean sacrificing modern DevOps efficiencies.
