doc/install/docker/migrate.md
{{< details >}}
{{< /details >}}
Migrate your existing Linux package GitLab instance to Docker using one of two approaches:
Migrate a Linux package GitLab instance to Docker by reusing existing data directories.
Stop all GitLab services:
sudo gitlab-ctl stop
How you prepare the volume directories depends on where Docker runs:
If Docker runs on the same server as the Linux package instance, you can mount the existing directories directly without copying them. Set the volume paths in your Docker Compose file to the Linux package locations:
volumes:
- '/etc/gitlab:/etc/gitlab'
- '/var/log/gitlab:/var/log/gitlab'
- '/var/opt/gitlab:/var/opt/gitlab'
If you are moving to a different server, or want to keep the Docker volumes separate from the Linux package paths, copy the directories to a new location first.
Set $GITLAB_HOME to the target directory:
export GITLAB_HOME=/srv/gitlab
sudo mkdir -p $GITLAB_HOME
Copy (or move) the data, logs, and configuration directories:
sudo cp -a /var/opt/gitlab $GITLAB_HOME/data
sudo cp -a /var/log/gitlab $GITLAB_HOME/logs
sudo cp -a /etc/gitlab $GITLAB_HOME/config
To move instead of copy, use mv instead of cp -a.
[!warning] Do not change the ownership of the host directories to
root:rootbefore starting the container. Doing so prevents the container from starting, and prevents theupdate-permissionsscript from correcting ownership afterwards.
Verify that the repository directory exists and is a real directory, not a broken symlink:
ls -la $GITLAB_HOME/data/git-data/repositories
If the directory is missing or a broken symlink, create it:
sudo mkdir -p $GITLAB_HOME/data/git-data/repositories
The GitLab Docker image includes a built-in script called update-permissions that sets
correct ownership on all GitLab directories. If the Linux package instance used different
UIDs than the Docker image expects (either OS defaults that vary by distribution, or
explicitly configured values),
run update-permissions from a temporary container with your volumes mounted before
starting the container. This corrects ownership before the first start:
docker run --rm \
-v <config_path>:/etc/gitlab \
-v <logs_path>:/var/log/gitlab \
-v <data_path>:/var/opt/gitlab \
--entrypoint /bin/bash \
gitlab/gitlab-ee:<version> \
-c "update-permissions"
Replace <config_path>, <logs_path>, and <data_path> with the host paths you
identified in Prepare the volume directories.
Follow the installation instructions to create a Docker Compose file or Docker Engine command that mounts the directories you prepared:
volumes:
- '$GITLAB_HOME/config:/etc/gitlab'
- '$GITLAB_HOME/logs:/var/log/gitlab'
- '$GITLAB_HOME/data:/var/opt/gitlab'
After the container starts, run reconfigure:
docker exec -it <container_name> gitlab-ctl reconfigure
Verify the installation:
docker exec -it <container_name> gitlab-rake gitlab:check
Before you stop your Linux package instance, create a backup:
sudo gitlab-backup create
Copy your secrets file to a safe location:
sudo cp /etc/gitlab/gitlab-secrets.json /your/backup/location/
For more information, see Back up GitLab.
Stop all GitLab services:
sudo gitlab-ctl stop
Follow the installation instructions to set up a new Docker instance.
Set $GITLAB_HOME to the directory you create for the volumes, for example:
export GITLAB_HOME=/srv/gitlab
Start the container once to initialize the volume directories, then stop it before restoring:
docker compose up -d
docker compose stop
Copy the backup archive into the Docker data volume:
sudo cp <timestamp>_gitlab_backup.tar $GITLAB_HOME/data/backups/
Copy the secrets file into the Docker config volume:
sudo cp gitlab-secrets.json $GITLAB_HOME/config/gitlab-secrets.json
Start the container and run the restore:
docker compose start
docker exec -it <container_name> gitlab-backup restore BACKUP=<timestamp>
Reconfigure and restart after the restore completes:
docker exec -it <container_name> gitlab-ctl reconfigure
docker exec -it <container_name> gitlab-ctl restart
Verify the installation:
docker exec -it <container_name> gitlab-rake gitlab:check
When migrating a Linux package GitLab instance to Docker, you might encounter the following issues.
If the container starts but reports permission errors, run:
sudo docker exec <container_name> update-permissions
sudo docker restart <container_name>
This occurs when the Linux package instance used different UIDs for system accounts than the
Docker image expects. To prevent this, run update-permissions before starting as described in
Align user and group identifiers.
When reusing data from another instance, you might encounter the following issues.
stat: missing operand error on startupThis error occurs when the container cannot find the git-data/repositories directory:
stat: missing operand
Expected process to exit with [0], but received '1'
Ran stat --printf='%U' $(readlink -f /var/opt/gitlab/git-data/repositories) returned 1
On the host, create the missing directory, then restart the container:
sudo mkdir -p $GITLAB_HOME/data/git-data/repositories
sudo docker restart <container_name>
docker execIf the container exits immediately after starting, you cannot use docker exec to
investigate or run update-permissions. Instead, run update-permissions directly
using the same command from
Align user and group identifiers, which starts a
temporary container with your volumes mounted and corrects ownership without needing the
main container to be running.