Building a 100% Automated GitOps Infrastructure on a Linux VPS using Gitea, Woodpecker CI, and Renovate Bot
Introduction: The Imperative of Automation in Modern Infrastructure
In the contemporary digital landscape, engineering efficiency and infrastructure reliability are paramount to business success. Traditional deployment workflows, often characterized by manual interventions and fragmented scripts, present significant operational risks. These include configuration drift, prolonged recovery times, and increased security vulnerabilities. To mitigate these challenges, the industry has shifted toward GitOps—an operational framework that takes DevOps best practices used for application development, such as version control, collaboration, compliance, and CI/CD, and applies them to infrastructure automation.
While enterprise solutions like GitLab, GitHub Enterprise, and cloud-native tools offer robust GitOps capabilities, they often come with prohibitive licensing fees, resource-heavy architectures, and data privacy concerns. For small-to-medium enterprises (SMEs) and dedicated engineering teams seeking a lean, cost-effective, and highly performant alternative, a self-hosted stack on a Linux VPS provides the ideal solution. This comprehensive guide outlines how to architecture and build a 100% automated GitOps infrastructure by seamlessly integrating Gitea, Woodpecker CI, and Renovate Bot.
The Core Architectural Pillars
Before diving into the technical implementation, it is crucial to understand the distinct role each component plays within this automated ecosystem:
- Gitea (The Git Core): A lightweight, self-hosted Git service written in Go. It provides a robust, low-resource alternative to GitHub or GitLab, acting as the single source of truth for both application code and infrastructure declarations.
- Woodpecker CI (The Automation Engine): A community-driven fork of Drone CI. Woodpecker utilizes a container-first design, executing pipeline steps within isolated Docker containers. Its minimal footprint and asynchronous agent architecture make it perfect for running on restricted VPS environments.
- Renovate Bot (The Dependency Guardian): An automated dependency management tool that scans repositories for outdated versions (Docker tags, Helm charts, npm packages, etc.) and automatically generates Pull Requests to keep the infrastructure secure and up-to-date.
By combining these three tools, we establish a closed-loop system where infrastructure is declared as code, tested and deployed automatically upon code changes, and proactively maintained against software obsolescence.
Phase 1: Setting Up the Foundation on Linux VPS
The first phase requires provisioning a standard Linux Virtual Private Server (VPS)—ideally running Ubuntu 24.04 LTS or Debian 12—with at least 2 vCPUs and 4GB of RAM. The fundamental prerequisite for our lightweight stack is a containerized runtime engine. We will use Docker and Docker Compose to ensure isolation and easy portability.
Step 1.1: Environment Initialization
Connect to your VPS via SSH and execute the following commands to update the system and install Docker:
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git docker.io docker-compose-plugin
sudo systemctl enable --now dockerStep 1.2: Docker Compose Configuration
We will construct a unified docker-compose.yml file to orchestrate our GitOps foundation. This file defines the networks, volumes, and service configurations for Gitea and Woodpecker CI.
version: '3.8'
networks:
gitops-net:
driver: bridge
volumes:
gitea-data:
woodpecker-server-data:
woodpecker-agent-data:
services:
gitea:
image: gitea/gitea:1.21
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
volumes:
- gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
networks:
- gitops-net
restart: always
woodpecker-server:
image: woodpeckerci/woodpecker-server:v2.1
container_name: woodpecker-server
volumes:
- woodpecker-server-data:/var/lib/woodpecker
ports:
- "8000:8000"
environment:
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=http://gitea:3000
- WOODPECKER_HOST=http://your-vps-ip:8000
networks:
- gitops-net
restart: always
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:v2.1
container_name: woodpecker-agent
command: agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:8000
networks:
- gitops-net
restart: alwaysNote: For production deployments, it is highly recommended to place an HTTP reverse proxy like Nginx, Caddy, or Traefik in front of these services to handle SSL/TLS encryption via Let's Encrypt.
Phase 2: Configuring the Gitea and Woodpecker Integration
Once the containers are operational (via docker compose up -d), access the Gitea web interface at http://your-vps-ip:3000 to complete the initial setup wizard. Create your admin account, which will serve as the root administrator for your GitOps ecosystem.
Step 2.1: Creating an OAuth2 Application
To enable secure, seamless authentication between Woodpecker CI and Gitea, navigate to Site Administration > Applications in Gitea and generate a new OAuth2 Application:
- Application Name: Woodpecker CI
- Redirect URI:
http://your-vps-ip:8000/authorize
Save the generated Client ID and Client Secret. Update your docker-compose.yml file under the woodpecker-server environment section with these keys:
- WOODPECKER_GITEA_CLIENT=your_client_id
- WOODPECKER_GITEA_SECRET=your_client_secretRestart the Woodpecker services using docker compose up -d woodpecker-server to apply the configuration. You can now log into Woodpecker CI using your Gitea credentials.
Phase 3: Setting Up the Infrastructure as Code (IaC) Repository
With our version control and CI engine linked, we can establish our GitOps repository structure. Create a new repository in Gitea named infrastructure-live. This repository will hold the declarative state of our production environment.
The Declarative Directory Layout
A structured repository prevents configuration clutter and allows Woodpecker pipelines to target specific environments efficiently:
infrastructure-live/
├── .woodpecker/
│ └── deploy.yaml
├── apps/
│ └── web-app/
│ ├── docker-compose.prod.yml
│ └── renovate.json
└── README.mdDefining the Woodpecker Continuous Deployment Pipeline
Create the .woodpecker/deploy.yaml file inside your repository. This pipeline is triggered automatically whenever a push event occurs on the main branch, applying the changes directly to the VPS hosting environment.
pipeline:
validate:
image: linter/compose-linter:latest
commands:
- docker-compose -f apps/web-app/docker-compose.prod.yml config
deploy:
image: appleboy/drone-ssh
settings:
host:
from_secret: ssh_host
username:
from_secret: ssh_username
key:
from_secret: ssh_private_key
port: 22
script:
- cd /opt/gitops/apps/web-app
- git pull origin main
- docker compose -f docker-compose.prod.yml up -d --remove-orphans
when:
branch: main
event: pushIn the Woodpecker UI, navigate to the repository settings and add the secrets referenced above (ssh_host, ssh_username, and ssh_private_key) to allow the runner to securely connect back to the VPS host and initiate container updates.
Phase 4: Achieving 100% Automation with Renovate Bot
The true power of this GitOps infrastructure lies in its ability to self-maintain. Manually monitoring Docker image registries or Helm charts for security updates creates cognitive load and vulnerabilities. Renovate Bot solves this by turning updates into automated Pull Requests.
Step 4.1: Creating the Renovate Configuration
Add a renovate.json file to the root or application directory within your repository to define the bot's behavior:
{
"$schema": "[https://docs.renovatebot.com/renovate-schema.json](https://docs.renovatebot.com/renovate-schema.json)",
"extends": [
"config:recommended"
],
"platform": "gitea",
"endpoint": "http://gitea:3000/api/v1",
"automerge": true,
"major": {
"automerge": false
},
"packageRules": [
{
"matchPackagePatterns": ["*"],
"pinDigests": false
}
]
}This configuration instructs Renovate to automatically merge patch and minor version updates if your Woodpecker validation pipelines pass successfully, while reserving major version changes for manual review via Pull Requests.
Step 4.2: Scheduling Renovate Executions via Woodpecker Cron
To keep the system automated without relying on external SaaS triggers, we configure a periodic cron job within Woodpecker CI to spin up Renovate Bot daily. Create .woodpecker/renovate.yaml:
pipeline:
renovate:
image: renovate/renovate:37
environment:
- RENOVATE_PLATFORM=gitea
- RENOVATE_ENDPOINT=http://gitea:3000/api/v1
- RENOVATE_TOKEN=from_secret:gitea_renovate_token
- RENOVATE_AUTODISCOVER=true
when:
event: cron
cron: "nightly"Generate a Personal Access Token in Gitea under your account profile settings and add it to Woodpecker as gitea_renovate_token. Set up a Cron schedule named nightly in the Woodpecker repository panel configured to run at 0 2 * * *.
Business Benefits and Operational Impact
Implementing this lightweight, 100% automated GitOps stack provides distinct operational and strategic advantages for engineering groups:
| Operational Aspect | Traditional VPS Method | Gitea + Woodpecker + Renovate GitOps Stack |
|---|---|---|
| Deployment Safety | Manual SSH commands, high error margin. | Declarative definitions validated via containerized pipelines. |
| Resource Overhead | Low, but unmonitored and untraceable. | Extremely minimal; total memory usage under 1.5GB RAM. |
| Dependency Maintenance | Reactive; updates happen only after critical failures. | Proactive; nightly automated scanning and safe auto-merging. |
| Infrastructure Audit | Non-existent; logs must be manually parsed. | Perfect tracking via the Git commit history timeline. |
Conclusion: Embracing High-Velocity, Zero-Trust Operations
By leveraging the collective capabilities of Gitea, Woodpecker CI, and Renovate Bot, we successfully eliminate manual friction from the infrastructure lifecycle. Security vulnerabilities are instantly patched, manual configuration drift is structurally avoided, and updates are continually validated through automated regression testing pipelines—all contained within an incredibly lightweight, budget-friendly VPS footprint.
For technology leaders and system architects, embracing this self-hosted GitOps pipeline translates directly to improved developer velocity, minimal operational overhead, and absolute sovereignty over enterprise data and infrastructure code.
