Google Cloud Run を Swift 5 + IBM Kitura で動かす


Google Cloud Run は基本的にどんな言語でも動かすことが出来ます。
[Cloud Run の Quickstart](https://cloud.google.com/run/docs/quickstarts/build-and-deploy) にはコミュニティサンプルとして Swift 4.2 と [Swifty](https://github.com/httpswift/swifter) を使ったサンプルが掲載されています。

この記事では Cloud Run を Swift 5 と IBM の Kitura で動かしてみます。
[**私のブログ記事のほうではスクリーンショット付きで詳しく解説していますので、そちらも合わせてご覧いただければと思います。**](https://notes.tret.jp/google-cloud-run-with-swift-5-and-ibm-kitura/ "Google Cloud Run を Swift 5 + IBM Kitura で動かす - notes from E | 広く薄くの雑記帳 by treastrain")

# あえて始めに雑感を書く
> コンテナ等使ったことがなかった私でも簡単にデプロイすることが出来ました。
`main.swift` のほうですが、コミュニティサンプルの Swifty のほうはポートの取得や Kitura でいう `Kitura.run()` の記述に一工夫されているのが見られるので、その点は改善点なのかなとざっくり思います。
Cloud Functions for Firebase で「うわぁ…どうしても JavaScript (TypeScript) で書かなきゃダメか……」と思っていたところで突然降ってきた Cloud Run。私の大好きな Swift で書けるのはとっても嬉しいですし、モチベが全然違います…。

[Google Cloud Run を Swift 5 + IBM Kitura で動かす - notes from E | 広く薄くの雑記帳 by treastrain](https://notes.tret.jp/google-cloud-run-with-swift-5-and-ibm-kitura/)


#環境
- Xcode Version 10.2.1 (10E1001)
- Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.5.0
- Kitura version 2.7.0


# 始める前に
GCP のプロジェクトの課金が有効になっているかどうか確認します。
私の場合、将来的に Firebase Hosting に繋ぎたいので、Firebase プロジェクトの課金を有効にします。

プロジェクトの課金を有効にしたあとは [Cloud Run API を有効](https://console.cloud.google.com/apis/library/run.googleapis.com)にします。

続けて Google Cloud SDK の components を最新にアップデートします。

```
$ sudo gcloud components update
```


# Swift 5 でサンプルアプリケーションを作成する
## `Package.swift` の準備
作業するためのディレクトリを作成し、そこで `$ swift package init --type=executable` します。

`Package.swift` は次のようにし、IBM Kitura を持ってきます。

```swift:Package.swift
// swift-tools-version:5.0

import PackageDescription

let package = Package(
    name: "cloudrun",
    dependencies: [
        .package(url: "https://github.com/IBM-Swift/Kitura.git", .upToNextMinor(from: "2.7.0")),
    ],
    targets: [
        .target(
            name: "cloudrun",
            dependencies: [
                "Kitura",
            ]),
        .testTarget(
            name: "cloudrunTests",
            dependencies: ["cloudrun", "Kitura"]),
    ]
)
```

`Package.swift` を書いたら `$ swift build` します。
成功したら、以降は Xcode の補完を効かせたいので、 `$ swift package generate-xcodeproj` で Xcode プロジェクトを作成することにします。

## `main.swift` を書く
作成した Xcode プロジェクトを開いて、`main.swift` を次のようにします。

```swift:main.swift
import Foundation
import Kitura


let router = Router()

router.get("/") { request, response, next in
    response.send("Hello world")
    next()
}

Kitura.addHTTPServer(onPort: 8080, with: router)
Kitura.run()
```

Xcode での Build が成功すれば OK です。もし Run すると localhost の 8080 番で動作確認することもできます。


# `Dockerfile` を作成
続いて `Dockerfile` を作成します。

```Dockerfile
# Use the official Swift image.
# https://hub.docker.com/_/swift
FROM swift:5.0.1

# Copy local code to the container image.
WORKDIR /app
COPY . .

# Install dependencies and build.
RUN apt-get install openssl libssl-dev libcurl4-openssl-dev
RUN swift build -c release

# Run the web service on container startup.
CMD [ ".build/release/cloudrun"]
```


# コンテナ化して Container Registry にアップロードする
作業用ディレクトリで次のコマンドを実行します。
`[PROJECT-ID]` は Google Cloud Platform の プロジェクトIDです。

```
$ gcloud config set project [PROJECT-ID]
$ gcloud builds submit --tag gcr.io/[PROJECT-ID]/helloworld
```


# Cloud Run にデプロイする
ここまで来たらあとは Cloud Run にデプロイするだけです。


```
$ sudo gcloud components install beta
$ gcloud components update
$ gcloud beta run deploy --image gcr.io/[PROJECT-ID]/helloworld
```

リージョンの選択のあとに `Service name: (helloworld):` と聞かれますが、この場合はここに何も入力しなくて大丈夫でした。

出力された URL にアクセスすると `Hello world` と返ってきます。