GitLab的安装和升级, 一把辛酸泪

警告:

gitlab 提供了一键安装包, 这种从 source 编译的方法并不有趣, 每次升级和改配置都极其麻烦, 它只会浪费你现在以及预期的未来的生命, 要是打算用它做生产环境, 那绝对是你的不智

在 gitlab 早期, 并没有那么好的条件, 因为历史原因才被迫这么做的. 本文作为历史存档, 仅作为参考, 主要目的是记录一段过去的血泪教训.

更新了下 gitlab. 留个 log. 安装可以按照说明文档 https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md, 若是6.x升级到7.14, 可以使用这个文档: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/6.x-or-7.x-to-7.14.md , 若7.14升级到8.0, 则可以使用这个文档: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/7.14-to-8.0.md. 一步一步走下去, 介绍得非常好. 本文也毫无意愿去吧内容翻译一下. 只是介绍下错误的处理.

1. bunder的被墙处理

# sudo -u git -H bundle install --without postgres development test --deployment
Fetching source index from https://rubygems.org/

用 bundle 安装会遇到这样的问题: 卡在了上述fetch的位置. 原因是被墙了.可以使用淘宝的镜像.

方法是:

# sudo -u git -H gem sources --remove https://rubygems.org/
# sudo -u git -H gem sources -a https://ruby.taobao.org/
# sudo -u git -H bundle config mirror.https://rubygems.org https://ruby.taobao.org

重新执行效果是:

# sudo -u git -H bundle install --without postgres development test --deployment
Fetching source index from https://ruby.taobao.org/

不过 bundle 体验不咋滴, 无论如何都会卡死一段时间, 然后显示

# sudo -u git -H bundle install --without postgres development test --deployment
Fetching source index from https://ruby.taobao.org/
Using sass 3.2.19
Using thor 0.19.1
Using mime-types 1.25.1
Using tilt 1.4.1
Using ace-rails-ap 2.0.1
Using hike 1.2.3
Using colored 1.2
....

2. mysql错误(简直要疯)

错误如下:

...
-- add_index(:oauth_applications, :uid, {:unique=>true})
rake aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Specified key was too long; max key length is 767 bytes: CREATE UNIQUE INDEX `index_oauth_applications_on_uid` ON `oauth_applications` (`uid`) /home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:303:in `query'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:303:in `block in execute'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/abstract_adapter.rb:378:in `block in log'
/home/git/gitlab/vendor/bundle/ruby/gems/activesupport-4.1.12/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/abstract_adapter.rb:372:in `log'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:303:in `execute'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/mysql2_adapter.rb:228:in `execute'
/home/git/gitlab/config/initializers/connection_fix.rb:20:in `execute'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:525:in `add_index'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:656:in `block in method_missing'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:628:in `block in say_with_time'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:628:in `say_with_time'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:648:in `method_missing'
/home/git/gitlab/db/migrate/20141216155758_create_doorkeeper_tables.rb:12:in `change'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:602:in `exec_migration'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:586:in `block (2 levels) in migrate'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:585:in `block in migrate'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/connection_adapters/abstract/connection_pool.rb:294:in `with_connection'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:584:in `migrate'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:759:in `migrate'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:998:in `block in execute_migration_in_transaction'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:1046:in `ddl_transaction'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:997:in `execute_migration_in_transaction'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:959:in `block in migrate'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:955:in `each'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:955:in `migrate'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:814:in `up'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/migration.rb:792:in `migrate'
/home/git/gitlab/vendor/bundle/ruby/gems/activerecord-4.1.12/lib/active_record/railties/databases.rake:34:in `block (2 levels) in '
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

关键词是:

Mysql2::Error: Specified key was too long; max key length is 767 bytes: CREATE UNIQUE INDEX `index_oauth_applications_on_uid` ON `oauth_applications` (`uid`)

我们可以看到这个, 这个和这个的介绍.

大致意思是有若干种 workaround 方法:

不用 InnoDB 而用 MyISAM

改 Schema, 用 innodb_large_prefix

改 Charset, 用 innodb_large_prefix

换成 PostgreSQL

对我亲爱的 mariadb 进行五个小时的拼搏, 各种尝试后表示–卒…

那么就选择我最不想做的, 使用 PostgreSQL 吧.

因为 mysql 已经被污染了, 所以首先要滚回去, 让数据保持干净.

在最开始的时候, 备份的数据帮大忙了:

cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production

而 restore 也要先滚回当时版本.

sudo -u git -H git checkout v7.4.3 # 也就是我之前的版本
sudo -u git -H bundle install --without development test postgres --deployment # 更新下mysql版本的bundle
sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production # 执行回滚

漫长的等待后,一切滚回了最初样子.

然后开始准备 psql. 若没有配置过 psql, 那么可以参考此处.

一堆安装后( CentOS 用 yum, Ubuntu 用 apt-get )

# Login to PostgreSQL
sudo -u postgres psql -d template1

# Create a user for GitLab
# Do not type the 'template1=#', this is part of the prompt
template1=# CREATE USER git CREATEDB;

# Create the GitLab production database & grant all privileges on database
template1=# CREATE DATABASE gitlabhq_production OWNER git;

# Quit the database session
template1=# \q

# Try connecting to the new database with the new user
sudo -u git -H psql -d gitlabhq_production

# Quit the database session
gitlabhq_production> \q

这样就算初始化了一个 psql.

然后参考此处. 从已有 mysql 中导出数据到 psql.

git clone https://github.com/gitlabhq/mysql-postgresql-converter.git -b gitlab
cd mysql-postgresql-converter
mysqldump --compatible=postgresql --default-character-set=utf8 -r gitlabhq_production.mysql -u root gitlabhq_production -p
python db_converter.py gitlabhq_production.mysql gitlabhq_production.psql
ed -s gitlabhq_production.psql < move_drop_indexes.ed

# Import the database dump as the application database user
sudo -u git psql -f gitlabhq_production.psql -d gitlabhq_production

然后重新把工程升级为期望的版本(7.14.x or 8.0.x)

cd /home/git/gitlab
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
sudo -u git -H git checkout 7-14-stable # for 一个 exmaple

# PostgreSQL installations (note: the line below states '--without ... mysql')
sudo -u git -H bundle install --without development test mysql --deployment #这次是psql版本了

这时候,可以吧 备份后,替换成同目录下的 database.yml.postgresql

sudo -u git -H mkdir -p ~/backup/gitlab/config/
sudo -u git -H mv ~git/gitlab/config/database.yml ~/backup/gitlab/config/database.yml
sudo -u git -H cp ~git/gitlab/config/database.yml.postgresql ~git/gitlab/config/database.yml

然后继续数据更新

# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production

# Enable internal issue IDs (introduced in GitLab 6.1)
sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production

# Clean up assets and cache
sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production

# Close access to gitlab-satellites for others
sudo chmod u+rwx,g+rx,o-rwx /home/git/gitlab-satellites

# Update init.d script
sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab