Google Cloud Run を Swift 5 + IBM Kitura で書く

Google, Swift, プログラミング

これだと Cloud Functions for Firebase で無理やり JavaScript (TypeScript) で書くんじゃなくて Cloud Run で Swift で書くっていう選択肢も増えますね…。超うれしい……。好きな言語を使って Firebase Hosting で動的コンテンツ配信もできるんじゃないか!

Google Cloud Next ’19 で発表された Cloud Run。

今日、2019年5月6日現在ではベータリリースではありますが、Cloud Run を使って Firebase Hosting で動的コンテンツの配信もできるとのことで(Cloud Run on GKE は未サポート)。今回はすこーしだけのぞいてみることにします。

私の大好きな Swift で書ける

Google Cloud Functionsや Cloud Functions for Firebaseは JavaScript や TypeScript で書くことになりますが、Cloud Run はどんな言語でも使えることになっています。

Any language, any library, any binary

Use the programming language of your choice, any language or operating system libraries, or even bring your own binaries.

Features – Cloud Run  |  Google Cloud

実際に Cloud Run の Quickstartでも以下の言語でサンプルが紹介されています。

  • Go
  • Node.js
  • Python
  • PHP
  • Ruby
  • Shell
  • その他
    • Kotlin
    • Swift
    • Dart
    • Rust
    • その他
      • Clojure
      • Elixir
      • Haskell
      • Eclipse Vert.x

めっちゃある……。

Swift のサンプルは Swift 4.2 で Swifty を使っていますが、今回は Swift 5 と IBM Kitura で Cloud Run を試してみます。

環境

  • 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

あえて始めに雑感を書く

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

始める前に

まずは Google Cloud Platform のプロジェクトに対して課金が有効になっていることを確認します。今回は将来的に Firebase Hosting で動的コンテンツを運用したいので、Firebase のプロジェクトの課金を有効にしました。Google Cloud Platform で Firebase プロジェクトの課金を有効にすると、そのプロジェクトのプランが Blaze – 従量制 に切り替わります。

プロジェクトの課金を有効にしたら、次は Cloud Run API を有効にします。

そして、Google Cloud SDK の components を最新に update します。

サンプルアプリケーションを書く

ここからが本題、Swift で サンプルアプリケーションを書いていきます。

作業するためのディレクトリを作って swift package init します

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

swift build します。

これ以降は Xcode の補完を効かせたいので、Xcode プロジェクトを作成することにします。

$ swift package generate-xcodeproj
generated: ./cloudrun.xcodeproj

作成した Xcode プロジェクトを開いて、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()

続いて作業用ディレクトリに 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 にアップロードする

作業用ディレクトリで次のコマンドを実行し、Cloud Build を使ってコンテナイメージを build します。[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 にデプロイします。私は gcloud beta を入れていなかったので、ここで入れておきます。

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

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

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