В данной статье подробно разберем пример переезда GitLab с omnibus-установки в docker-установку с сохранением всех данных — репозиториев, мерджей, комментариев, артефактов и билдов (если такие есть). Давайте разберемся!
Итак, имеем неактуальную omnibus-установку GitLab из пакета gitlab-ce_10.6.4-ce.0_amd64.deb, например на debian7 это последняя версия из пакетов. Хотим получить актуальную версию (14.5.0-ce.0), установленную в docker-контейнере, для простоты обновления в будущем.
Сначала делаем резервную копию omnibus-установки GitLab:
sudo gitlab-rake gitlab:backup:create
Для создания копии без одного из этих компоненетов
- db (database)
- uploads (attachments)
- repositories (Git repositories data)
- builds (CI job output logs)
- artifacts (CI job artifacts)
- lfs (LFS objects)
- registry (Container Registry images)
- pages (Pages content)
например без registry
gitlab-rake gitlab:backup:create SKIP=registry
По умолчанию резервная копия будет создана в каталоге /var/opt/gitlab/backups.
При создании резервных копий Gitlab бекапятся все git-репозитории, загруженные файлы и база данных. SSH-ключи не бекапятся, следует помнить об этом!
sudo gitlab-rake gitlab:backup:create```
Далее очень важный момент - если вы не хотите чтобы ваши ci-variables поломалась и выдавали 500 при доступе к ним то надо сделать еще их экспорт с помощью скрипта. Читаем тут.
```sh
https://github.com/sameersbn/docker-gitlab/issues/1497
</code></pre>
<p>Сам скрипт сохранения переменных. Его надо выполнить на старом гите.</p>
<pre><code class="language-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. Допустим у нас была версия 14.5.0 и не может она больше обновляться по разным причинам.
Создадим необходимые директории.
mkdir -p /docker-compose/SWARM/services/gitlab
cd /docker-compose/SWARM/services/gitlab
mkdir -p {data/gitlab/configs,data/gitlab/logs,data/gitlab/data}
Отредактируем(создадим) конфиг
cd /docker-compose/SWARM/services/gitlab
vim data/gitlab/config/gitlab.rb
Вставим содержимое
external_url 'https://gitlab.itc-life.ru'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
gitlab_rails['backup_keep_time'] = 14515200
gitlab_rails['gitlab_email_display_name'] = 'gitlab Administrator'
gitlab_rails['gitlab_email_reply_to'] = 'gitlab@mail.linux2be.com'
gitlab_rails['gitlab_email_from'] = 'gitlab@mail.linux2be.com'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "mail.linux2be.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "gitlab@mail.linux2be.com"
gitlab_rails['smtp_password'] = "gitlab_USER_PASSWORD"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'none'
gitlab_rails['smtp_force_ssl'] = false
gitlab_rails['incoming_email_enabled'] = true
gitlab_rails['incoming_email_address'] = "gitlab@mail.linux2be.com"
gitlab_rails['incoming_email_email'] = "gitlab@mail.linux2be.com"
gitlab_rails['incoming_email_password'] = "gitlab_USER_PASSWORD"
gitlab_rails['incoming_email_host'] = "mail.linux2be.com"
gitlab_rails['incoming_email_port'] = 993
gitlab_rails['incoming_email_ssl'] = true
gitlab_rails['incoming_email_start_tls'] = false
gitlab_rails['incoming_email_mailbox_name'] = "inbox"
gitlab_rails['incoming_email_idle_timeout'] = 60
gitlab_rails['incoming_email_ssl_verify'] = true
gitlab_rails['incoming_email_delivery_method'] = "sidekiq"
gitlab_rails['service_desk_email_delivery_method'] = "sidekiq"
gitlab_rails['smtp_tls'] = false
#unicorn['worker_timeout'] = 60
#unicorn['worker_processes'] = 3
logging['logrotate_frequency'] = "weekly"
logging['logrotate_rotate'] = 52
logging['logrotate_compress'] = "compress"
logging['logrotate_method'] = "copytruncate"
logging['logrotate_delaycompress'] = "delaycompress"
nginx['logrotate_frequency'] = "weekly"
nginx['logrotate_rotate'] = 52
nginx['logrotate_compress'] = "compress"
nginx['logrotate_method'] = "copytruncate"
nginx['logrotate_delaycompress'] = "delaycompress"
# Add any other gitlab.rb configuration options if desired
registry_external_url 'https://gitlab.itc-life.ru:4568'
registry_nginx['enable'] = true
registry_nginx['listen_port'] = 4568
registry_nginx['ssl_certificate'] = "/etc/letsencrypt/live/gitlab.itc-life.ru/fullchain.pem"
registry_nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/gitlab.itc-life.ru//privkey.pem"
nginx['listen_port'] = 80
nginx['listen_https'] = false
prometheus_monitoring['enable'] = false
pages_external_url 'http://gitpages.gitlab.itc-life.ru/'
gitlab_pages['inplace_chroot'] = true
gitlab_workhorse['auth_socket'] = '/var/tmp/gitlab-rails/sockets/gitlab.socket'
nano docker-compose.yml
#docker stack deploy --compose-file=docker-compose.yml gitlab
version: '3.4'
services:
gitlab:
image: gitlab/gitlab-ce:14.5.0-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"
- "/docker-compose/SWARM/certbot/etc/letsencrypt:/etc/letsencrypt" # дира где хранятся cert's - для registry
networks:
gitlab-net:
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]
networks:
gitlab-net:
driver: overlay
ipam:
driver: default
Запускаем gitlab. Обращаем внимание на версию gitlab указанную в docker-compose файле – она должна быть той версии, что и omnibus установка.
docker-compose swarm init
docker stack deploy -c docker-compose.yml gitlab
Или если не swarm
docker-compose up -d
Теперь копируем созданный ранее бэкап из /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 cp gitlab-secrets.json $(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
cp /var/opt/gitlab/backups/gitlab-secrets.json /etc/gitlab/
gitlab-ctl start
gitlab-rake gitlab:check SANITIZE=true
После восстановления проверим возможность логина в браузере, если все работает, то идем дальше.
Останавливаем и удаляем docker-контейнер с GitLab:
cd /docker-compose/SWARM/services/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:14.5.0-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"
- "/docker-compose/SWARM/certbot/etc/letsencrypt:/etc/letsencrypt" # дира где хранятся cert's - для registry
networks:
gitlab-net:
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]
networks:
gitlab-net:
driver: overlay
ipam:
driver: default
Делаем 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/services/gitlab/data/gitlab/data"
GITLAB_CONFIG_DIR="/docker-compose/SWARM/services/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