Migrate GitLab from the Linux package to the Helm chart

Moving an Omnibus GitLab onto Kubernetes is mostly a data-externalization and secrets project, not a file copy. This page sets out the documented path, the decisions it forces and what drives effort.

On this page

Why moving GitLab from the Linux package to the Helm chart is a data project first

An Omnibus GitLab keeps its own PostgreSQL, Redis and repository files on the same host, so moving it to Kubernetes is mostly a question of where that state lives. The move depends on two things: externalizing the stateful services first, and restoring a backup into a chart that runs the same GitLab version. Without those two steps in place, the chart has nothing reliable to attach to and the data cannot be trusted once it arrives.

The documented sequence requires a Helm installation running the same GitLab version, with object storage, PostgreSQL and Redis configured as external services before the chart is deployed. In practice, that means your team must first decide where the database, cache and object store will run, and confirm that the Kubernetes cluster can reach them. The effort is driven mainly by how much state you have to move (repositories, uploads, CI artifacts, container and package registries) and by how well your existing PostgreSQL and Redis are already operated. The GitLab Helm chart migration documentation is the authoritative sequence, and you should confirm the exact prerequisites for your chart version before you schedule work. No duration is implied here; ask any partner for a written scope that lists each external service, its owner and its restore test.

Treat the cutover as a data project with an acceptance test, not as a deployment. The migration documentation moves data to object storage, creates a backup tarball, restores it into the chart, restarts all pods and then expects you to check projects, users and uploads by hand. Plan that verification step as a named deliverable, with sample projects, a user login check and a sample upload retrieved from the new object store. Also decide, before you begin, who holds the copy of /etc/gitlab/gitlab-secrets.json, because a restored instance that cannot decrypt its stored secrets will fail in ways that are hard to diagnose.

What maps cleanly from Omnibus to the chart and what does not

This table compares each part of a Linux package GitLab with where it lives in a chart-based deployment. Read the middle column as what you must provide or move yourself, and the right column as what to verify in the chart docs before you commit to a cutover plan.

Component or dataOmnibus behaviorChart target and what to verify
PostgreSQLBundled on the same server by defaultMust be an external service configured before the chart deploys. Confirm the supported PostgreSQL versions and connection settings in the chart migration docs.
RedisBundled and managed through gitlab.rbMust be external before deployment. Reference architecture guidance says stateful components like Redis are not supported inside Kubernetes, so plan a VM or managed service.
SidekiqRuns as a bundled service on the Omnibus hostRuns as chart pods. Size replicas to your job load and confirm the chart values for queues and resources.
Gitaly and Git repositoriesRepositories stored on the Omnibus host file systemRepository data is carried by the backup tarball and restored into the chart's Gitaly. Verify Gitaly storage and sizing for your repository volume before cutover.
Uploads, LFS, artifacts and packagesStored on local disk unless object storage is configuredMust move to object storage before the backup is taken. Confirm each object store bucket is configured in the chart values.
gitlab-secrets.jsonLives at /etc/gitlab/gitlab-secrets.jsonValues must be copied into the chart's secrets. Without them, encrypted CI variables, two-factor secrets and tokens will not decrypt.
gitlab.rb settingsCustom settings in gitlab.rbDo not carry over directly. Translate each setting into Helm values and review the chart docs for equivalents before deploying.
Runners and CI/CD variablesRunners are registered separately and variables live in project or group settingsRunners are not part of the Omnibus backup. Re-register or repoint runners at the new instance and confirm which variables restore with the database.

Documented migration paths and tools for this move

The Linux package to Helm chart move rests on a small set of documented components: a backup, object storage, external services and the secrets file. Each does a specific job, and none of them carries the whole migration by itself, so the checks sit between them.

Linux package backup and restore

The backup task on the Linux package instance produces a tarball of database, repositories and uploads that the chart restores from. It does not carry gitlab-secrets.json, configuration files or the runner fleet, so those must be moved separately. Confirm the exact backup and restore commands and the version pairing in the migration docs before you run anything against production.

Object storage for uploads and artifacts

Uploads, job artifacts, LFS objects and package files are moved to object storage before the backup is taken, so the chart can point at the same buckets. Plan the bucket layout, access keys and lifecycle rules with the storage team. Object storage does not hold the database, so a bucket copy alone cannot restore issues, merge requests or users.

External PostgreSQL and Redis settings

The chart must reach PostgreSQL and Redis as external services, configured before the chart deploys. The Helm chart does not run these stateful services for you in this design, so the database and cache need their own high availability, backup and upgrade plans. Confirm the supported PostgreSQL and Redis versions for your chart release in the migration docs.

The gitlab-secrets.json file

The gitlab-secrets.json file holds keys that encrypt database fields such as CI variables and two-factor secrets. Its values must be copied into the chart's secrets exactly, or encrypted data becomes unreadable after restore. Store the copy in a controlled secrets manager, restrict who can read it, and treat it as a credential during the cutover window.

Chart version and migration docs

The migration requires a Helm installation running the same GitLab version as the source instance, so the chart version must match the Linux package release. Do not assume a chart version maps to a GitLab release from memory. Check the compatibility table and the migration steps in the chart documentation for your exact target version before you pin it.

The sequence: externalize, back up, restore, verify and cut over

The sequence moves a Linux package GitLab onto the Helm chart at the same version, with data services moved out first so the final backup is the only point where the old node stops serving users. It ends with a verified chart instance, a parallel check window and a retired Omnibus node.

  1. Inventory the source instance and its secrets

    Record the installed GitLab version, the enabled features, the external URL, the storage paths, the CI runners and every integration that calls the instance. Confirm the exact version from the running Omnibus node, then copy /etc/gitlab/gitlab-secrets.json and gitlab.rb to a protected location with restricted access, since the chart cannot decrypt stored data without those keys. The step is done when the team holds a written inventory and a verified secrets copy that someone other than the migrating engineer has checked.

  2. Externalize PostgreSQL, Redis and object storage

    While the Omnibus node still runs, move the bundled PostgreSQL, Redis and file storage to services the chart will reference as external. The chart requires object storage, PostgreSQL and Redis to be configured as external services before it is deployed, so this work comes first. Test each service with a copy of the data and a reconnect from the old node. The step is done when the Omnibus node runs against the external services without errors in its logs over a full working day of normal traffic.

  3. Confirm the target chart runs the same version

    Install the Helm chart in a staging namespace with the same GitLab version as the source, configured against the same external services. The chart version must match the GitLab application version you are migrating from, so check the chart release mapping before you deploy. Confirm the pods start and the web interface responds. The step is done when the staging chart reports healthy and the version shown in the admin area matches the source exactly.

  4. Block CI job requests and take the final backup

    Schedule a window, enable maintenance mode and stop accepting new CI job requests so that no pipeline writes data during the final backup. Disable Sidekiq cron jobs that could change state, then create a backup tarball with the GitLab backup task. Store the tarball and the copied secrets together in a location the new environment can reach. The step is done when the backup task completes without errors and the tarball's checksum is recorded alongside the secrets file.

  5. Restore the backup into the chart

    Copy the secrets from gitlab-secrets.json into the chart's YAML secret definitions, so the restored database and encrypted fields can be read. Start the chart with the restore procedure, restart all pods so each component picks up the restored data and secrets, and confirm the application starts cleanly. The step is done when the restored instance shows the expected projects and the logs contain no decryption or database errors.

  6. Verify projects, users and uploads manually

    Check a sample of projects by cloning repositories, viewing merge requests and reading wiki pages, and confirm that users can sign in through their configured method. Open a set of attachments and avatars, run a test pipeline on a runner, and compare issue and project counts with the source. Record each check in a shared checklist. The step is done when every check on the list passes and the owners of the affected teams have signed off on their projects.

  7. Run a parallel check window

    Keep the Omnibus node available in read-only or stopped state for a window agreed in advance, while the chart instance handles test traffic. Confirm that runners registered to the new instance are on the same GitLab version and that the runner and instance major and minor versions stay aligned. Watch logs, error rates and runner job results. The step is done when the agreed window closes with no open defects that block users.

  8. Cut DNS over and decommission the old node

    Point the external hostname at the chart instance, lower the risk of double processing by confirming that the old node no longer accepts writes, and then re-enable the runners and integrations against the new URL. Keep the Omnibus node and its backup for a retention period set by your change process before you remove it. The step is done when DNS resolves to the new instance, webhooks and runners report to it, and the retired node's backup and secrets are archived under your access controls.

What drives the effort and cost of this migration

This table lists the factors that change the size of a Linux package to Helm chart move, who pays for each one, and whether it is a one-time or recurring cost. Use it to shape the written scope and to check that a quote covers each driver. The main takeaway is that the state of your existing external services and Kubernetes platform usually matters more than the GitLab data itself.

DriverWhy it changes effort or costWho pays and one-time or recurringWhat to ask for in a quote
Git repository and object storage volumeLarger repositories, LFS objects, artifacts and uploads lengthen the backup, transfer and restore windows and raise storage needs in the chart's target environment.Your cloud or data center bills storage and transfer (recurring). Migration time for data movement is one-time.Estimated data sizes, transfer method, and a dry-run restore window agreed in writing.
Users and CI loadMore users and pipelines increase the verification scope and the sizing of the chart's pods and the Runner fleet during cutover.Compute for the chart is recurring. Load testing and cutover checks are one-time.Named user count, peak pipeline volume, and which load checks are in scope.
PostgreSQL and Redis already externalizedIf both still run inside the Omnibus package, you must build and move them to external services before the chart can be deployed, which adds work.Database platform cost is recurring (managed or self-run). Externalizing and data migration are one-time.Whether the external PostgreSQL and Redis are already provisioned, their versions, and who operates them after handover.
Kubernetes platform readinessA cluster that lacks storage classes, ingress, certificate handling, backup tooling or a supported Kubernetes version adds platform work before GitLab can be placed on it.Your team or the cluster provider pays for the platform (recurring). Preparing gaps is one-time.A list of cluster prerequisites, the Kubernetes version in use, and the owner of cluster upgrades.
Identity and SSO integrationMoving to the chart means re-testing SAML, LDAP, OAuth or other providers, since callback URLs and certificates change with the new hostname or ingress.Identity platform costs are already in place. Reconfiguration and testing are one-time.Which providers are in use, the callback URLs to change, and how user login is verified after cutover.
Runner fleet changesRunners registered to the old instance must be re-registered or repointed, and executors that depend on the old network or hosts need review.Runner compute is recurring. Re-registration and pipeline checks are one-time.Runner inventory, executor types, and whether runners are moved or rebuilt.
Network and air-gap constraintsRestricted egress, private registries and offline package sources require extra image mirroring and configuration before the chart deploys.Your network team pays for changes (one-time). Mirror storage is recurring.Confirmed registry locations, egress rules, and how images and chart packages reach the cluster.
Verification scopeThe checks you require (projects, users, uploads, pipelines, integrations, backups) set how much testing is needed before cutover and rollback.Verification is one-time, but ongoing monitoring is recurring under your operations budget.A written checklist of acceptance tests, the owner who signs each one, and the rollback point.
Secrets and gitlab-secrets.json handlingCopying secrets into chart values must be done carefully, and secrets stored in Kubernetes need encryption at rest and tight RBAC.Key management tooling is recurring if you use an external store. Secret transfer is one-time.How secrets are stored, who can read them in the cluster, and the encryption method confirmed for etcd.

Questions buyers ask before moving GitLab to Kubernetes

Can our own team move Omnibus GitLab to the Helm chart without a partner?

Yes, a capable platform team can do this in-house, but the work spans two systems at once: a GitLab backup and restore and a Kubernetes deployment. The official procedure has a defined sequence: move data to object storage, create a backup tarball, restore it into the chart, copy secrets across, restart all pods and then check projects, users and uploads by hand. The main question is whether your team has run GitLab upgrades, Kubernetes operations and backup restores in production, and whether it can staff the validation window. An outside partner is most useful when the team lacks one of those skills or needs the cutover fixed to a written scope and timeline.

What makes the cost and effort of this migration go up or down?

The cost tracks the number of external services to build, the size of the instance and the number of integrations that must keep working. Externalizing PostgreSQL, Redis and object storage before the chart is deployed is often the largest single piece, and it depends on whether you already run those services in a supported form. Other drivers include the volume of repositories, uploads and container registry data to move, the number of runners and CI/CD variables, authentication settings, and how many custom configuration keys in gitlab.rb need translating into chart values. Ask any provider for a quote that lists each of these as a separate line item, with what is one-time (the migration itself) and what recurs (running and upgrading the chart afterward).

How long does a Linux package to Helm chart migration take?

Duration depends on the same drivers as cost, plus the time needed to copy data and restore it, which grows with the size of your repositories, uploads and object storage. Plan separate windows for building the external PostgreSQL, Redis and object storage services, for the backup and restore itself, and for manual verification of projects, users and uploads after the pods restart. Your change calendar and any required maintenance windows will also shape the schedule. Confirm with your provider how each window is measured and what the written scope assumes about instance size and data volume before you commit to a date.

What does our team need to provide during the migration?

Your team usually supplies access to the existing GitLab server, the Kubernetes cluster and cloud or data center accounts, and the decisions only you can make. Those include the target object storage, the external database and cache services, DNS and ingress choices, and who signs off on the post-restore checks. You will also need someone who can explain your authentication setup, your runner fleet and any integrations with issue trackers, secrets managers or chat. Ask the provider to list these inputs in writing so that waiting on an access request or a missing decision does not stall the cutover.

Does the Helm chart have to run the same GitLab version as the Linux package?

Yes. The official migration procedure requires a Helm installation running the same GitLab version as the Omnibus instance, so the backup can be restored into the chart. Once the move is complete, plan upgrades separately, because GitLab requires upgrades to pass through required upgrade stops, which currently fall at versions x.2, x.5, x.8 and x.11 (for example 19.2, 19.5, 19.8 and 19.11). Check the upgrade paths documentation before choosing the source version, since an instance that is behind a stop may need extra steps before the chart deployment is possible.

What happens to our GitLab Runners and CI/CD secrets during the move?

Runners are separate from the GitLab application, so they can keep running while you move the server, but they must be pointed at the new instance URL and kept on versions aligned with GitLab. The gitlab-secrets.json file holds encryption keys that the restored data depends on, so its values must be copied into the chart secrets exactly, or encrypted data such as CI/CD variables and tokens will fail to decrypt. Review which runners use the Kubernetes executor and whether their registration tokens and cluster credentials need rotating. Your team should also confirm how existing variables are checked after the restore, since the procedure leaves that verification to you.

Why do PostgreSQL and Redis stay outside the Kubernetes cluster?

GitLab's reference architectures state that running stateful components such as PostgreSQL and Redis inside Kubernetes is not supported. The supported pattern is the Cloud Native Hybrid architecture, which runs stateless components on Kubernetes and keeps stateful services on virtual machines or managed services. That is why the migration requires these services to be configured as external before the chart is deployed. Keeping them outside also makes backups, failover and patching of the database independent of chart upgrades. Confirm the exact supported topology for your user count with the reference architectures documentation before you design the platform.

What usually goes wrong and how to prevent it

Most failed Linux package to Helm chart migrations break in a small set of predictable places: secrets, versions, external services, storage and access checks. Each card below names one failure, why it matters for this move, and the check that catches it before users do.

Lost or mismatched secrets file

The file /etc/gitlab/gitlab-secrets.json holds the keys that encrypt database fields such as CI variables and two-factor secrets. If it is missing, or the values copied into the chart differ by a character, encrypted data becomes unreadable after restore. Back up the secrets file separately from the tarball and confirm each key was transferred before the first restore. Test a sample of CI variables after go-live.

Version drift between source and chart

The backup can only be restored into a chart running the same GitLab version as the Omnibus source. If the chart is newer, or someone upgrades one side during the window, the restore fails or the data is misread. Pin the chart to the exact source version and freeze changes on both sides until verification ends. Record the version in the cutover runbook.

External services configured too late

The migration expects object storage, PostgreSQL and Redis to exist as external services before the chart is deployed. Teams that deploy the chart first and try to repoint it later often end up with data split across two databases. Confirm the connection settings for all three services and run a test connection from the cluster before starting the backup.

Object storage gaps and incomplete uploads

Attachments, LFS objects, packages and artifacts move to object storage, and any item left on local disk will be missing after the switch. Buckets with wrong permissions or lifecycle rules can also delete data silently. Compare object counts and sizes per bucket before and after the move, and open a sample of uploaded files from old issues and merge requests.

Runners left on old versions

GitLab Runner should keep its major and minor versions aligned with GitLab, and runners registered to the old instance will not automatically follow the new URL. Jobs can queue indefinitely or fail with API errors if runners still point at the source. Re-register or reconfigure each runner against the new endpoint and upgrade it to the aligned version before enabling pipelines.

Unverified users and permissions

A successful restore does not prove that users can sign in, that group roles are intact or that projects show the right visibility. Authentication providers configured on the Omnibus side must also be recreated in the chart values. Run a scripted check of sample projects, groups, users and uploads against a documented list, and only then reopen access to developers.

What you provide and what you receive from a fixed-scope move

Before any work starts, the scope, deliverables and timeline for this move are agreed in writing. The client team's main inputs are access and endpoints. You supply a Kubernetes cluster that meets the chart's requirements, a Helm installation running the same GitLab version as the Linux package instance, and working endpoints for object storage, PostgreSQL and Redis, because the migration only works once those three are external services. You also supply the Linux package host's access so the backup and /etc/gitlab/gitlab-secrets.json can be handled, a named owner for DNS and ingress changes, and a maintenance window long enough for the backup, restore and pod restarts. The exact window length depends on instance size, so ask DeployOpen to base it on a measured backup of your data, not on an estimate.

On the acceptance side, you supply named business users who will check projects, users and uploads after the restore. The migration guidance includes manual checks of those three areas, and that testing needs people who know which projects, pipelines and attachments matter most. You also decide who signs off the cutover and who can authorize a rollback. Confirm in advance who can approve each of these, since that is where fixed-scope projects usually stall.

In return, DeployOpen delivers the written items agreed in the scope: the target chart configuration with secrets mapped into chart values, the backup and restore runbook, the cutover and rollback steps, the post-restore verification checklist, and a handover of the resulting configuration. Each deliverable should be listed by name in the statement of work so you can check it at handover. DeployOpen does not publish a price list. The quote follows from the written scope, and the drivers you should ask about are instance data size, the number of external services you need built or reused, and the number of acceptance rounds.

How DeployOpen scopes and delivers this migration

DeployOpen treats the move from the Linux package to the Helm chart as a planned change to a running system, not a fresh install. We agree the written scope first, then build and test the external services, the restore and the cutover checks in your own infrastructure.

How we scope

  • Inventory the Omnibus version, enabled components, custom gitlab.rb settings and attached storage before estimating any work
  • Confirm the target chart release matches the exact GitLab version running on the Linux package host
  • Agree in writing how external PostgreSQL, Redis and object storage will be provisioned and who owns each
  • Record which projects, users, uploads and CI variables must be checked after restore, and who signs off

How we build

  • Move object storage first, then point the Linux package instance at external PostgreSQL and Redis before the backup
  • Create the backup tarball on the source, then restore it into a chart deployment running the same GitLab version
  • Copy values from gitlab-secrets.json into chart secrets in a controlled way and test that encrypted data still decrypts
  • Run a rehearsal restore in a non-production namespace and record the steps, timings and any errors found

How we hand over

  • Deliver the scope-agreed runbook covering the cutover order, rollback point and post-restart checks
  • Document the chart values, secret locations, external service connections and access paths for your operators
  • Walk your team through the manual checks of projects, users and uploads and record the results as evidence
  • Provide a list of open items, such as runner reconfiguration or DNS changes, that remain under your control

How we support

  • Support after cutover can be covered by a retainer agreed separately from the migration scope
  • Retainers can include upgrade planning against required upgrade stops and chart version changes
  • Ongoing work can include backup restore testing and monitoring review, scoped in writing
  • Pricing for any follow-on work follows from the written scope, with no list prices published

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.