tsuru でプライベート PaaS を構築し操作してみるメモ

Heroku の様にソースコード push するだけでデプロイ＆WEBアプリ構築ができる PaaS なり Docker as a Service といったプロダクトとしては [Dokku](http://dokku.viewdocs.io/dokku/) や tsuru が存在しています。

今回 [tsuru.io](https://tsuru.io/) が使ってみたかったのですが、情報が少なかったので本家の[ドキュメント](https://docs.tsuru.io/stable/)を見ながら悪戦苦闘したメモを記録しておきます。

#記述時の環境

tsuru - 1.1.0

#サーバーのインストール
##お試しコース
tsuru を手軽に試すための一発インストールコースとしては

1) [Tsuru Now](https://github.com/tsuru/now) インストールスクリプト
2) [tsuru-bootstrap](https://github.com/tsuru/tsuru-bootstrap) Vagrant 設定

の2つがあります。

ちょこっと試すには Vagrant でも良いのですが、プライベートサーバーに立ててみたいという向きには Tsuru Now の方かなということでこちらを選択しました。

どちらも 1台全部込みのインストーラーですが、Tsuru Now はノード(Docker farm)の作成と追加も対応しているっぽいので数台構成のスケーリングを試すことができそうです。

##インストール用件
Tsuru Now は apt で提供されます。Ubuntu もしくは debian に対応と書いてあるのですが、init 時代の docker engine 設定を期待している所があるので実質 Ubuntu 14.04 専用です。
Debian8 や Ubuntu 16.04 ではうまいこといきませんでした。

WEBアプリサーバーなのでグローバルアドレスに接続されていることを期待しています。NAT内のローカルアドレスだとこの用件を満たさないのでインストールが中断されます。
この場合 `--host-ip` オプションを付けてアドレス明記で先に進めることができますが最終的にNATゲートウェイになっているルータのパブリックIPアドレスが設定されてしまう部分があったりします。
グローバルアドレスを持ったサーバーでやるのが一番楽なのでクラウドサービスでVMを借りてやるのが最善手かもしれません。
ローカル向けにこのへんどう設定するかは要調査事項。

あと Proxy 経由だと引っかかる所が多すぎて挫けました。proxy 無しな環境でお試しください。

#サーバーの設定
インストールが無事完了すると tsuru が可動します。
このままでも利用できますが必要に応じてtsuru サーバ上でいくつか設定を行います。

##管理者アカウントの作成
tsuru サーバーにログインし、管理者権限で tsurud を実行することで管理者アカウントの追加が行えます。

```shell:
# tsurud root-user-create (admin@mail.address)
```

アカウントとしてメールアドレスを指定するとこのユーザーに対するパスワードの入力を求められますので入力して設定してください。

追加できているかどうかは `user-list` で確認します。

```shell:
# tsuru user-list
```

ローカルからアクセスするときに `admin@example.com` というアカウントが設定されています。消しても良さそうなのですが、Tsuru Now で起動したときに唯一起動しているアプリ `tsuru-dashboard` が `admin@example.com` 所有で動いています。
所有権を移せたら `admin@example.com` を消せるかな？

##アプリドメインの設定
Tsuru Now でインストールした場合、サーバーのドメイン名が `***.***.***.***.nip.io` という IPv4 アドレス丸見えの外部 DNS が設定されます。
サーバーにドメイン名を割り振っていてもこれではちょっと嬉しくないのでせめてデプロイしたアプリへのアクセスくらいは自前のドメイン名が使いたいものです。

サーバー上で `/etc/tsuru/tsuru.conf` を編集してドメイン名を設定します。

`host:` で指定されている部分は tsuru API のホスト名になります。これはクライアント(開発マシン)からアクセスするときのアドレスです。

`router:hipache:domain:` で指定されている部分がアプリにアクセスするときのドメイン設定となります。ここに `tsuru.your.domain` と設定した場合、sample1 アプリにアクセスするURLが `http://sample1.tsuru.your.domain/` となります。
ドメイン名のサブドメインにアプリ名が追加されますので `tsuru.your.domain` を設定している DNS ではサブドメインを全て処理できるように `*.tsuru.your.domain` を設定しておく必要があります。


#クライアントツールのインストール
アプリを開発したりサーバーにデプロイするマシンをクライアントとします。
クライアント側には tsuru cli ツールをインストールして、tsuru サーバーをリモート操作します。

##クライアントツール
tsuru cli ツールには以下の 3種類があります。

- tsuru
    - 開発者が使うクライアントツール、ほぼ全てが詰まっている
- tsuru-admin
    - 主に tsuru システムの Docker farm を管理するためのツール。nodeの追加、削除など 
- crane
    - サービス(アプリとは別に動作するサーバー、主にDB類)の管理、設定を行うツール

クライアント側には `tsuru` だけインストールしておけば良いと思います。

##インストール
インストール手順については[ドキュメント](https://docs.tsuru.io/stable/using/install-client.html)を参照してください。
go言語がインストールしてある環境なら `go get (リポジトリ)` でインストールするのが簡単だと思います。

##接続サーバーの設定
クライアントツールをインストールしたら、tsuru サーバーの場所を教えてやる必要があります。

```shell:
% tsuru target-add サーバー名 http://(tsuru.your.domain):8080
% tsuru target-set サーバー名
```

`(tsuru.your.domain)` の部分にはクライアントから見えるあなたの tsuru サーバーを指定します。
サーバー名は愛称で構いません、`target-set` で接続先を指定する際に使われます。

##ログイン
アクセスするユーザーアカウントでログインします。パスワードを求められるので入力して下さい。

```shell:
% tsuru login (your@mail.address)
```

ユーザーアカウントの作成については後述しますが、ここでは先にサーバー上で作成した管理者アカウントが使えることを確認してください。

ログインまで完了したら `tsuru` コマンドで tsuru サーバーが操作できるようになっています。

#ユーザー管理
ユーザーの管理については把握しきれなかったのでおおよそこのようだというメモ書きまでにししておきます。
要調査項目。

##ユーザーとチーム
作業者個人のアカウントは「ユーザー」と呼ばれ、ユーザーの集合を「チーム」と呼びます。
アプリケーションはチームが所有し、チームに参加しているユーザーが開発を行います。

ユーザーの確認(自分の権限以下のユーザーのみ表示されます)

```shell:
% tsuru user-list
% tsuru user-info
```

チームの確認

```shell:
% tsuru team-list
```

##パーミッションとロール
作業権限をパーミッションと呼び沢山あります。

パーミッションの一覧確認

```shell:
% tsuru permission-list
```

ロールは利用可能なパーミッションを複数束ねたものであり、ユーザーにロールを与えることでパーミッションを束で付与することができます。

```shell:
% tsuru role-list
```

どうも team という概念を role に移行している途中っぽくて、この辺の管理がすっきりしません。なのにアプリケーションには team の設定が必要だったりするので把握しきれないでいます。



#プラットフォームの追加
プラットフォームというのはざっくり言うと Docker のイメージです。
予め言語環境を整えておいた Docker イメージからコンテナを作成してその中にアプリをデプロイするのが tsuru のお仕事です。
このプラットフォームが言語や開発環境毎に存在していて、アプリ作成の最初にその利用を宣言します。
このへん heroku を使ったことがある人はすぐイメージできるでしょう。(heroku では Framework と呼んでいました)

tsuru サーバーをインストールした直後は python しかプラットフォームが存在しません。
その他の環境を利用したい場合はプラットフォームを追加します。
プラットフォームを自作することもできるのですが、ここでは tsuru 標準のプラットフォーム追加を説明します。

tsuru 標準のプラットフォームになにがあるかは github を見て下さい。
https://github.com/tsuru/platforms

現在登録されているプラットフォームを確認する

```shell:
% tsuru platform-list
```

プラットフォームの追加には `tsuru-admin` を使います。tsuru サーバー上で行うのが容易でしょう。

```shell:
# tsuru-admin platform-add ruby
```

上記例では bundle 使用の ruby プラットフォームをインストールしています。
後は必要に応じて追加していってください。


#アプリの開発
ruby プラットフォーム上で helloworld アプリを作成するまでの簡単な流れです。
アプリ作成ができる開発者アカウントをうまいこと用意できなかったので以下は全て管理者アカウントで実行しているとお考え下さい。

##前準備
`git push` でデプロイを行いたい場合は tsuru の git (正確にはGandalf) に ssh アクセスの公開鍵を登録します。

```shell:
% tsuru key-add (鍵管理名) (公開鍵ファイルのパス)
% tsuru key-list
```

削除したい場合は key-remove です。

##アプリケーションの作成
tsuru サーバー上に hello1 という名前のアプリを作成します。

```shell:
% tsuru app-create hello1 ruby --team testteam
```

アプリを所有するチームを指定しないとうまくいきませんでした。予めなんらかのチームを作成しておいてください。

アプリ作成時に git リポジトリ URL が表示されます。
これをクローンして始めるなり、後で push するためにメモするなりしておいてください。
リポジトリは app-info で確認できます。

```shell:
% tsuru app-info -a hello1
```

今回は ruby/sinatra で簡単な Hello world を作成してみます。
以下の 3ファイルを作成

```ruby:Procfile
web: bundle exec ruby app.rb -p $PORT -e production
```

```ruby:Gemfile
source 'https://rubygems.org'

gem 'sinatra'
```

```ruby:app.rb
require 'sinatra'

get '/' do
  "Hello, tsuru."
end
```

`bundle install` して `Gemfile.lock` を作成しておき、Procfile, Gemfile, Gemfile.locl, app.rb の 4ファイルを git リポジトリに commit します。

##アプリケーションのデプロイ
ローカルに commit した git リポジトリを tsuru サーバーに push することでアプリケーションのビルド＆デプロイが行われます。

```shell:
% git add .
% git commit -m "my app"
% git push git@(tsuruサーバーのIPアドレス).nip.io:hello1.git master
```

問題なければアプリが起動します。
起動中のアプリについては app-list で確認できます。

```shell:
% tsuru app-list
```

`http://hello1.(tsuruサーバーのドメイン名)/` にアクセスすると `Hello, tsuru.` と表示されるはずです。

##gitを使わないデプロイ
git リポジトリを介さなくても `tsuru app-deploy` でローカルファイルのアップロード＆デプロイをすることができます。

```shell:
% tsuru app-deploy -a hello1 .
```

ssh鍵の登録も不要ですし、書き捨てアプリとかならこれでも良いかもしれませんね。