doc/administration/dedicated/geo_migration.md
{{< details >}}
{{< /details >}}
[!note] GitLab Dedicated for Government does not support ongoing Geo replication or Geo-based failover. Geo migration for onboarding new tenants is supported, but requires a VPN connection. Contact your GitLab Dedicated for Government onboarding team to set this up.
Geo migration requires secrets from your GitLab Self-Managed primary instance so that GitLab Dedicated can decrypt your data after migration. These secrets include database encryption keys, CI/CD variables, and other sensitive configuration details.
SSH host keys are optional, but strongly recommended. Preserving them prevents SSH host key
verification failures when users run git clone or git pull over SSH after migration.
They are especially important if you plan to use your own domain.
The collection scripts use age, a file encryption tool, to securely encrypt your secrets before you upload them to Switchboard.
Collect and upload Geo migration secrets when you create your GitLab Dedicated instance.
Prerequisites:
age public key from the Geo migration secrets page in Switchboardkubectl configured with access to your GitLab cluster (Kubernetes installations only)To collect and upload migration secrets:
Sign in to Switchboard.
On the Geo migration secrets page, download the appropriate collection script for your installation type.
Optional. For offline environments, embed the age binary into the collection script before
running it. For more information, see offline environments.
Run the collection script for your installation type, and replace <age_public_key> with
the key displayed on the page:
For Linux package installations, run the following command on a Rails node:
python3 collect_secrets_linux_package.py <age_public_key>
It requires read access to /etc/gitlab/gitlab-secrets.json, /var/opt/gitlab/gitlab-rails/etc/database.yml, and /etc/ssh/.
For Kubernetes installations, run the following command from a workstation with kubectl access:
python3 collect_secrets_k8s.py <age_public_key>
To override default values, you can pass additional flags. For more information, see Kubernetes collection script flags.
Optional. To collect SSH host keys only, add the --hostkeys-only flag to the command.
The script generates:
migration_secrets.json.age: GitLab secrets (required)ssh_host_keys.json.age: SSH host keys (optional but recommended)Upload your migration_secrets.json.age file.
Optional. Upload your ssh_host_keys.json.age file.
Wait for validation to complete. Validation takes approximately 10-20 seconds per file.
Verify the filename and fingerprint displayed match your uploaded files.
[!note] Validation checks that files are properly encrypted and contain the expected structure. It does not decrypt or expose the contents of your files.
After uploading your secrets, complete the remaining steps to create your tenant.
Use these optional flags with collect_secrets_k8s.py to override default values:
| Flag | Default | Description |
|---|---|---|
--namespace NAME | Current context | Kubernetes namespace. |
--release NAME | gitlab | Helm release name prefix. |
--rails-secret NAME | None | Rails secrets secret name. |
--registry-secret NAME | None | Registry secret name. |
--postgres-secret NAME | None | Postgres password secret name. |
--hostkeys-secret NAME | None | SSH host keys secret name. |
If your GitLab Self-Managed instance doesn't have internet access, embed the age binary in the
collection script before you run it.
To set up the collection script for offline environments:
On a machine with internet access, download download_age_binaries.py and embed_age_binary.py from the
Geo secrets collection
project, and put them in the same directory as the collection script you downloaded from Switchboard.
Download and encode the age binaries:
python3 download_age_binaries.py > age_binaries.txt
The script prints base64-encoded age binaries for Linux AMD64 and ARM64 to standard output, so you
must redirect the output to age_binaries.txt.
Embed the binaries in the collection script:
python3 embed_age_binary.py
The script reads age_binaries.txt from the current directory,
and overwrites collect_secrets_linux_package.py and collect_secrets_k8s.py
with versions that include the embedded binaries.
Transfer the updated collection script to your offline environment.
Run the script on your GitLab Self-Managed instance as described in collect and upload migration secrets.
The updated script is self-contained and automatically extracts and uses the embedded age binary.
When working with Geo migration, you might encounter the following issues.
Permission denied when running the collection scriptYou might get a permission error when the collection script tries to access GitLab configuration files.
This issue occurs when the script runs without sufficient privileges to read the required files.
To resolve this issue:
root user or use sudo.kubectl context has access to the GitLab namespace.You might get an error that the script cannot locate your GitLab installation or configuration files.
This issue occurs in the following scenarios:
Common error messages include:
Error: database.yml not found: /var/opt/gitlab/gitlab-rails/etc/database.yml followed by ✗ Failed to collect GitLab secretsError: Could not retrieve gitlab-rails-secretsTo resolve this issue: