2017年4月23日日曜日

【Microsoft Azure】みんな大好きマストドンを Web App On Linux で簡単に動かそう(完結編)

Web App On Linux は、簡単に言えば単体のDockerコンテナを動かすサービスです。
最初からNode.jsとかPHPのイメージが提供されているので、Windowsベースの Web App と同じように、かつApacheをWebサーバーとして使えるのがメリットです。

今回マストドンを単体のdockerコンテナで動かすわけですが、大変な苦労をして作成したdockerコンテナイメージを Docker Hub で公開します。
https://hub.docker.com/r/cocteau666/mastodon/

苦労した点を列挙するとこんな感じです。

1.複数のサーバーをひとつのコンテナに立てる
本来なら1コンテナ1プロセスの思想で、必要ならオーケストレーションツールで複数のコンテナを使うのが正しいのですが、限られた環境なのであえてオールインワンにしてみました。
この問題を解決するためには、supervisordを使いました。

2.ホスト名を設定する
コンテナをrunしたらほぼ問題なく動くようになったのですが、Web App にデプロイ後にどうやってホスト名を追加するのが良いのか、いろいろ検討しました。
結局、ポータルのアプリケーション設定の中のアプリ設定(いわゆる環境変数)に、Railsで使う環境変数を上書きする形で設定するように落ち着きました。
手順は後ほど説明します。

それでは、このイメージを使って、Azureで簡単にマストドンを運用する手順を説明します。

Azure使ってない人はまず使えるようにしてくださいw
https://azure.microsoft.com/ja-jp/offers/ms-azr-0044p/

ポータルにログインしたら、「Web + モバイル」→「Web App On Linux」を選びます。



アプリ名(今回はmastodon0)を入力し、サブスクリプションを選択(デフォルトでも問題ないはず)、リソースグループを新規作成または既存のグループを選択(今回はdocker2というグループを新規作成)します。
App Service のプラン/場所は、プランは今のところ「B1 Basic」が5700円/月で一番安いです。場所はプレビューなので、West Europe、Southeast Asia、West USの3つから選びます。ご自身に近いところでどうぞ。
コンテナの構成は、イメージのソースは「Docker Hub」、リポジトリ アクセスは「パブリック」、イメージとオプションのタグは「cocteau666/mastodon:latest」をそれぞれ入力します。
ここまで入力したら左下の「作成」を押します。

出来上がったら、アプリの管理ポータルで環境変数を設定します。
左の一覧から「アプリケーション設定」を選び、真ん中あたりのアプリ設定に追加します。
キーが「LOCAL_DOMAIN」、値が今回のアプリのFQDN(mastodon0.azurewebsites.net)を入力して上の保存を押します。












保存したら左の一覧の「概要」を選び、上の「再起動」をクリックします。


10分程度たってから、アプリにアクセスします。(今回は https://mastodon0.azurewebsites.net/)
見えましたか?




























ここでアカウントを登録すると確認メールが来て、アカウントを有効化できると思います。

なお、簡単にできますが、多少注意点があります。

・データベースもオールインワンなので、再起動するとすべてのデータがなくなります...
・App Serviceのプランに応じてサーバーのディスクサイズが決まりますが、B1だと10GBであまり余裕がないかと。大きくしても50GBなので、ごく小規模での運用に限られるかと思います。

公開しているイメージを自分でカスタムして使うのもアリなので、データベースを外部に立てたり(PostgreSQLです)、Redisキャッシュサービス使ってみたり、いろいろできると思いますので、挑戦してみてください。


2017年4月14日金曜日

【Microsoft Azure】みんな大好きMastodonをAzureで動かそう #1

最近にわかに話題に上がってるMastodonは、アメリカのヘヴィメタルバンドではなく、Twitterに似たWebサービスです。
https://github.com/tootsuite/mastodon

サーバーがそれぞれ分散しているのが特徴で、私を含む大人たちはもしかしたらNiftyServeみたいなのを思い出すかもしれません。
もちろんオープンソースですので、Azureで動かしちゃいます。

今回の構築に必要なものは、こちら。

・Azure Container Service(以下ACS)
docker-composeコマンドでさくっとMastodonサーバーを構築するのにちょうどいいです。

・PostgreSQLとRedisを動かす仮想マシン
今後DBを分散するために、dockerコンテナの外に構築します。
Ubuntuでやってみましょう。

・SMTPサーバー
登録時のメールアドレス確認のためのメールサーバーです。
なんでもいいんですけど。

では、さっそくやってみましょう。

まずは最初に仮想マシンを作成します。
こちらを参考にして、ログインするところまで頑張ります。
https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/quick-create-portal

ログイン後、以下のようにPostgreSQLとRedisを設定していきます。
まずは管理者になってパッチを当てます。
# apt update
# apt -y upgrade

次はaptコマンドでPostgreSQLとRedisをインストールします。
# aot -y install redis-server redis-tools postgresql postgresql-contrib

ACSからRedisに繋がるように設定します。
# vi /etc/redis/redis.conf
redis.confの中の「bind 127.0.0.1」を「bind 0.0.0.0」に書き換えます。
なお、この状態だとすべてのサーバーからの接続を許可するので、そのまま放置するのはよろしくないです。

PostgreSQLへ、Mastodonで使用するデータベース(mastodon)とユーザー(mastsan)を追加します。この作業はpostgresユーザーで行います。
# su - postgres
$ createdb mastodon
$ psql
> create role mastsan login createdb password 'ログインパスワード文字列';
> \q
$ exit

ACSからPostgreSQLへのパスワードログインを許可します。
# vi /etc/postgresql/9.5/main/postgresql.conf
まずは、postgresql.confに「listen_addresses = '*'」を追加します。
これで他のサーバーからのログインができるようになります。

# vi /etc/postgresql/9.5/main/pg_hba.conf
pg_hba.confの最後に以下の行を追加します。
「host   all  mastosan  0.0.0.0/0   md5」
mastosanユーザーはパスワードでログイン可能です。

最後に、サービスを再起動して反映します。
# /etc/init.d/redis-server restart
# /etc/init.d/postgresql restart


次はACSの設定ですが、今回は構築してSSHトンネリングで起動を確認するまでをやってみます。

まず、AzureポータルからACSを作成します。
左の「+」から、「Containers」を選び、「Azure Container Service」をクリックします。


そのまま下の「OK」をクリックします。


Orchestratorは「Swarm」を選んで、リソースグループやロケーションを決めたら、「OK」をクリックします。



DNSのプレフィックスに今回「mastodon」を設定しました。
コンテナへのユーザーネームと、ログインに必要な公開鍵を貼り付けます。



今回コンテナを3つ動作させるので、Agent count は「3」にします。
Agent virtual machine size はヘタレなので「Standard A0」(ACSでは最小)を選択します。


登録内容を確認して「OK」をクリック。


デプロイが終わるのを待ちます...。


デプロイが終わったら、リソースグループの一覧から今回作成したもの(acstest)を探して表示します。
左のメニューに「Deployments」があるので、選んで表示された一番上(最新)のデプロイ内容を表示します。


そこにdockerホストへのアクセス情報が書かれています。
SSHMASTER0というキーに表示されている値をコピーして、sshでdockerホストへアクセスします。
今回は「ssh ユーザー名@プレフィックス+mgmt.リージョン.cloudapp.azure.com -A -p 2200」となります。


さて、ここからはdockerホストでの作業です。

ログインしてまずはgithubからMastodonをクローンします。
$ ssh ユーザー名@プレフィックmgmt.リージョン.cloudapp.azure.com -A -p 2200
$ git clone https://github.com/tootsuite/mastodon.git
$ cd mastodon

環境に合わせて、「.env.production」ファイルを編集します。
$ cp .env.production.sample .env.production
$ vi .env.production

今回使うRedis、PostgreSQL、SMTPの設定をします。以下の値を環境に合わせて設定しましょう。

--------------------------------------------------------------------------------------------
REDIS_HOST=Redisが動作しているホスト名
REDIS_PORT=6379
DB_HOST=PostgreSQLが動作しているホスト名
DB_USER=ユーザー名(今回はmastsan)
DB_NAME=データベース名(今回はmastodon)
DB_PASS=PostgreSQLにログインするパスワード
DB_PORT=5432

# Federation
LOCAL_DOMAIN=example.com
LOCAL_HTTPS=false

# Application secrets
# Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
PAPERCLIP_SECRET=長い文字列
SECRET_KEY_BASE=長い文字列
OTP_SECRET=長い文字列

# E-mail configuration
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
SMTP_SERVER=SMTPサーバー
SMTP_PORT=587
SMTP_LOGIN=ログイン名
SMTP_PASSWORD=パスワード
SMTP_FROM_ADDRESS=メールに設定するFromアドレス
--------------------------------------------------------------------------------------------

保存したら、docker-compse.ymlを変更して、RedisとPostgreSQLのコンテナを作成しないよう以下のように変更します。

$ vi docker-compose.yml
--------------------------------------------------------------------------------------------
version: '2'
services:

#  db:
#    restart: always
#    image: postgres:alpine
### Uncomment to enable DB persistance
#    volumes:
#      - ./postgres:/var/lib/postgresql/data

#  redis:
#    restart: always
#    image: redis:alpine
### Uncomment to enable REDIS persistance
#    volumes:
#      - ./redis:/data

  web:
    restart: always
    build: .
    env_file: .env.production
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - "3000:3000"
#    depends_on:
#      - db
#      - redis
    volumes:
      - ./public/assets:/mastodon/public/assets
      - ./public/system:/mastodon/public/system

  streaming:
    restart: always
    build: .
    env_file: .env.production
    command: npm run start
    ports:
      - "4000:4000"
#    depends_on:
#      - db
#      - redis

  sidekiq:
    restart: always
    build: .
    env_file: .env.production
    command: bundle exec sidekiq -q default -q mailers -q pull -q push
#    depends_on:
#      - db
#      - redis
    volumes:
      - ./public/system:/mastodon/public/system
--------------------------------------------------------------------------------------------


あとはビルドしてコマンドから起動します。
途中で失敗する場合は、仮想マシンのRedisやPostgreSQLが起動していなかったりアクセスができない状態ではないか確認してみます。
$ docker-compose build
$ docker-compose run --rm web rake secret
$ docker-compose run --rm web rails db:migrate
$ docker-compose run --rm web rails assets:precompile
$ docker-compose up -d


ひとまず確認のため、ローカルホスト(私の場合はMacOS)からSSLトンネリングしてMastodonに接続できるか確認します。ローカルホストのポート30000/TCPに繋ぐとMastodonに接続するようにします。
$ ssh -fNL 30000:localhost:3000 ユーザー名@プレフィックス+mgmt.リージョン.cloudapp.azure.com -A -p 2200

ブラウザで「http://localhost:30000」へアクセスしてみましょう。
きっと見えてるはずw