Request an exact quote
CI/CD & DevOps migration path

From GitLab (Premium/Ultimate) to Gitea / Forgejo

Leaving GitLab Premium/Ultimate for self-hosted Gitea or Forgejo, mirroring repos, translating CI pipelines (the real work), migrating issues via API, and cutting over team by team.

Effort
High
Est. timeline
~18 wks
Gitea / Forgejo model
Free (self-hosted)
Open source
Yes
▶ Model your savings in the interactive calculator

GitLab’s Premium and Ultimate tiers are priced per user, gate the best features behind the top tier, and commit you to annual seats with CI-minute overages on top. Gitea (and its community fork Forgejo) is a lightweight, self-hosted Git platform that removes seat licensing entirely, with Gitea Actions providing GitHub-Actions-compatible CI. Repos and issues migrate easily; the real lift is translating pipelines.

What you gain, and what you give up

You gain a fast, low-footprint Git host with code review, issues, packages, and Actions-based CI, at no per-seat cost. You give up GitLab’s all-in-one breadth: advanced security scanning (SAST/DAST/dependency), built-in value-stream and compliance dashboards, sophisticated merge-request approval rules, and the integrated container/agent fleet. For most teams that mainly need Git + code review + CI, Gitea/Forgejo is ample; if you lean on Ultimate’s security and compliance suite, plan replacements (e.g. Trivy, Semgrep, Renovate) rather than assume parity.

Migrate repos, issues, and artifacts

Gitea/Forgejo can pull-mirror repositories directly from GitLab, including the option to import issues, pull/merge requests, labels, and milestones via the GitLab API during migration. Stand up the new instance (with an external PostgreSQL for production), then run migrations per project. This part is genuinely smooth.

A few things do not ride along with the mirror, so plan them explicitly:

  • User mapping. Issue and MR authorship maps to Gitea accounts only when the accounts match. Create or link users first, or accept that history attributes to a fallback account.
  • Packages and container images. GitLab’s package and container registries do not mirror through the Git import. Re-publish artifacts to Gitea’s package registry, or point builds at whatever external registry you already run.
  • Wikis and snippets. Wikis migrate as their own Git repositories; snippets have no direct equivalent, so decide whether to fold them into a repo or drop them.

Treat the repo and issue import as a rehearsal for the real work. If a pilot project imports cleanly and its history looks right, you have proven the mechanism and can move on to the part that actually takes time.

The pipeline rewrite is where the time goes

.gitlab-ci.yml does not run on Gitea. Gitea Actions uses the GitHub Actions workflow format (.gitea/workflows/*.yml), so each GitLab job, stages, rules, needs, artifacts, services, caching, must be rewritten as Actions steps (or Woodpecker pipelines if you prefer that engine). Budget the bulk of the project here:

  • Map GitLab stages/jobs → Actions jobs/steps, and GitLab runners → Act runners registered to the instance.
  • Re-create CI/CD variables and secrets in the new platform’s secret store.
  • Reconnect container registry, package registry, and deploy targets; re-point webhooks and service connections.
  • Recreate protected-branch and approval rules as closely as the platform allows.

Where the effort concentrates

Not every job costs the same to convert. Simple build-and-test jobs map almost line for line: a script: block becomes a run: step, and a job’s image: becomes the container the step runs in. The expensive cases are the ones that leaned on GitLab-specific machinery: rules: with complex if/changes conditions, dynamic child pipelines, extends and YAML anchors used as a homegrown template system, and needs: graphs that fan out widely. Convert the straightforward jobs first to build momentum, then sit down with the complex ones once the team is fluent in the Actions model.

Re-entering secrets and registering runners

Secrets do not travel with the repo mirror. Re-enter CI/CD variables in the new secret store, scoped to org or repo, and never inline them in workflow YAML. For runners, register Act runners against the Gitea instance and re-point the same underlying compute you already run. Confirm the runners can reach your registries and deploy targets before you rely on them, since network egress rules often differ from the old GitLab environment.

Cut over team by team

  1. Inventory repos, pipelines, runners, secrets, artifacts, integrations, and permission/environment models.
  2. Stand up Gitea/Forgejo (HA + PostgreSQL), register Act runners.
  3. Mirror repos and import issues/MRs for a pilot project; translate and dry-run its pipeline (build/test/deploy).
  4. Validate the full pipeline shape on the pilot, then migrate project by project, keeping GitLab live until each team’s pipelines are green.
  5. Re-point webhooks/runners back on failure, rollback is keeping GitLab authoritative until sign-off.

Validation before you trust it

The acceptance bar is “a representative project builds, tests, and deploys end to end on the new platform.” Verify secret/artifact resolution, webhook and integration behavior, and a deploy-plus-rollback. Don’t migrate the whole org until the pilot’s pipeline runs clean.

What to weigh before you start

GitLab → Gitea/Forgejo removes per-seat cost; repos and issues migrate cleanly, but pipeline translation to Actions/Woodpecker is the substance of the work, and Ultimate’s security/compliance suite needs deliberate replacement. Pilot one project end to end, then cut over team by team with GitLab as fallback. Model your per-seat savings in the calculator above, and treat them as provisional until you scope the pipeline-conversion effort.

Tooling & automation for this path

Mirror repos to Gitea/Forgejo; convert .gitlab-ci.yml to Actions/Woodpecker pipelines; migrate issues/MRs via API; re-point runners; cut over team by team.

Primary references: official Gitea / Forgejo documentation ↗ and the GitLab (Premium/Ultimate) documentation ↗ , always verify version-specific behavior against them before you migrate.

Frequently asked questions

Can Gitea or Forgejo import my GitLab issues and merge requests, not just the code?

Yes. The built-in migration can pull-mirror the repository and, using a GitLab API token, import issues, merge requests, labels, and milestones during the same migration. Comments and authorship come across too, though the mapping to Gitea users depends on matching accounts. Run it per project so you can verify each import before trusting it.

How do I convert a .gitlab-ci.yml pipeline to run on Gitea?

Gitea Actions uses the GitHub Actions workflow format under .gitea/workflows/, so .gitlab-ci.yml does not run as-is. You rewrite each job, stage, rule, needs relationship, artifact, service, and cache entry as Actions steps, or as Woodpecker pipelines if you prefer that engine. This rewrite is the bulk of the migration, not the repo move.

What happens to my GitLab CI/CD variables and protected-branch rules?

Neither transfers automatically. Re-create CI/CD variables and masked secrets in the new platform's secret store, scoped to the org or repo, and rebuild protected-branch and approval rules as closely as Gitea or Forgejo allows. GitLab's more elaborate approval logic may need to be simplified since the feature sets are not identical.

Do my existing GitLab runners work with Gitea, or do I need new ones?

You register Act runners against the Gitea instance rather than reusing GitLab runners, because the runner protocol and job format differ. In practice you re-point the same underlying compute, VMs or Kubernetes nodes, at the new server by installing and registering the Act runner there. Size the pool for your real concurrency before cutover.

Model your 3-year cost

Pre-filled for GitLab (Premium/Ultimate) → Gitea / Forgejo; adjust every figure with your own numbers. Estimates are illustrative, not vendor quotes, see our methodology.

Sized at 200 users, cost is computed on this.
Stay on GitLab (Premium/Ultimate) (3yr)
$240,000
Move to Gitea / Forgejo (3yr + migration)
$75,000
Projected savings
$165,000 (69%)
Payback period
10.9 mo
Build a decision report from these numbers:

Illustrative, editable figures, not vendor pricing (defaults reviewed May 2026).

Request a vendor-accurate Gitea / Forgejo quote

A guided builder that turns your estimates into a requirements report (RFQ) you can send to a vendor, partner, or distributor for a binding quote, then feed the real prices back into the calculator above. How our estimates work.

  1. 1Size it
  2. 2Requirements
  3. 3Your details
  4. 4Channels & export

How big is your GitLab (Premium/Ultimate) estate?

Count the people who need accounts or seats. Not sure? Enter rough numbers, the distributor confirms exact counts later.

200 users
Default mid-size assumption (200 users)