Pull to refresh

Миграция Redmine на новую версию и одновременно в Docker

Возникла необходимость поставить на Redmine, которым мы пользуемся уже несколько лет, плагин для agile. Redmine хоть и старый (версия 2.4), но в доке от RedmineUP(redmine_agile) указано, что он поддерживает версии с 2.1 по 3.3. То есть должен встать. Но не тут то было.




Пойдя простым путем, то есть действуя по инструкции, закинул плагин в нужную папку, запустил:

bundle install --without development test --no-deployment
bundle exec rake redmine:plugins NAME=[plugin_name] RAILS_ENV=production

Но каменный цветок не вышел. Rake abort вышел. И еще на две экрана выдал ругательств. Покурив много форумов, помучив гугл, и перепробовав разные способы, так и не смог победить этот аборт. Попробовал обновить Redmine (думал в этом проблема), но и обновляться он не захотел.
Так как на Ruby я не спец, то вникать в проблему можно было очень долго. Тут и пришла спасительная мысль — а не попробовать ли Redmine развернуть в Docker'е? Сказано — сделано. Посмотрел какие есть в репозитории образы Redmine, взял sameersbn/redmine и образ для базы sameersbn/mysql. Очень подробный мануал от автора образа: https://github.com/sameersbn/docker-redmine.

Делаем pull образов, запускаем и проверяем, что все работает.

MySql

sudo docker run --name=mysql-redmine -d \
 --env-file=/srv/docker/redmine/config.mysql \
 --volume=/srv/docker/redmine/mysql:/var/lib/mysql \
  sameersbn/mysql

Подключаем volume на хосте /srv/docker/redmine/mysql для хранения базы. Конфиг для переменных среды выносим в файл «config.mysql»:

DB_NAME=redmine_production
DB_USER=redmine
DB_PASS=somepass

Redmine

sudo docker run --name=redmine -it --rm --link=mysql-redmine:mysql \
 --publish=80:80 --publish 443:443 \
 --env-file=/srv/docker/redmine/config.redmine \
 --volume=/srv/docker/redmine/redmine:/home/redmine/data \ 
 sameersbn/redmine

Делаем линк в контейнер с базой. Публикуем порты 80 и 443 (можно только 443 оставить). Подключаем volume /srv/docker/redmine/redmine для хранения файлов редмайна на хосте. Конфиг выносим в «config.redmine»:

REDMINE_PORT=443
REDMINE_HTTPS=true
SMTP_METHOD=smtp
SMTP_HOST=yourhost
SMTP_ENABLED=true
SMTP_PORT=25
SMTP_DOMAIN=yourdomain

Переменных довольно много можно использовать, весь список у автора образа подробно расписан (спасибо ему, очень качественный readme сделал).

Заводится все с полпинка, при первом старте обновляется схема базы данных. Логинимся в новый инстанс Redmine как admin/admin. Меняем пароль.

Закидываем в папку /srv/docker/redmine/redmine/plugins на хосте нужный нам agile плагин. Перезапускаем образ редмайна. Плагин подхватывается и замечательно работает. Очень хорошо, можно пить кофе и переносить базу со старого редмайна в новый. Делаем дамп старой базы:

/usr/bin/mysqldump -u root -p redmine_default > /home/admin/redmine_sql

Редактируем дамп redmine_sql (так как название базы у нас поменялось), вставляем первой строкой в файле:

use redmine_production;

Копируем дамп в расшаренный volume на хосте /srv/docker/redmine/mysql. Импортируем дамп в новый инстанс mysql в контейнере:

sudo docker exec -ti mysql-redmine /bin/bash
mysql -u redmine -p < /var/lib/mysql/redmine_sql

Кажется, что победа уже близко. В браузере заходим по нужному адресу. Страница отображается. Логинимся в Redmine под админом. И упс… Error 500.

Ну мы не такие наивные, чтобы верить, будто все заработает с первого раза. Нас этим не обломаешь. Смотрим логи. Снова читаем, что умные люди пишут в интернетах. Ага, надо при миграции на новую версию редмайна обновить схему базы. Делаем:

sudo docker exec -ti redmine /bin/bash
bundle exec rake db:migrate RAILS_ENV=production

Частично скрипт отрабатывает успешно, но потом вылетает с ошибкой «не могу создать таблицу такую-то, она уже существует». Смотрим, что за таблица, лезем в контейнер с базой, удаляем вредную таблицу. И так несколько раз подряд. Итого удалил следующие:

sudo docker exec -ti mysql-redmine /bin/bash
mysql -u redmine -p 
use redmine_production;
drop table email_addresses;
drop table import_items;
drop table imports;
drop table roles_managed_roles;
drop table custom_field_enumerations;

После этого снова обновляем схему из контейнера с редмайном:

sudo docker exec -ti redmine /bin/bash
bundle exec rake db:migrate RAILS_ENV=production

Обновляется без ошибок. Рестартуем образ редмайна. Заходим на страницу, логинимся и вуаля!
Все работает.

Дальше остается полировка. Настраиваем автозапуск контейнеров при старте ОС. Пишем конфиг запуска в systemd:

Redmine:

nano /etc/systemd/system/docker.redmine.service

[Unit]
Description=Redmine Service
After=docker.service
Requires=docker.service
After=docker.mysql.service
Requires=docker.mysql.service

[Service]
TimeoutStartSec=10
Restart=on-failures
ExecStartPre=-/usr/bin/docker stop redmine
ExecStart=/usr/bin/docker run --name=redmine --rm --link=mysql-redmine:mysql \
 --publish=80:80 --publish 443:443 \
 --env-file=/srv/docker/redmine/config.redmine \
 --volume=/srv/docker/redmine/redmine:/home/redmine/data sameersbn/redmine

[Install]
WantedBy=multi-user.target

Мы запускаем контейнер из образа и после прекращения работы удаляем его.

MySql:

nano /etc/systemd/system/docker.mysql.service

[Unit]
Description=Mysql Service
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
Restart=on-failures
ExecStartPre=-/usr/bin/docker stop mysql-redmine
ExecStart=/usr/bin/docker start mysql-redmine 

[Install]
WantedBy=multi-user.target

Контейнер с базой просто стартуем, он у нас не удаляется при выключении.

Включаем сервисы:

systemctl enable docker.redmine.service
systemctl enable docker.mysql.service

Рестартуем ОС, проверяем, все поднялось и работает. Миграция с Redmine 2.4 до 3.3 с переездом в Docker и установкой плагина agile завершилась успешно.

Итого имеем:

Environment:
Redmine version 3.3.2.stable
Ruby version 2.1.9-p490 (2016-03-30) [x86_64-linux-gnu]
Rails version 4.2.7.1
Environment production
Database adapter Mysql2
SCM:
Subversion 1.8.8
Darcs 2.8.4
Mercurial 2.8.2
Cvs 1.12.13
Bazaar 2.7.0
Git 2.11.0
Filesystem
Redmine plugins:
redmine_agile 1.4.3
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.