CentOS6にApache + RVM + UnicornでGitlab4.2構築
GitlabはGithubのオープンソースクローンで
プライベートリポジトリをつくることはもちろん、
ユーザ管理や公開鍵管理などをWebブラウザ上からできる、おされなツールです。
さらに、プロジェクト毎にWallやWikiが使えたり、ブランチのネットワークグラフを表示したり、マージリクエストの管理などもできます。
最近構築する機会があったのでメモ
# ただし、5.0へのメジャーアップデートでGitoliteが必要なくなるらしく、もっと簡単にインストールが済むようになるかもです。
とりあえず現時点の手順です。
極力手間をかけず、メンテもしやすいような感じで構成してみました。
メモ程度に残していたログを都合よくまとめただけなので、へんなとこあるかもです。
あしからず。
公式の手順はこちら
gitlabhq/installation.md at 4-2-stable · gitlabhq/gitlabhq · GitHub
必要そうなパッケージインストール
[mikito@nya ~]$ sudo yum -y install libyaml-devel openssl-devel gdbm-devel readline-devel ncurses-devel libffi-devel redis libxml2-devel libxslt-devel libicu-devel curl git-core openssh-server postfix
Redis起動、自動起動設定
[mikito@nya ~]$ sudo /etc/init.d/redis
[mikito@nya ~]$ sudo chkconfig redis on
[mikito@nya ~]$ chkconfig --list redis
redis 0:off 1:off 2:on 3:on 4:on 5:on 6:off
データベース設定(MySQL)
[mikito@nya ~]$ mysql -u root -p
mysql> create user 'gitlab_user'@'localhost' identified by '*******'
mysql> CREATE DATABASE IF NOT EXISTS `gitlab_db` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlab_db`.* TO 'gitlab_user'@'localhost';
System User作る
[mikito@nya ~]$ sudo adduser -r -s /bin/sh -c 'git' -d /home/git -m git
[mikito@nya ~]$ sudo adduser -r -s /bin/sh -c 'gitlab' -d /home/gitlab -m gitlab
[mikito@nya ~]$ sudo chmod g+rx /home/git
[mikito@nya ~]$ sudo usermod -a -G git gitlab
gitlabユーザのSSH Key作ってコピーしとく
[mikito@nya ~]$ sudo -u gitlab -H ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa
[mikito@nya ~]$ sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub
[mikito@nya ~]$ sudo chmod 0444 /home/git/gitlab.pub
Gitolite設定
[mikito@nya ~]$ sudo su - git -s /bin/bash # gitユーザで作業
[git@nya ~]$ git clone -b gl-v320 https://github.com/gitlabhq/gitolite.git gitolite
[git@nya ~]$ mkdir /home/git/bin
[git@nya ~]$ sh -c 'printf "%b\n%b\n" "PATH=\$PATH:/home/git/bin" "export PATH" >> /home/git/.profile'
[git@nya ~]$ sh -c 'gitolite/install -ln /home/git/bin'
[git@nya ~]$ sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub"
[git@nya ~]$ chmod 750 /home/git/.gitolite/
[git@nya ~]$ chmod -R ug+rwX,o-rwx /home/git/repositories/
[git@nya ~]$ find /home/git/repositories -type d -print0 | xargs -0 chmod g+s
list of known hostsに追加とかcloneチェックとか
[mikito@nya ~]$ sudo su - gitlab -s /bin/bash # gitlabユーザで作業
[gitlab@nya ~]$ ssh git@localhost
The authenticity of host '[127.0.0.1]:2222 ([127.0.0.1]:2222)' can't be established.
RSA key fingerprint is 24:11:23:ff:35:72:9f:e0:5e:36:5f:c4:f9:4d:c7:f8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:2222' (RSA) to the list of known hosts.
PTY allocation request failed on channel 0
hello gitlab, this is git@nya running gitolite3 v3.2-gitlab-patched-0-g2d29cf7 on git 1.7.1
...
実際に管理用のリポジトリcloneしてみる
[gitlab@nya ~]$ git clone git@localhost:gitolite-admin.git gitolite-admin
Initialized empty Git repository in /home/gitlab/gitolite-admin/.git/
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (6/6), done.
[gitlab@nya ~]$ ls
gitolite-admin
[gitlab@nya ~]$ rm -rf gitolite-admin/
Git設定
[gitlab@nya gitlab]$ git config --global user.name "Gitlab"
[gitlab@nya gitlab]$ git config --global user.email "gitlab@gitlab.mikinya.net"
RVM & Gemインストール
[gitlab@nya ~]$ curl -L --insecure https://get.rvm.io | bash -s stable --ruby
[gitlab@nya ~]$ source .bash_profile
[gitlab@nya ~]$ rvm install 1.9.3
[gitlab@nya ~]$ gem install bundler --no-rdoc --no-ri
[gitlab@nya ~]$ gem install charlock_holmes --version '0.6.9' --no-rdoc --no-ri
[gitlab@nya ~]$ rvm gemset create gitlab
[gitlab@nya ~]$ rvm use 1.9.3@gitlab --default
Gitlabインストール
[gitlab@nya ~]$ git clone https://github.com/gitlabhq/gitlabhq.git gitlab
[gitlab@nya ~]$ cd gitlab/
[gitlab@nya gitlab]$ git checkout 4-2-stable
[gitlab@nya gitlab]$ chmod -R u+rwX log/
[gitlab@nya gitlab]$ chmod -R u+rwX tmp/
[gitlab@nya gitlab]$ mkdir gitlab-satellites
[gitlab@nya gitlab]$ cp config/gitlab.yml.example config/gitlab.yml
[gitlab@nya gitlab]$ vim config/gitlab.yml # host名とか設定
[gitlab@nya gitlab]$ cp config/database.yml.mysql config/database.yml
[gitlab@nya gitlab]$ vim config/database.yml
database.yml
# # PRODUCTION # production: adapter: mysql2 encoding: utf8 reconnect: false database: gitlab_db pool: 5 username: gitlab_user password: "***********" # host: localhost # socket: /tmp/mysql.sock
unicorn設定
[gitlab@nya gitlab]$ cp config/unicorn.rb.example config/unicorn.rb
[gitlab@nya gitlab]$ vim config/unicorn.rb
unicorn.rb
# uncomment and customize to run in non-root path # note that config/gitlab.yml web path should also be changed # ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" app_dir = "/home/gitlab/gitlab/" worker_processes 2 working_directory app_dir # Load app into the master before forking workers for super-fast # worker spawn times preload_app true # nuke workers after 30 seconds (60 is the default) timeout 30 # listen on a Unix domain socket and/or a TCP port, #listen 8080 # listen to port 8080 on all TCP interfaces #listen "127.0.0.1:8080" # listen to port 8080 on the loopback interface #listen "#{app_dir}/tmp/sockets/gitlab.socket" listen "127.0.0.1:8080", :tcp_nopush => true pid "#{app_dir}/tmp/pids/unicorn.pid" stderr_path "#{app_dir}/log/unicorn.stderr.log" stdout_path "#{app_dir}/log/unicorn.stdout.log" # http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow if GC.respond_to?(:copy_on_write_friendly=) GC.copy_on_write_friendly = true end before_fork do |server, worker| # the following is highly recomended for Rails + "preload_app true" # as there's no need for the master process to hold a connection defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! ## # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and # immediately start loading up a new version of itself (loaded with a new # version of our app). When this new Unicorn is completely loaded # it will begin spawning workers. The first worker spawned will check to # see if an .oldbin pidfile exists. If so, this means we've just booted up # a new Unicorn and need to tell the old one that it can now die. To do so # we send it a QUIT. # # Using this method we get 0 downtime deploys. old_pid = "#{server.config[:pid]}.oldbin" if File.exists?(old_pid) && server.pid != old_pid begin sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU Process.kill(sig, File.read(old_pid).to_i) rescue Errno::ENOENT, Errno::ESRCH # someone else did our job for us end end end after_fork do |server, worker| # Unicorn master loads the app then forks off workers - because of the way # Unix forking works, we need to make sure we aren't using any of the parent's # sockets, e.g. db connection defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection # Redis and Memcached would go here but their connections are established # on demand, so the master never opens a socket end
フックの設定
[gitlab@nya gitlab]$ cp /home/gitlab/gitlab/lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive
[gitlab@nya gitlab]$ chown git:git /home/git/.gitolite/hooks/common/post-receive
gemインストール、Migration & Setup
[gitlab@nya gitlab]$ bundle install --deployment --without development test postgres
[gitlab@nya gitlab]$ bundle exec rake gitlab:setup RAILS_ENV=production
Applicationチェック
[gitlab@nya gitlab]$ bundle exec rake gitlab:env:info RAILS_ENV=production
[gitlab@nya gitlab]$ bundle exec rake gitlab:check RAILS_ENV=production
それっぽいのが出ればOKかと
起動スクリプト設定
[mikito@nya ~]$ sudo -E curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/4-2-stable/init.d/gitlab
[mikito@nya ~]$ sudo vim /etc/init.d/gitlab #RVMの環境変数の設定を追加
/etc/init.d/gitlab
#! /bin/bash # GITLAB # Maintainer: @randx # App Version: 4.0 ### BEGIN INIT INFO # Provides: gitlab # Required-Start: $local_fs $remote_fs $network $syslog redis-server # Required-Stop: $local_fs $remote_fs $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: GitLab git repository management # Description: GitLab git repository management ### END INIT INFO # # set rvm environment valiables. # export PATH=/home/gitlab/.rvm/gems/ruby-1.9.3-p392@gitlab/bin:/home/gitlab/.rvm/gems/ruby-1.9.3-p392@global/bin:/home/gitlab/.rvm/rubies/ruby-1.9.3-p392/bin:/home/gitlab/.rvm/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/gitlab/bin export GEM_HOME=/home/gitlab/.rvm/gems/ruby-1.9.3-p392@gitlab export GEM_PATH=/home/gitlab/.rvm/gems/ruby-1.9.3-p392@gitlab:/home/gitlab/.rvm/gems/ruby-1.9.3-p392@global export BUNDLE_PATH= export MY_RUBY_HOME=/home/gitlab/.rvm/rubies/ruby-1.9.3-p392 export IRBRC=/home/gitlab/.rvm/rubies/ruby-1.9.3-p392/.irbrc set -u set -e APP_ROOT="/home/gitlab/gitlab" DAEMON_OPTS="-c $APP_ROOT/config/unicorn.rb -E production" PID_PATH="$APP_ROOT/tmp/pids" UNICORN_PID="$PID_PATH/unicorn.pid" SIDEKIQ_PID="$PID_PATH/sidekiq.pid" STOP_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:stop" START_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:start" NAME="unicorn" DESC="Gitlab service" check_pid(){ if [ -f $UNICORN_PID ]; then PID=`cat $UNICORN_PID` SPID=`cat $SIDEKIQ_PID` STATUS=`ps aux | grep $PID | grep -v grep | wc -l` else STATUS=0 PID=0 fi } start() { cd $APP_ROOT check_pid if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then # Program is running, exit with error code 1. echo "Error! $DESC $NAME is currently running!" exit 1 else if [ `whoami` = root ]; then sudo -u gitlab -H bash -l -c "nohup bundle exec unicorn_rails $DAEMON_OPTS > /dev/null 2>&1 &" sudo -u gitlab -H bash -l -c "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &" echo "$DESC started" fi fi } stop() { cd $APP_ROOT check_pid if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then ## Program is running, stop it. kill -QUIT `cat $UNICORN_PID` sudo -u gitlab -H bash -l -c "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &" rm "$UNICORN_PID" >> /dev/null echo "$DESC stopped" else ## Program is not running, exit with error. echo "Error! $DESC not started!" exit 1 fi } restart() { cd $APP_ROOT check_pid if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then echo "Restarting $DESC..." kill -USR2 `cat $UNICORN_PID` sudo -u gitlab -H bash -l -c "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &" if [ `whoami` = root ]; then sudo -u gitlab -H bash -l -c "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &" fi echo "$DESC restarted." else echo "Error, $NAME not running!" exit 1 fi } status() { cd $APP_ROOT check_pid if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then echo "$DESC / Unicorn with PID $PID is running." echo "$DESC / Sidekiq with PID $SPID is running." else echo "$DESC is not running." exit 1 fi } ## Check to see if we are running as root first. ## Found at http://www.cyberciti.biz/tips/shell-root-user-check-script.html if [ "$(id -u)" != "0" ]; then echo "This script must be run as root" exit 1 fi case "$1" in start) start ;; stop) stop ;; restart) restart ;; reload|force-reload) echo -n "Reloading $NAME configuration: " kill -HUP `cat $PID` echo "done." ;; status) status ;; *) echo "Usage: sudo service gitlab {start|stop|restart|reload}" >&2 exit 1 ;; esac exit 0
Gitlab起動、自動起動設定
[mikito@nya ~]$ sudo chmod +x /etc/init.d/gitlab
[mikito@nya ~]$ sudo service gitlab start
[mikito@nya ~]$ sudo chkconfig gitlab on
[mikito@nya ~]$ chkconfig --list gitlab
gitlab 0:off 1:off 2:on 3:on 4:on 5:on 6:off