AWS OpsWorksにgitlabサーバーを構築する

こんにちは,@h3_potetoです.

社内にGitlabサーバーを建てたので,詰まった点をまとめておきます.

縛りとしては,AWS OpsWorks上で動かすということだけ!


使用したソースは,
https://gitlab.com/gitlab-com/cookbook-gitlab-opsworks
このcookbookをベースに,

https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md

このgitlabのソースを動かします.

とりあえずcookbookを突っ込んでみる.

エラー:redisioがおかしい


opscodeの最新redisioを引っ張ってきて,上書きしました.
これにてredisのインストールは完了.

エラー:require 'mysql'でひたすら怒られる

基本的にはruby-mysqlのgemを突っ込めば解決するはずだが…….
解決しない.

正解:gitlab/recipes/database_mysql.rbに追記.

正確には

# 5.Database
unless gitlab['external_database']
  include_recipe "mysql::server"
  include_recipe "database::mysql"
else
  include_recipe "database::mysql"
end

external_databaseを使う設定にしているので(RDSは別ですでに用意してある),database::mysqlというレシピが実行されていなかったのが問題のようでした.


エラー:migrationでこける

正解:メモリがひたすら足らない.

エラーログを読むとRDSとのコネクションが張られた後,migration中にlost connectionしています.
これはtimeoutの設定とかいろいろ変えて対応してみたけれど,まぁ無理!

メモリを馬鹿みたいに増やすしかない.

というか,初回のcreate+migrateだけが辛いので,そこはローカルでmigrationまで通して,sqlファイルをサーバーに移してDBに流し込みました.
超力技!!

あと,database.ymlあたりのreconnectionをtrueにしておくと,ちょっとはマシになる


ここまでやってようやく起動したが……



いざ,サインアップしようとすると,メールが飛ばない…….
サインアップを有効にするには,Custom Jsonにsignup_enabled: trueを追加すればいいだけ.


しかし,サインアップにはconfirmのメール送信が付いている……つまり,メールが送れない.


AWS SESを使えるようにする(茨の道)

必要なものは,gitlab本体のbundle install時にaws-sdkとfigaroを入れる必要があります.

Gemfile.localとかいろいろ試したんですが……これはもう無理!本体のソースを書き換えずにやるというのがきつすぎる.

というわけで,gitlab本体のソースをcloneした直後にGemfileに追記します.



そして追記終了したらbundle installをかけてやります.

execute "add gemfile" do
  not_if "grep 'aws-sdk' Gemfile"
  command <<-EOS
    echo "gem 'aws-sdk'" >> Gemfile
    echo "gem 'figaro', github: 'laserlemon/figaro'" >> Gemfile
  EOS
  cwd gitlab['path']
  user gitlab['user']
  group gitlab['group']
  action :run
  subscribes :run, "git[clone gitlabhq source]", :immediately
end

execute "bundle install" do
  command <<-EOS
    PATH="#{gitlab['postgresql']['configuration_dir']}:/usr/local/bin:$PATH"
    #{gitlab['bundle_install']} --without #{bundle_without.join(" ")}
  EOS
  cwd gitlab['path']
  user gitlab['user']
  group gitlab['group']
  action File.exists?(File.join(gitlab['home'], "Gemfile.lock")) ? :nothing : :run
  subscribes :run, resources("execute[add gemfile]"), :immediately
end


これでGemのインストールは完了です.




あとは,smtp_settingでamazon_sesを指定します.
aws-sdkからSES経由のメールを送信する方法についての解説は,こちら



それに伴いfigaroの設定をする必要があったため,自分でレシピとテンプレートを書いて,application.ymlを生成してやります.





まだメール送れない

aws.yml.exampleというのがあり,このcookbook,s3を使えるようにしてくれるんですが,ここでミスった.

awsの設定がこのファイルで行われてしまうので,aws-sdkを呼び出した時,ここの設定がつかわれてしまう.
と,なんとregionの設定がされてしまうのである.


AWS SESは,regionの設定をすると,メールを送れなくなります.


というわけで,s3を諦め,aws.ymlの生成は取りやめ.





これでようやくメールが送れるようになって,サインインできました.


ちなみに,このs3の設定はアイコン等のファイルアップロード時の保存先として使用するようです.
あればそのほうが楽なのですが……メールのほうが重要なのでとりあえず諦めています.



ソースをcloneしたり,pushしたり,cloneできるようにする.

gitlabのページから自分のssh公開鍵を登録したけど,ssh接続ができない!
と思ったら,そりゃーポート開けてないから無理だよね,ってことに気づいた.


というわけで,いつもどおりセキュリティグループを作成し,OpsWorksのLayerとELBにくっつける.

さらにELBのListenポートとして22番を……と思ったけど,ELBは22番を許可しない.



というわけで,割り当てのない適当にでかい数のポートを一つあけて,それをインスタンス側の22番ポートにつなげてるようにListenを書く.



sshアクセスでgitlabからソースをcloneしたりするためには,~/.ssh/configを以下のように編集.

Host "自分のgitlabのホスト名"
  User git
  Port "先ほど開放したELBポート"
  IdentityFile "登録した公開鍵に対応する秘密鍵ファイル"

SSLの設定をかます


いつもどおりELBに証明書を登録するまではいい.

これでcookbook-gitlab-opsworks側の設定で,SSLを有効にしてやる必要がある.

Custom JSONに,port: 443と書けば,httpsを有効にしてくれる.


が,しかし,これだけでは通らない.



まず,ELBを通してアクセスすることを想定していないので,サーバー本体にSSLの証明書を登録する前提で,このcookbookは組まれている.

だから,nginxの設定でポートを443に限定してしまうし,SSLの証明書を登録させようとして,エラーになる.


というわけで,ここを書き換え,SSLの証明書の登録は無効にして,ポートは80番で受けるように変更.


gitlab/recipe/nginx.rb

・証明書を設定している部分をコメントアウト


gitlab/templates/nginx.conf.erb

・listenを80番で受けるように固定.
・proxy_set_header X-Forwarded-Proto https;  に設定



その他,なんかnginx関連で証明書を指定しそうな場所は消していきます.


最後に,Custom JSON側で指定するgitlabのurlを,https込みのアドレスにしておきます.




正常にインストールは成功したけど,大丈夫?

アクセスして動いていれば,とりあえず問題ないです.

あとは,サーバーにログインして,gitユーザになります.
そこでgitlabのインストールディレクトリに行き,

$ bundle exec rake gitlab:check RAILS_ENV=production

としてみて,出てきたエラーを全部潰します.
ここで出るエラーは,どうしたらいいかが記述されていると思うので,その通りにしていきましょう.







長かったです.

以上で設定は完了しました.

Custom JSONについては,一応解説が公式から提供されていますが,自分でattributesとrecipeをよく読んだ方がいいです.


別サーバーのDBを使う設定はサンプルとして載っているかと思うので割愛します.
その他注意事項としては,

・repositoryの指定をした場合は,必ずrevisionの指定もしましょう.古いソースが取得されてしまいます.
sslを導入した場合は,https込みのアドレスにする.
・urlは必ず最後の"/"を含める


あたりでしょうか.






サーバーの構成としては,OpsWorks内でIsntans storeタイプのインスタンスを立ち上げ,そこにEBSをくっつけています.
repos_pathの指定で,EBSを指定しておき,そのEBSをまるごとスナップショットを取る(バックアップ用)スクリプトをcronで走らせています.
このインスタンスの上にELBをつけ,そこにSSL証明書の登録をしています.
また,DBについてもRDSを別で用意し,そこを使うようにしています.


ちなみに,このgitlab用のopsworks cookbook,かなり重い処理を連発します.
gitlabhqのソースも自動取得ですし,他にも必要な物を全部インストール,起動します.

そのため,公式の説明にも書いてありますが,c3.largeインスタンス推奨です.

一度,m1.smallで起動を試みたのですが,上手く行きません.メモリが足らなくなりますね.


試しにt2.smallで立ち上げてみたのですが,バーストさせればサクッと起動できます.
そのくらいの重さってことなので,インスタンスタイプについては,ちょっと高いのを使わないといけないかもしれません.
負荷がかかるのはgitlab::setupとgitlab::deployのレシピだけなので,t2というのはかなりいい選択肢かもしれないですね(現状,インスタンスタイプがEBS backedしか選択できませんが).