Deckhouse Code runs on GitLab and takes over the data of a GitLab Community Edition (CE) instance of the same GitLab version: repositories, users, groups, issues, merge requests, CI/CD settings and history. The instance is moved as a whole. To move single projects between instances, use Importing a project.
The procedure depends on where Deckhouse Code runs:
- on the same server or with the same Docker volumes as GitLab CE: the Deckhouse Code package or image replaces GitLab CE, and the data stays in place, as described in In-place migration;
- on another server, in a Helm Chart installation or in the Deckhouse Kubernetes Platform module: the data is moved in a backup archive, as described in Migration through a backup archive.
Before you start
Check the conditions on the GitLab CE instance:
- The GitLab version of the instance is the GitLab version of the Deckhouse Code release you install. A backup archive is restored only into the version it was created on. When the instance runs an older version, upgrade it along the GitLab upgrade path first.
- All background migrations have finished: open “Admin” → “Monitoring” → “Background migrations” and check that the “Queued”, “Finalizing” and “Failed” tabs are empty.
- There is enough free disk space for a backup archive.
Check the GitLab version of the instance:
- Linux package
- Omnibus Docker
sudo cat /opt/gitlab/embedded/service/gitlab-rails/VERSIONIn the commands of this page, the GitLab CE container is named gitlab; replace the name with your own.
docker exec gitlab cat /opt/gitlab/embedded/service/gitlab-rails/VERSIONIn-place migration
The Deckhouse Code package replaces the gitlab-ce package, and the Deckhouse Code image runs on the volumes of the GitLab CE container. The configuration in /etc/gitlab/gitlab.rb, the secrets in /etc/gitlab/gitlab-secrets.json and the data in /var/opt/gitlab are kept. The configuration run applies the database migrations that create the tables of Deckhouse Code.
The services restart during the installation, and the instance is unavailable until the configuration and the migrations finish.
- Linux package
- Omnibus Docker
Create a backup and copy it, together with
/etc/gitlab/gitlab.rb,/etc/gitlab/gitlab-secrets.jsonand the/etc/gitlab/ssl/directory, off the server:sudo gitlab-backup createInstall the Deckhouse Code package. The package manager removes the
gitlab-cepackage:# RED OS. sudo dnf install -y ./deckhouse-code-<VERSION>.el8.x86_64.rpm # AlmaLinux. sudo dnf install -y ./deckhouse-code-<VERSION>.el9.x86_64.rpm # Ubuntu. sudo apt install -y ./deckhouse-code_<VERSION>_amd64.debRun the configuration:
sudo gitlab-ctl reconfigureCheck that no migration is pending, that the encrypted data in the database is read with the secrets of the instance and that the instance passes the self-check:
sudo gitlab-rake db:migrate:status | grep -w down sudo gitlab-rake gitlab:fe:secret:verify sudo gitlab-rake gitlab:check SANITIZE=trueThe first command prints nothing when all migrations are applied. When it prints migrations, apply them and run the checks again:
sudo gitlab-rake db:migrate
In the commands below, <GITLAB_HOME> is the host directory that holds the config, logs and data volumes of the GitLab CE container.
Create a backup and copy it, together with the
<GITLAB_HOME>/configdirectory, off the host:docker exec -t gitlab gitlab-backup createStop and remove the GitLab CE container. The volumes are host directories and stay in place:
docker stop gitlab docker rm gitlabCreate the Deckhouse Code container on the same volumes, with the ports and environment variables of the GitLab CE container:
docker run -d --name code \ --shm-size 256m \ -p 80:80 -p 443:443 -p 22:22 \ -e GITLAB_OMNIBUS_CONFIG="external_url 'https://<HOSTNAME>'" \ -v <GITLAB_HOME>/config:/etc/gitlab \ -v <GITLAB_HOME>/logs:/var/log/gitlab \ -v <GITLAB_HOME>/data:/var/opt/gitlab \ <REGISTRY>/<FLAVOR>:<VERSION>Follow the start. The database migrations run during the configuration, and the instance answers 502 until it finishes:
docker logs -f codeCheck that no migration is pending, that the encrypted data in the database is read with the secrets of the instance and that the instance passes the self-check:
docker exec code gitlab-rake db:migrate:status | grep -w down docker exec code gitlab-rake gitlab:fe:secret:verify docker exec code gitlab-rake gitlab:check SANITIZE=trueThe first command prints nothing when all migrations are applied. When it prints migrations, apply them and run the checks again:
docker exec code gitlab-rake db:migrate
Migration through a backup archive
The data moves in a backup archive, and the files the archive does not contain are copied separately. Deckhouse Code is installed in advance with the GitLab version of the source instance and the same external address.
Collecting the data of GitLab CE
Collect the files from the GitLab CE instance and keep them with the same level of protection as passwords:
- the backup archive;
gitlab-secrets.json: the encryption keys of the database; without them, two-factor authentication settings, tokens and encrypted CI/CD variables are lost;gitlab.rb: the instance configuration;- the certificates and keys from the
/etc/gitlab/ssl/directory; - the SSH host keys: with them, Git clients connect over SSH to Deckhouse Code without a host key warning.
- Linux package
- Omnibus Docker
Create a backup:
sudo gitlab-backup createThe archive
<BACKUP_NAME>_gitlab_backup.taris written to/var/opt/gitlab/backups/.Copy the archive, the
/etc/gitlab/gitlab.rband/etc/gitlab/gitlab-secrets.jsonfiles, the/etc/gitlab/ssl/directory and the/etc/ssh/ssh_host_*files off the server.
Create a backup:
docker exec -t gitlab gitlab-backup createThe archive
<BACKUP_NAME>_gitlab_backup.taris written to<GITLAB_HOME>/data/backups/on the host.Copy the archive, the
gitlab.rbandgitlab-secrets.jsonfiles, thessl/directory and thessh_host_*files from<GITLAB_HOME>/configoff the host.
When GitLab CE keeps uploads, CI/CD artifacts, LFS objects or packages in object storage, the archive does not contain them. Connect Deckhouse Code to the same buckets, or copy the buckets to the storage of Deckhouse Code, for example with rclone sync.
<BACKUP_NAME> is the archive file name without the _gitlab_backup.tar suffix: for the 1784800000_2026_07_23_19.4.1_gitlab_backup.tar archive it is 1784800000_2026_07_23_19.4.1.
Restoring into Deckhouse Code
After the restore, the database holds the schema of GitLab CE. The gitlab-rake db:migrate command adds the tables of Deckhouse Code to it.
- Linux package
- Omnibus Docker
- Helm Chart
- Deckhouse Kubernetes Platform module
Install Deckhouse Code as described in Quick start.
Replace
/etc/gitlab/gitlab.rband/etc/gitlab/gitlab-secrets.jsonwith the files of GitLab CE, copy the certificates and keys into/etc/gitlab/ssl/, then run the configuration:sudo gitlab-ctl reconfigureCopy the SSH host keys into
/etc/ssh/and restart the SSH server:sudo cp ssh_host_* /etc/ssh/ # RED OS, AlmaLinux. sudo systemctl restart sshd # Ubuntu. sudo systemctl restart sshCopy the archive to the backup directory and hand the file over to the
gituser:sudo cp <BACKUP_NAME>_gitlab_backup.tar /var/opt/gitlab/backups/ sudo chown git:git /var/opt/gitlab/backups/<BACKUP_NAME>_gitlab_backup.tarStop the services that write to the database:
sudo gitlab-ctl stop puma sudo gitlab-ctl stop sidekiqRestore the data. The command asks for confirmation twice, before the
authorized_keysfile is rebuilt and before the current database tables are dropped; answeryesboth times:sudo gitlab-backup restore BACKUP=<BACKUP_NAME>Apply the database migrations of Deckhouse Code:
sudo gitlab-rake db:migrateRestart the instance and check it:
sudo gitlab-ctl restart sudo gitlab-rake gitlab:fe:secret:verify sudo gitlab-rake gitlab:check SANITIZE=true
The container reads the configuration, the secrets and the SSH host keys from the configuration volume and generates host keys only when the volume has none, so the files are put on the volume before the first start.
Put the files of GitLab CE into the configuration directory on the host:
gitlab.rb,gitlab-secrets.jsonand thessh_host_*files into/srv/code/config/, the certificates and keys into/srv/code/config/ssl/.Create the container as described in Quick start and wait for the first start to finish:
docker logs -f codeCopy the archive into the backup directory on the data volume and give it the owner the instance uses:
sudo cp <BACKUP_NAME>_gitlab_backup.tar /srv/code/data/backups/ docker exec code chown git:git /var/opt/gitlab/backups/<BACKUP_NAME>_gitlab_backup.tarStop the services that write to the database:
docker exec code gitlab-ctl stop puma docker exec code gitlab-ctl stop sidekiqRestore the data. The command asks for confirmation twice, before the
authorized_keysfile is rebuilt and before the current database tables are dropped; answeryesboth times:docker exec -it code gitlab-backup restore BACKUP=<BACKUP_NAME>Apply the database migrations of Deckhouse Code:
docker exec code gitlab-rake db:migrateRestart the container and check the instance:
docker restart code docker exec code gitlab-rake gitlab:fe:secret:verify docker exec code gitlab-rake gitlab:check SANITIZE=true
Install Deckhouse Code as described in Quick start, with the release named code in the code namespace and object storage for backups configured.
Convert the
gitlab_railssection ofgitlab-secrets.jsoninto the Rails secrets file and replace the Secret of the release with it:yq -p json -o yaml '{"production": .gitlab_rails}' gitlab-secrets.json > secrets.yml d8 k -n code create secret generic code-rails-secret --from-file=secrets.yml \ --dry-run=client -o yaml | d8 k apply -f -Replace the Secret with the SSH host keys:
d8 k -n code create secret generic code-gitlab-shell-host-keys --from-file=. \ --dry-run=client -o yaml | d8 k apply -f -Run the command in a directory that holds only the
ssh_host_*files.Restart the pods so that they read the new Secrets:
d8 k -n code delete pods -l app=webservice d8 k -n code delete pods -l app=sidekiq d8 k -n code delete pods -l app=gitlab-shellUpload the archive to the backups bucket, the
global.appConfig.backups.bucketvalue.Restore the data inside the toolbox pod:
d8 k -n code exec -it deploy/code-toolbox -- backup-utility --restore -t <BACKUP_NAME>Apply the database migrations of Deckhouse Code:
d8 k -n code exec -it deploy/code-toolbox -- gitlab-rake db:migrateRestart the pods and check the instance:
d8 k -n code delete pods -l app=webservice d8 k -n code delete pods -l app=sidekiq d8 k -n code exec -it deploy/code-toolbox -- gitlab-rake gitlab:fe:secret:verify d8 k -n code exec -it deploy/code-toolbox -- gitlab-rake gitlab:check SANITIZE=true
d8-code namespace. The procedure is described in the Migration section of the module documentation; the Linux package installation of GitLab named there is the GitLab CE instance.After the migration
Point the DNS name of the instance at Deckhouse Code when it runs on another server, then check the instance and finish the move:
- Sign in to the web interface with an account of GitLab CE and clone a repository over HTTPS and over SSH.
- Install the license key as described in License. Without a key, the instance runs in trial mode.
- When the external address has changed, update the
urlsetting of every GitLab Runner in/etc/gitlab-runner/config.tomland restart the runner withgitlab-runner restart.
A pipeline keeps the CI_SERVER_URL, CI_PROJECT_URL and other CI_* variables of the moment it was created. When the address has changed, a retried job of a pipeline created before the migration uses the old address; run a new pipeline instead.