В данной статье подробно разберем пример переезда GitLab с omnibus-установки в docker-установку с сохранением всех данных — репозиториев, мерджей, комментариев, артефактов и билдов (если такие есть). Давайте разберемся!
Итак, имеем неактуальную omnibus-установку GitLab из пакета gitlab-ce_10.6.4-ce.0_amd64.deb, например на debian7 это последняя версия из пакетов. Хотим получить актуальную версию (11.2.1-ce.0), установленную в docker-контейнере, для простоты обновления в будущем.
Сначала делаем резервную копию omnibus-установки GitLab:
sudo gitlab-rake gitlab:backup:create```
Для создания копии без одного из этих компоненетов
<ul>
<li>db (database)</li>
<li>uploads (attachments)</li>
<li>repositories (Git repositories data)</li>
<li>builds (CI job output logs)</li>
<li>artifacts (CI job artifacts)</li>
<li>lfs (LFS objects)</li>
<li>registry (Container Registry images)</li>
<li>pages (Pages content)</li>
</ul>
например без registry
```sh
gitlab-rake gitlab:backup:create SKIP=registry</code></pre>
<p>По умолчанию резервная копия будет создана в каталоге /var/opt/gitlab/backups.</p>
<p>При создании резервных копий Gitlab бекапятся все git-репозитории, загруженные файлы и база данных. SSH-ключи не бекапятся, следует помнить об этом!</p>
<pre><code class="language-sh">sudo gitlab-rake gitlab:backup:create```
Далее очень важный момент - если вы не хотите чтобы ваши ci-variables поломалась и выдавали 500 при доступе к ним то надо сделать еще их экспорт с помощью скрипта. Читаем тут.
```sh
https://github.com/sameersbn/docker-gitlab/issues/1497```
Сам скрипт сохранения переменных. Его надо выполнить на старом гите.
```sh
#!/usr/bin/env ruby
require 'pry'
require 'gitlab'
require 'terminal-table'
require 'yaml'
Gitlab.endpoint = 'https://<gitlab url>/api/v4'
Gitlab.private_token = '<administrator token>'
projects = Gitlab.projects(order_by: 'id')
projects.auto_paginate do |project|
begin
variables = Gitlab.variables(project.id)
project_vars = {}
variables.auto_paginate do |variable|
project_vars[variable.key] = variable.value
end
unless project_vars.empty?
puts project.name
File.open("dump/#{project.id}.yml", 'w') { |f| f.write(YAML.dump(project_vars)) }
end
rescue
next
end
end</code></pre>
<p>Потом делай upgrade и перенос. Затем делаем восстановление, предварительно чикнув их в базе(ci-variables).
В докере с гитом</p>
<pre><code class="language-sh">docker exec -ti -u 0 имя_контейнера sh -c "stty rows 50 && stty cols 150 && bash"```
делаем
```sh
gitlab-rails dbconsole
delete from ci_variables;
Скрипт восстановления
#!/usr/bin/env ruby
require 'pry'
require 'gitlab'
require 'terminal-table'
require 'yaml'
Gitlab.endpoint = 'https://<gitlab url>/api/v4'
Gitlab.private_token = '<administrator token>'
Dir.chdir('dump')
Dir.glob('*.yml') do |item|
variables = YAML.load(File.read(item))
variables.each do |variable|
puts File.basename(item, ".*")
Gitlab.create_variable(File.basename(item, ".*"), variable[0], variable[1])
end
end
Из docker-образа устанавливаем GitLab той же версии, что и в omnibus-установке. Сделаем все красиво через docker-compose. Допустим у нас была версия 10.6.4 и не может она больше обновляться по разным причинам – например из-за РКН, или у вас старая дебиан на которую нельзя накатить обновления.
Создадим необходимые директории.
mkdir -p /docker-compose/SWARM/gitlab
cd /docker-compose/SWARM/gitlab
mkdir -p {data/gitlab/configs,data/gitlab/logs,data/gitlab/data}
nano docker-compose.yml
#docker stack deploy --compose-file=docker-compose.yml gitlab
version: '3.4'
services:
gitlab:
image: gitlab/gitlab-ce:10.6.4-ce.0
ports:
- "10080:80"
- "2224:22"
- "4567:4567"
volumes:
- "./data/gitlab/config:/etc/gitlab"
- "./data/gitlab/logs:/var/log/gitlab"
- "./data/gitlab/data:/var/opt/gitlab"
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://git.itс-life.ru'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
networks:
gitlab-net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
aliases:
- gitlab.itc-life.ru
deploy:
mode: replicated
replicas: 1
resources:
limits:
cpus: '2'
memory: 3096M
reservations:
memory: 16M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 20s
update_config:
parallelism: 1
delay: 10s
failure_action: continue
monitor: 5s
max_failure_ratio: 0.3
placement:
constraints: [node.role == manager]
redis:
image: redis:5.0-rc-alpine
restart: always
networks:
gitlab-net:
ipv4_address: 172.16.238.11
ipv6_address: 2001:3984:3989::11
aliases:
- redist
deploy:
mode: replicated
replicas: 1
resources:
limits:
cpus: '2'
memory: 1024M
reservations:
memory: 16M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 20s
update_config:
parallelism: 1
delay: 10s
failure_action: continue
monitor: 5s
max_failure_ratio: 0.3
placement:
constraints: [node.role == manager]
networks:
gitlab-net:
driver: overlay
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
- subnet: 2001:3984:3989::/64
Запускаем gitlab. Обращаем внимание на версию gitlab указанную в docker-compose файле – она должна быть той версии, что и omnibus установка.
docker-compose swarm init
docker stack deploy -c docker-compose.yml gitlab
Теперь копируем созданный ранее бэкап из /var/opt/gitlab/backups/ в докер контейнер gitlab по такому же пути /var/log/gitlab.
В данном случаем
cd /var/opt/gitlab/backups/
docker cp 1528576316_2018_06_10_10.6.4_gitlab_backup.tar $(docker ps | grep gitlab_gitlab | awk '{print $1}'):/var/opt/gitlab/backups/
Опционально: изменим права доступа и владельца файла с бекапом внутри контейнера, на случай если он скопировался неправильно:
docker exec -ti $(docker ps | grep gitlab_gitlab | awk '{print $1}') bash
cd /var/opt/gitlab/backups/
chmod 600 *
chown git:git *
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
gitlab-rake gitlab:backup:restore BACKUP=1528576316_2018_06_10_10.6.4
gitlab-ctl start
gitlab-rake gitlab:check SANITIZE=true
После восстановления проверим возможность логина в браузере, если все работает, то идем дальше.
Останавливаем и удаляем docker-контейнер с GitLab:
cd /docker-compose/SWARM/gitlab
docker stack rm gitlab
Правим docker-compose. Изменим версию gitlab на последнюю.
nano docker-compose.yml
#docker stack deploy --compose-file=docker-compose.yml gitlab
services:
gitlab:
image: gitlab/gitlab-ce:11.2.1-ce.0
ports:
- "10080:80"
- "2224:22"
- "4567:4567"
volumes:
- "./data/gitlab/config:/etc/gitlab"
- "./data/gitlab/logs:/var/log/gitlab"
- "./data/gitlab/data:/var/opt/gitlab"
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://git.itс-life.ru'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
networks:
gitlab-net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
aliases:
- gitlab.itc-life.ru
deploy:
mode: replicated
replicas: 1
resources:
limits:
cpus: '2'
memory: 3096M
reservations:
memory: 16M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 20s
update_config:
parallelism: 1
delay: 10s
failure_action: continue
monitor: 5s
max_failure_ratio: 0.3
placement:
constraints: [node.role == manager]
redis:
image: redis:5.0-rc-alpine
restart: always
networks:
gitlab-net:
ipv4_address: 172.16.238.11
ipv6_address: 2001:3984:3989::11
aliases:
- redist
deploy:
mode: replicated
replicas: 1
resources:
limits:
cpus: '2'
memory: 1024M
reservations:
memory: 16M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 20s
update_config:
parallelism: 1
delay: 10s
failure_action: continue
monitor: 5s
max_failure_ratio: 0.3
placement:
constraints: [node.role == manager]
networks:
gitlab-net:
driver: overlay
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
- subnet: 2001:3984:3989::/64
Делаем pull
docker-compose pull```
Запускаем gitlab.
```sh
docker stack deploy -c docker-compose.yml gitlab
Ну а теперь запускаемся с новой версией и ждем пока пройдет процесс обновления. Наблюдаеть за ним можно так:
docker service logs -f --tail 100 $(docker service ls | grep gitlab_gitlab | awk '{print $1}')
Gitlab nginx proxy config
upstream gitlab {
server 10.28.0.1:10080;
}
# let gitlab deal with the redirection
server {
listen 80;
server_name
git.linux2be.com
;
root /dev/null;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name
git.linux2be.com
;
server_tokens off;
root /dev/null;
include /etc/nginx/ssl.d/linux2be.com/ssl.linux2be.com.conf;
location / {
#include git-access.conf;
## If you use https make sure you disable gzip compression
## to be safe against BREACH attack.
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://gitlab;
}
}
server {
listen 50445 ssl http2;
server_name
git.linux2be.com
;
server_tokens off;
root /dev/null;
include /etc/nginx/ssl.d/linux2be.com/ssl.linux2be.com.conf;
location / {
#include git-access.conf;
## If you use https make sure you disable gzip compression
## to be safe against BREACH attack.
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_set_header Host $http_host;
#proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://gitlab;
}
}
# let gitlab deal with the redirection
server {
listen 80;
server_name
gitpages.linux2be.com
*.gitpages.linux2be.com
;
server_tokens off;
#access_log off;
root /dev/null;
location / {
return 301 https://$host$request_uri;
#return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name
gitpages.linux2be.com
*.gitpages.linux2be.com
;
server_tokens off;
root /dev/null;
include /etc/nginx/ssl.d/gitpages.linux2be.com/ssl.gitpages.linux2be.com.conf;
location / {
#include git-access.conf;
## If you use https make sure you disable gzip compression
## to be safe against BREACH attack.
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://gitlab;
}
}
Скрипт бэкапа Gitlab из докера. Поправьте под себя.
#!/bin/bash
GITLAB_DATA_DIR="/docker-compose/SWARM/gitlab/data/gitlab/data"
GITLAB_CONFIG_DIR="/docker-compose/SWARM/gitlab/data/gitlab/config"
BACKUP_DIR_GITLAB="${GITLAB_DATA_DIR}/backups"
REMOTE_DIR="BACKUP-GIT"
BACKUP_OPTIONS="SKIP=registry"
BACKUP_DIR="/bup/app/gitlab"
DATE=$(date "+%Y_%m_%d")
backup_gitlab() {
docker exec -i $(docker ps | grep 'gitlab-ce' | awk '{print $NF}') gitlab-rake gitlab:backup:create CRON=1 ${BACKUP_OPTIONS};
if [[ ! -d "${BACKUP_DIR}/${DATE}" ]];then
mkdir -p "${BACKUP_DIR}/${DATE}"
fi
rsync -aPzv ${BACKUP_DIR_GITLAB}/ ${BACKUP_DIR}/${DATE}/
rsync -aPzv ${GITLAB_CONFIG_DIR}/gitlab-secrets.json ${BACKUP_DIR}/${DATE}/
}
delete_old_backups(){
/usr/bin/find "${BACKUP_DIR_GITLAB}" -type f -name '*.tar' -exec rm {} \;
/usr/bin/find "${BACKUP_DIR}" -type f -name '*.tar' -mtime +10 -exec rm {} \;
}
main() {
backup_gitlab
delete_old_backups
}
main