AppEngine go1.11 開発 & デプロイ 環境構築【Linux & Mac】

# AppEngine go111 開発 & デプロイ 環境構築【Linux & Mac】

## はじめに
こんにちは、お久しぶりです。
以前以下の記事を書きました。
[GAE Go 開発環境の構築からテストアプリのデプロイまで【MacOS】](https://qiita.com/teikoku-penguin/items/782a23662d68aab1316c)

今回は**AppEngine go 1.11**での開発環境構築を記事にまとめたいと思います。

## goのインストール
ここでは**go**のインストールについて解説しようと思います。
方法は色々あるのですが**goenv**を使う方法を書いていきます。
**(shellはbashを前提に書きます)**

### goenvのインストール
ここでは二通りの方法を紹介します。

#### Githubからクローンする
Githubの[goenv Installation](https://github.com/syndbg/goenv/blob/master/INSTALL.md)を参考にします。

```bash:コンソール
# ユーザーのホームディレクトリにgoenvを置くためcdします
$ cd $HOME

# Githubからクローンしてきます
$ git clone https://github.com/syndbg/goenv.git ~/.goenv

# パスを通します
$ echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.bash_profile
$ echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.bash_profile

# goenvの初期設定が行われるように設定します
$ echo 'eval "$(goenv init -)"' >> ~/.bash_profile

# 設定を反映します
$ exec $SHELL

# $SHELLが設定されていない環境はでは代わりに以下でも可です
# $ source .bash_profile

# goenv -v で以下のようにバージョンが表示されればgoenvのインストールはOKです
$ goenv -v
goenv 2.0.0beta3

# インストール可能なgoのバージョンを一覧表示します
$ goenv install -l

# バージョンを指定してgoをインストールします
$ goenv install 1.11.5

# システム全体でgoenv内にインストールしたgoを使うように設定します
$ goenv global 1.11.5

# goを有効化します
$ goenv rehash

# go version でバージョンが表示されればOKです
$ go version
```

#### HomeBrewを使う(Mac OS X 向け)
HomeBrewのインストールについては省略します。
インストールしていない方は[公式ページ](https://brew.sh/index_ja)を参照してインストールして下さい。

```bash:ターミナル

$ brew update
$ brew install goenv

# goenvの初期設定が行われるように設定します
$ echo 'eval "$(goenv init -)"' >> $HOME/.bash_profile

# 設定を反映します
$ exec $SHELL

# $SHELLが設定されていない環境はでは代わりに以下でも可です
# $ source $HOME/.bash_profile

# goenv -v で以下のようにバージョンが表示されればgoenvのインストールはOKです
$ goenv -v
goenv 2.0.0beta3

# インストール可能なgoのバージョンを一覧表示します
$ goenv install -l

# バージョンを指定してgoをインストールします
$ goenv install 1.11.5

# システム全体でgoenv内にインストールしたgoを使うように設定します
$ goenv global 1.11.5

# goを有効化します
$ goenv rehash

# go version でバージョンが表示されればOKです
$ go version
```

## google-cloud-sdkのインストール
google-cloud-sdk(以下 gcloud-sdk)を使用するにはpython 2.7.xが必要です。
`$ python -V`を打ってバージョンが表示されない場合は事前にインストールして下さい。

### ダウンロードと展開
gcloud-sdkはOSによりダウンロードするファイルが異なります。
各自のOSに合った物をダウンロードして下さい。

- [Linux全般](https://cloud.google.com/sdk/docs/quickstart-linux?hl=ja)
- [Debian / Ubuntu](https://cloud.google.com/sdk/docs/quickstart-debian-ubuntu?hl=ja)
- [RedHat / CentOS](https://cloud.google.com/sdk/docs/quickstart-redhat-centos?hl=ja)
- [Mac](https://cloud.google.com/sdk/docs/quickstart-mac-os-x?hl=ja)

ダウンロードが終わったらファイルを展開します。
今回は展開後のファイル名を`google-cloud-sdk`とし、配置場所はホームディレクトリとします。

### インストール
ホームディレクトリへの展開が終わったところでインストールスクリプトを実行します。

```bash:コンソール

# ホームディレクトリにcdしてインストールスクリプトを実行
# 途中何度か質問されるのでYやエンターを押します
$ cd $HOME
$ ./google-cloud-sdk/install.sh

# 設定を反映します
$ exec $SHELL

# $SHELLが設定されていない環境はでは代わりに以下でも可です
# $ source $HOME/.bash_profile

# gcloud -v でバージョンが表示されればOKです
$ gcloud -v
```

### コンポーネントの追加
AppEngine go のコンポーネントを追加でインストールします

```bash:コンソール

# コンポーネントの一覧を表示
$ gcloud components list

# app-engine-go コンポーネントをインストール
$ gcloud components install app-engine-go
```

### Googleアカウントへのログインとプロジェクト設定
gcloud-sdkと自分のGoogleアカウントを紐づけ、使用するGCPプロジェクトを設定します。

GCPプロジェクトをまだ作成していない方はプロジェクトを先に作成して下さい。
プロジェクトの作成・設定は[GCPコンソール](https://console.cloud.google.com/projectselector/appengine/create?lang=go&st=true&hl=ja)から行えます。

プロジェクトの作成が終わったらプロジェクトIDを控えておいて下さい。
![{65511F3D-98CC-4CF5-A6D6-0D170DB26389}.png](https://qiita-image-store.s3.amazonaws.com/0/258309/20d16c06-1b69-bd09-fef9-7637b49db0af.png)

```bash:コンソール

# 指示に従ってログインして下さい
$ gcloud auth login

# デフォルトで使用するプロジェクトを指定します
$ gcloud config set project <プロジェクトID>

# gcloud config list と打って設定したアカウントとプロジェクトが出ればOK
$ gcloud config list
```

## ローカルサーバーとクラウド上で Hello,world! してみる
ある程度設定できたところでAppEngineで動くコードを書いていきたいと思います。
今回は go111 ランタイムから使用できるようになった module 機能を使用します。

### ライブラリルートの設定と開発ディレクトリの準備
ライブラリルート(GOPATH)の設定とソースコードを置くディレクトリを準備したいと思います。

```bash:コンソール

# ホームディレクトリにcdします
$ cd $HOME

# ホームディレクトリにgoフォルダを作ります
$ mkdir go

# $GOPATH(ライブラリルート的なの)を設定します
$ echo 'export GOPATH="$HOME/go"' >> ~/.bash_profile

# $GOPATH/bin にパスを通します
$ echo 'export PATH="$GOPATH/bin:$PATH"' >> ~/.bash_profile

# 設定を反映します
$ exec $SHELL

# $SHELLが設定されていない環境はでは代わりに以下でも可です
# $ source $HOME/.bash_profile

# ソースコードを置くディレクトリを作ります
# <>の中はお好きな名前でどうぞ
$ mkdir -p <project-name>/src/github.com/<githubID>/<app-name>

# 以下のような構成になっていればOKです
# $HOME
# └── <project-name>
#    └── src
#       └── github.com
#           └── <githubID>
#               └── <app-name>
```

### モジュールの初期化とソースコードの配置
go module ではgo.modファイルを使用して依存関係の管理などを行います。
go module を使用するために `go mod init <module-name>` で go.modファイルを生成します。
main.go と app.yamlも作成して配置します。

```bash:コンソール

# 先程作成した<app-name>にcdします
$ cd <project-name>/src/github.com/<githubID>/<app-name>

# モジュールを初期化します
$ go mod init github.com/<githubID>/<app-name>

# main.go と app.yamlを作ります
$ touch main.go app.yaml
```

```yaml:app.yaml
runtime: go111
service: default

handlers:
  - url: /.*
```

```go:main.go

package main

import (
    "net/http"
    "os"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(200)
        w.Write([]byte("Hello,World!"))
    })

    port := os.Getenv("PORT")

    if port == "" {
        port = "8080"
    }

    http.ListenAndServe(":" + port, nil)
}
```

### ローカルサーバーの起動
app.yamlとmain.goを作成し、最小限の環境が整ったのでローカルサーバーで実行します。

```bash:コンソール
# app.yamlと同じディレクトリで以下のコマンドを入力し、ローカルサーバーを起動します
# http://localhost:8080/ にアクセスして Hello,World! が表示されればOKです
$ dev_appserver.py app.yaml
```

### AppEngineへのデプロイ
ローカルサーバーで正常に動いたらAppEngineへデプロイします。
プロジェクトの作成やgcloud-sdkの設定等は済んでいるものとします。

```bash:コンソール
# app.yamlと同じディレクトリで以下のコマンドを打ちます
# プロジェクト名やサービス名を確認して正しければYを押してしばらく待ちます
$ gcloud app deploy app.yaml

# デプロイが完了したら以下のコマンドでデプロイしたアプリケーションをブラウザで開くことができます
# Hello, World! が表示されれば成功です
$ gcloud app browse
```

お疲れ様でした。
以上で環境の構築とデプロイは終了です。

## 補足
$GOPATH配下にソースコードを置きたい時は意図的に `$GO111MODULE=off` を設定する必要があります。

## さいごに
ここまでお読みいただきありがとうございます。
誤字脱字、プログラムの間違いや誤った記述などございましたらコメント頂けますと幸いです。