Gitea in Late 2025: Did the Corporate Pivot Actually Work?
It’s New Year’s Eve. While normal people are out buying champagne or making resolutions they’ll break by Tuesday, I’m sitting here staring at my homelab dashboard, specifically the resource usage on my git server. It’s barely sipping RAM.
I’ve been running Gitea for what feels like forever. But looking at the version number today, I started thinking back to that weird, chaotic moment in late 2022 when the project announced it was forming a company. You remember that? The panic? The hot takes on Mastodon? Everyone was convinced that money changing hands meant the soul of the project was about to be sold off for parts.
Three years later, I think it’s time to be honest about what actually happened. Because my server is still running, the code is still open, and—surprise, surprise—paying developers to write code actually results in better code. Who knew?
The “Sustainment” Gamble
The whole premise back then was simple but controversial: volunteer maintainers burn out. They just do. You can’t build enterprise-grade software on weekends and pizza alone. The project leaders wanted a structure that could accept contracts, offer support, and actually pay people to fix the boring bugs that volunteers ignore.
Did it work? Mostly.
If you look at the changelogs from 2023 through 2025, the velocity didn’t just increase; it stabilized. We stopped seeing those long, agonizing droughts between patch releases. Security fixes land faster now. That’s the boring, unsexy benefit of having a legal entity that can actually sign a paycheck.
But it wasn’t all sunshine. We got the fork—Forgejo—which took a chunk of the community with it. And honestly? That was probably healthy. It kept the Gitea company honest. They knew that if they stepped out of line or closed the source, the users had a lifeboat ready. Competition keeps everyone on their toes.
The Feature That Changed My Mind: Actions
For me, the turning point wasn’t the politics. It was Gitea Actions.
Back in the day, I used to hack together webhooks to trigger Jenkins jobs, and it was miserable. I hated it. When Gitea started rolling out built-in CI/CD compatible with GitHub Actions, I was skeptical. Usually, “compatible” means “it parses the YAML but fails on everything else.”
But by mid-2024, it was solid. I finally shut down my Jenkins container last year. Being able to reuse uses: actions/checkout@v4 inside a self-hosted instance without rewriting my entire pipeline? That saved me weeks of work.
Here is what my standard workflow looks like these days. It’s stupidly simple, which is exactly what I want at 11 PM when I break production:
name: Build and Deploy
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Build
run: go build -v ./...
- name: Test
run: go test -v ./...
- name: Scp to Prod
uses: appleboy/scp-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
source: "myapp"
target: "/var/www/app"
The fact that I can use the appleboy/scp-action from the marketplace without hacking the Gitea source code is a testament to how well they implemented the compatibility layer. This is the kind of feature that requires sustained, focused development time—the exact kind of thing volunteer-only projects struggle to finish.
Self-Hosting in 2025
If you haven’t touched your Gitea config since 2022, you’re doing it wrong. The binary is still a single file (thank god), but the ecosystem around it has matured.
I switched my setup to use the rootless container image exclusively about a year ago. Security matters, and running as root inside Docker is so 2020. Plus, the configuration for the runner (for Actions) has gotten much less finicky.
Here’s the stack I’m running right now. I keep it behind Traefik because I’m not a savage, but this is the core logic:
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:1.26-rootless
environment:
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
restart: always
volumes:
- ./data:/var/lib/gitea
- ./config:/etc/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:2222"
networks:
- gitea
db:
image: postgres:16
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea
networks:
- gitea
volumes:
- ./postgres:/var/lib/postgresql/data
runner:
image: gitea/act_runner:latest
environment:
- GITEA_INSTANCE_URL=http://server:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=${RUNNER_TOKEN}
- GITEA_RUNNER_NAME=local-runner
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- gitea
depends_on:
- server
Notice the act_runner service? That wasn’t there three years ago. It’s the piece that executes the Actions. It took me a solid afternoon to figure out that it needs access to the Docker socket to spawn sibling containers, but once it’s up, it just works.
The Verdict
Look, I get the skepticism. When open source projects talk about “sustainability,” it usually sounds like code for “we’re about to lock features behind a paywall.” But Gitea seems to have threaded the needle.
They used the corporate structure to stabilize the codebase and ship massive features like Actions and the Container Registry, but they kept the core product open. I’m not paying a dime, and my experience is better today than it was in 2022.
Is it perfect? No. The UI still has those quirky moments where buttons don’t quite align on mobile, and the documentation can sometimes lag behind the release cycle. But as a personal code repo? It’s unbeatable.
I tried switching to a “heavier” alternative earlier this year—won’t name names, but it rhymes with HitLab—and my server fans started screaming within ten minutes. I crawled back to Gitea the next day.
So, here’s to 2026. Hopefully, I won’t break my runner config again. But I probably will.
