GAE/Swift

SwiftをGoogle App Engineで動かしてみます。ネタですが、Googleさんが少し頑張ってくれればサーバサイドもSwiftで書けて嬉しくなります。

# Google App Engine - sandbox, Managed VMs

最近は、GAEと言ってもGoogle App Engineを従来から存在する `sandbox` と、Containerベースの `Managed VMs` という二種類の環境に分けて考えられます。乱暴な言い方でわかりやすく違いを説明をすると、`Managed VMs`は従来の`sandbox`のような制約は無いが、瞬時のスケールアウトが超遅い（分単位）GAEと考えると良いです。つまり`Managed VMs`はフロントとしてはほぼ使えない環境なので、まぁよほどのことが無い限りは従来の`sandbox`の制約内で動作させる方が普通です。

主な違いは次のサイトで説明されています。

* https://cloud.google.com/appengine/docs/managed-vms/

# Managed VMs

Managed VMsの方はさらに `Standard runtimes`, `Custom runtimes` の二種類に分かれます。どちらも Dockerコンテナを稼働させますが、`Standard runtimes`の方はベースとなるDocker imageがいくつか指定されており、GAEの重要な標準サービス（DatastoreやTask Queue, Memcacheなどなど）がSDKのAPIで使用できます。`Custom runtimes`の方はどんなDocker imageでも使用できますが、GAEの標準サービスはHTTP経由のAPIを使う必要があります。

次のサイトでベースとなるイメージについて簡単な説明があります。

* https://cloud.google.com/appengine/docs/managed-vms/custom-runtimes#base_images

この記事でいう`GAE/Swift`は、`Managed VMs`で`Custom runtimes`を使用します…つまりどんな言語でも動くので、Swiftでもなんでもいいわけです。GAEはほぼ関係ないです。

# 手順

1. Swiftのサーバアプリケーションを起動する`Dockerfile`を作成する
2. GAE/Managed VMs用の`app.yaml`を作成する

Serverサイド用のSwift用のライブラリやフレームワークはいくつかあるようです。

* https://github.com/Zewo/HTTP
* https://github.com/PerfectlySoft/Perfect
* https://github.com/huytd/swift-http
* https://github.com/takebayashi/swiftra
    * https://github.com/huytd/swift-http

# 手順

今回は一番小さそうで"Hello, world"サンプルがある huytd/swift-http をそのままサーバアプリケーションとして実行します。

## Dockerfile

ubuntu15.10向けのSwift-2.2-SNAPSHOTを使用します。huytd/swift-httpで使用しているlibxml2もインストールしています。なお、`Custome runtimes`でリクエストを受ける場合は必ず [`8080`で受ける必要がある](https://cloud.google.com/appengine/docs/managed-vms/custom-runtimes#listen_to_port_8080)ようです。

```:Dockerfile
FROM ubuntu:15.10

RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get -y install curl clang libicu-dev make libxml2
RUN apt-get -y install tree git vim

WORKDIR /tmp

# Install Swift
ENV SWIFT_PACKAGE swift-2.2-SNAPSHOT-2015-12-31-a-ubuntu15.10.tar.gz
RUN curl https://swift.org/builds/ubuntu1510/swift-2.2-SNAPSHOT-2015-12-31-a/swift-2.2-SNAPSHOT-2015-12-31-a-ubuntu15.10.tar.gz -o $SWIFT_PACKAGE.tar.gz
RUN tar zxf $SWIFT_PACKAGE.tar.gz --directory / --strip-components=1
RUN rm -f $SWIFT_PACKAGE.tar.gz

# Install https://github.com/huytd/swift-http.git
RUN git clone https://github.com/huytd/swift-http.git && cd swift-http && swift build

RUN apt-get clean

EXPOSE 8080

WORKDIR /tmp/swift-http

CMD .build/debug/example
```

## app.yaml

`vm=true`の指定があると`Managed VMs`環境として認識されます。`Custom runtimes`ではautomatic scaling と manual scalingのみ使えます(basic scalingは使えない)。

```yaml:app.yaml
runtime: custom
vm: true

automatic_scaling:
  min_num_instances: 2
  max_num_instances: 5
  cool_down_period_sec: 60
  cpu_utilization:
    target_utilization: 0.5
```

## deploy

必要であれば、gcloud sdkのインストールと認証、プロジェクトの設定をしてください。

```shell-session
curl https://sdk.cloud.google.com | bash
gcloud auth login
gcloud config set projcet {your-project-id}
```

認証とプロジェクトの設定ができたら、次のコマンドでデプロイできます。

```shell-session
gcloud preview app deploy app.yaml
```

## 確認

開発者コンソールでGAEのバージョンを見てみると、`Runtime: vm`となっているものがあるはずで、そのバージョン名をクリックすると `https://${version}-dot-{your-project-id}.appspot.com` が別タブで開き、Hello worldという出力が確認できるはずです。Swift製のアプリがGAEで動きました(∩´∀｀)∩ﾜｰｲ…(´・ω・｀)

![Screen Shot 2016-01-02 at 01.28.42.png](https://qiita-image-store.s3.amazonaws.com/0/1387/2a204f2f-6283-184c-ec96-46d539b252fb.png)

Managed VMsの場合はGoogle Compute Engineのインスタンスが裏で立ち上がります。
![Screen Shot 2016-01-02 at 01.29.29.png](https://qiita-image-store.s3.amazonaws.com/0/1387/385eda72-b751-1c6d-9248-32ab9bf504d4.png)


## 後片付け

特に嬉しいアプリなわけでもないので、インスタンスを落としておきましょう。
開発者コンソールのGAEの該当バージョンを削除すると、Compute Engineのインスタンスもしばらくして消えていきます（たまにやけに時間がかかるかも?）。


# まとめ

`FROM gcr.io/google_appengine/swift` できるようになる日が待ち遠しいですね！

使ったファイル類をおいておきました: https://github.com/shin1ogawa/gae-swift-example