App Engine Flexible で SpringBoot のプロジェクトを Gradle でデプロイするまで

Google App Engine の Flexible Environment が公開されてだいぶ立ちますが、**gradleでspring-boot**のプロジェクトをデプロイして動かすようなサンプルが見つからなかったのでメモです
公式ドキュメントは**maven**中心だしなっ

### とりあえずソース
githubに置いておきます
[appenginetest](https://github.com/anego/appenginetest)

# 環境
## OS
Windows10 pro
## Java
Java SE 1.8.0_121
## Gradle
3.4.1
## Eclipse
Pleiades All in One 4.6.3.v20170323

# 準備
Google Cloud Platform のアカウント作成などはここでは省略します
## Google Cloud SDK のインストール
[公式ドキュメント](https://cloud.google.com/sdk/)がわかりやすいですので省略

### App Engine SDK for Java のインストール
SDKの初期化まで完了したら、以下のコマンドを投げてJava用のSDKをインストールします

```
gcloud components install app-engine-java
```

## GCPでテスト用プロジェクトの作成
Google Cloud Platform で新規のプロジェクトを作成します
今回は**springboottest**という名前で作っていきます
プロジェクトIDはあとで使うのでメモしておきましょう

# Spring-Boot プロジェクトの準備
Eclipse を使用して作っていきます
## プロジェクト作成
ファイル -> 新規 -> その他 から Gradleプロジェクトを選択
プロジェクト名は**appenginetest**とでもしておきます

次の画面では、インストールしたGradleを指定します
Eclipseの設定によってはデフォルトのままでもいけたかな?

次の画面で構成を確認し、警告とか出てなければ完了
gradleの設定がうまくないと警告出てきます

完了後はsrc配下にLibrary.javaとLibraryTest.javaが作られていますが、使わないので削除しておきます

## gradleの設定
build.gradle を開き、いろいろと設定します
### App Engine プラグイン
[この辺を参考に](https://cloud.google.com/appengine/docs/flexible/java/using-gradle)しながら設定します
公式では**gretty**というプラグインを使用していますが、今回はSpring-Bootを使おうと思うので外します

まぁ使い方がわからんかっただけなんですけどね・・・

### build.gradle サンプル
で、spring-boot とかも設定したのがこちら

```groovy:build.gradle
buildscript {
	repositories {
		jcenter()
		mavenCentral()
	}
	dependencies {
		classpath 'com.google.cloud.tools:appengine-gradle-plugin:1.1.1'
		classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.+'
	}
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'com.google.cloud.tools.appengine'
apply plugin: 'eclipse'

def defaultEncoding = 'UTF-8'
[compileJava, compileTestJava]*.options*.encoding = defaultEncoding

def jdkVersion = 1.8
sourceCompatibility = jdkVersion
targetCompatibility = jdkVersion

jar {
	baseName = 'appenginetest'
	version = '1.0-SNAPSHOT'
}

repositories {
	maven {
		url 'https://maven-central.storage.googleapis.com'
	}
    jcenter()
	mavenCentral()
}

dependencies {
	compile 'javax.servlet:javax.servlet-api:3.1.0'
	compile 'com.google.appengine:appengine:+'

	compile('org.springframework.boot:spring-boot-starter-web:1.5.+'){
		exclude module: 'spring-boot-starter-tomcat'
	}

	compile group: 'org.springframework.boot', name: 'spring-boot-starter-jetty', version: '1.5.+'
}

```

とりあえずデプロイして何かしら表示するだけなのでこんなもんですかね

## ソースとか
次にSpring-Bootで使用するjavaファイル

```java:Application.java
package appenginetest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

	@RequestMapping(value = "/")
	String hello() {
		return "Hello World!";
	}
}
```

デプロイできて動いてるのが確認するだけなので"Hello World!"が表示できるだけです

## AppEngine用の設定
次にAppEngine用の設定ファイルを書きます
場所は*src/main/appengine*になります

```yaml:app.yaml
runtime: custom
env: flex

runtime_config:
   jdk: openjdk8

automatic_scaling:
  min_num_instances: 1
  max_num_instances: 1
```

標準のjava8+jettyを使うなら*runtime*を*java*と指定しますが、今回は*Spring-Boot + jetty*のカスタム環境なので*custom*とします
*automatic_scaling*は起動するインスタンスの数で、未指定の場合だと最低で2つ起動してしまうので1を指定しておきます

他にも色々ありますが、あとは[公式](https://cloud.google.com/appengine/docs/flexible/java/configuring-your-app-with-app-yaml)を参照

## Dockerfileの設定
AppEngineで動くDocker用の設定を書きます
場所は*src/main/Docker*になります

```:Dockerfile
FROM gcr.io/google_appengine/openjdk8
VOLUME /tmp
ADD appenginetest-1.0-SNAPSHOT.jar app.jar
CMD [ "java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
```

*appenginetest-1.0-SNAPSHOT.jar*のところはプロジェクトをビルドしたときに作られるjarファイルを指定します

## ビルドしてみる
コマンドプロンプトとかで作ったプロジェクトのルートまで移動し、以下のコマンド実行

```
gradle appengineStage
```

設定がうまくいっていれば*BUILD SUCCESSFUL*で終了します

# App Engine にデプロイ
## プロジェクトの設定
今回のプロジェクトの用の設定を作ります
以下のコマンドで設定を作ります

```
gcloud config configurations create [NAME]
```

[NAME]にはなにかわかりやすい名前をつけてください

設定後は設定を有効にさせます

```
gcloud config configurations activate [NAME]
```

設定を有効にし、Google Cloud  Platform で作ったプロジェクトを紐付けます
で、ここで注意、プロジェクト名は**プロジェクトID**の方を使用してください
![2017-04-02_19h00_46.png](https://qiita-image-store.s3.amazonaws.com/0/25904/6132de93-93a1-77b8-5ad9-2efeef659245.png)
ここの赤いとこですね、間違ってプロジェクト名を指定しても特にエラーは出ませんが、最後のデプロイで失敗します

```
gcloud config set project [PROJECT]
```

プロジェクトのデフォルトゾーンの設定

```
gcloud config set compute/zone us-east1-b
```


設定の内容を表示するには以下のコマンド

```
gcloud config configurations describe [NAME]
```

有効な設定が何かは以下のコマンドで確認できます

```
gcloud config list
```

有効な設定ができたらログインします

```
gcloud auth login
```

ブラウザが開き、ログインするアカウント一覧が出ますのでGoogle Cloud Platform でログインできるアカウントを選択
次の画面で Google Cloud SDK にアクセス許可の確認が出るので許可します

この辺の手順はちょっと自信ないなー
余計なコマンド投げてるかも・・・

公式のドキュメントは[ここ](https://cloud.google.com/sdk/docs/initializing)です

## App Engine にデプロイ
有効な設定まで確認できたらいよいよデプロイです
以下のコマンドをプロジェクトのルートから実行します

```
gradle appengineDeploy
```

コマンド実行後は結構待ちます
この小さなサンプルプロジェクトでも5分程度かかります

## 見てみる
デプロイコマンドが帰ってきたら App Engine のダッシュボードの右上にリンクが表示されているので、そこから確認してみましょう
"Hello World!"が表示されていれば成功です

# で
これで最低限はできました
次はDB関係ですが、別にあげようと思います