AWS Cloud9でdepとDockerを使用したGo言語のAPIサーバーの開発環境を構築する

Go言語の開発は普通はローカルのPCで行う前提で環境構築が説明されているのですが、
AWS Cloud9はGo言語をサポートしているので、どれくらい開発に使えるものなのか試してみました。

拙作の[APIサーバーのstarter-kit](https://github.com/gemcook/go-gin-xorm-starter)が動作することを目標にしました。

このAPI starter-kitは、以下のような構成になっています。

* Ginフレームワーク
* O/Rマッパーにxorm
* MySQLをデータベースとして使用
* ローカル開発環境用にDockerを使用してMySQLを起動
* nodemonを使用してファイル編集時にAPIサーバーを自動リロード

結論からいくと、これらの全てが問題なく動作しました。

順番に設定手順を説明していきます。

以下のことが前提です。

* AWSアカウントを持っている
* bashの操作が出来る

# AWS Cloud9にログイン

AWS Cloud9の起動は既に終わっているところから説明します。
まだの場合、設定と起動手順は[こちらのQiita記事](https://qiita.com/icck/items/7705ef6871e261d6535e)などを参考にして下さい。

Cloud9を立ち上げて、下の画像のような状態からスタートします。
主に下側にある、`bash`のターミナルにコマンドを打ち込んで操作します。

<img width="1168" alt="Cloud9画面" src="https://qiita-image-store.s3.amazonaws.com/0/193814/00d770fd-623d-16ee-d68a-3a6c1bf4e94d.png">


# Go言語のバージョン確認と更新

```sh:Cloud9のターミナル
$ go version

# 表示結果
go version go1.9.1 linux/amd64
```

`go version` が`go1.10.x`の方がAPIサーバーの自動リロードが高速に行え、快適な開発がもたらされるため、Go言語のバージョンをアップデートします。

Go言語のアップデートには次のコマンドを実行します。
(go1.10.3は 2018/07時点の最新のバージョンです)

```sh:Cloud9のターミナル
$ wget https://storage.googleapis.com/golang/go1.10.3.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf ./go1.10.3.linux-amd64.tar.gz
$ rm ./go1.10.3.linux-amd64.tar.gz
$ go version

# 表示結果
go version go1.10.3 linux/amd64
```

# 環境変数の設定

以下の4つのコマンドを実行して、PATHとGOPATHを設定します。

```sh:Cloud9のターミナル
$ echo 'export GOPATH=$HOME/go' >> ~/.bashrc
$ echo 'export GOBIN=$GOPATH/bin' >> ~/.bashrc
$ echo 'export PATH=$GOBIN:/usr/local/go/bin:${PATH}' >> ~/.bashrc
$ . ~/.bashrc
```

# Go言語のパッケージ管理ツールdepのインストール

```sh:Cloud9のターミナル
$ mkdir -p $GOBIN
$ curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
```

# リポジトリのclone

[go-gin-xorm-starterリポジトリ](https://github.com/gemcook/go-gin-xorm-starter)をcloneします。

```sh:Cloud9のターミナル
$ git clone https://github.com/gemcook/go-gin-xorm-starter.git $GOPATH/src/github.com/gemcook/go-gin-xorm-starter
```

これ以降、リポジトリルートで作業を行うため、cdコマンドで移動します。

```sh:Cloud9のターミナル
$ cd $GOPATH/src/github.com/gemcook/go-gin-xorm-starter
```

このディレクトリが左のフォルダビューで表示されるように設定します。

フォルダービュー`Show Home in Favorites`を選択します。

<img width="445" alt="フォルダービューShow Home in Favoritesを選択" src="https://qiita-image-store.s3.amazonaws.com/0/193814/da5e68b3-6bb3-98e6-e35e-79bfb94ef5fa.png">


~/go/src/github.com/gemcook/ までディレクトリを開いていき、go-gin-xorm-starterを`Add to Favorites`します。

<img width="480" alt="Add to Favorites" src="https://qiita-image-store.s3.amazonaws.com/0/193814/0deba3d4-69f3-39b7-3904-f69732b57d17.png">

# nodemon　のインストール

`nodemon` コマンドをインストールします。

```sh:Cloud9のターミナル
$ npm i -g nodemon
```

`node`や`npm`がインストール済みなので簡単です。

# docker-composeコマンドをインストールする

Cloud9には`docker`コマンドは初めから入っていますが、`docker-compose`は入っていません。

以下のコマンドでインストールします。

```sh:Cloud9のターミナル
$ sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
```

(2018/07時点の最新のバージョンなので、今時点の最新を入れたい場合は、`docker-compose`の[リリース一覧](https://github.com/docker/compose/releases)から最新のバージョンのインストールコマンドを確認して下さい)

# Dockerを使用してMySQLを起動する

念のため既存のMySQLを停止しておきます。

```sh:Cloud9のターミナル
$ sudo service mysqld stop
```

docker-composeを使用してdockerを立ち上げます。

```sh:Cloud9のターミナル
$ docker-compose up
```

ターミナルにdockerの実行ログが流れます。

<img width="848" alt="docker-compose up実行結果" src="https://qiita-image-store.s3.amazonaws.com/0/193814/cbbd3e94-d4a7-556a-c039-ad4d6a0e8789.png">

このターミナルタブはそのまま置いておき、フォルダービューから`go-gin-xorm-starter` を選択して、右クリックメニューから`Open Terminal Here`を選択すると新しいタブが表示されます。

<img width="812" alt="Open Terminal Here" src="https://qiita-image-store.s3.amazonaws.com/0/193814/3140cbb9-c527-00c6-d39e-7738841b19cf.png">


ちなみに、新しいタブはエディタエリアに開きますが、ドラッグ&ドロップで下のパネルに移動できます。

# APIサーバーを立ち上げる

`.env`ファイルの準備が必要なのでexampleをコピーして作ります。

```sh:Cloud9のターミナル(2)
$ cp .env.example .env
```

APIサーバーの依存パッケージをdepコマンドでインストールします。

```sh:Cloud9のターミナル(2)
$ dep ensure
```

サンプルのデータベースを作成します。

```sh:Cloud9のターミナル(2)
$ sh ./fixtures/init_db.sh
```

APIサーバーを起動します。

```sh:Cloud9のターミナル(2)
$ make start
```

APIサーバーのルーティング一覧がログとして表示されていれば成功です。

<img width="951" alt="APIサーバー起動ログ" src="https://qiita-image-store.s3.amazonaws.com/0/193814/20d2a407-a76e-10a1-1cee-5a7ec315488a.png">

# APIを呼び出す

`Preview Running Application`を開くと外部からアクセス可能なURLが表示されます。
このURLは、ポート8080で起動しているAPIサーバーに繋がっています。

<img width="477" alt="Preview Running Application" src="https://qiita-image-store.s3.amazonaws.com/0/193814/f8a2ac7e-4385-0c7d-7677-687e1c32d3f9.png">

Cloud9の右側に内部ブラウザが開き、下記のようなURLにアクセスしています。

`https://<環境ID>.vfs.cloud9.<AWSリージョン>.amazonaws.com/`

starter-kitは `/v1/fruits` でアクセスするとフルーツ一覧をJSONで返すので、

`https://<環境ID>.vfs.cloud9.<AWSリージョン>.amazonaws.com/v1/fruits` にアクセスして、APIの動作確認が出来ます。

<img width="517" alt="/v1/fruitsにアクセス" src="https://qiita-image-store.s3.amazonaws.com/0/193814/fbb9b51d-df2e-5ac5-82d9-5e0d58507f1d.png">

<img width="519" alt="/v1/fruitsにアクセスした結果" src="https://qiita-image-store.s3.amazonaws.com/0/193814/bcc74e69-7c34-50e8-1c69-718694e95914.png">

# starter-kitを拡張していくには

以下の作業を行って下さい。

### リポジトリの名前を変更して、自分のものにします

`$GOPATH/src/github.com/<あなたのGitHubユーザー名>/<任意のリポジトリ名>`

### ソースコード全体に対して、以下の置換処理をします

置換前: `gemcook/go-gin-xorm-starter`
置換後: `<あなたのGitHubユーザー名>/<任意のリポジトリ名>`

# 【番外編】 adminerとphpMyAdminを使用してMySQLの内容を確認する

starter-kitでは`docker-compose`を使用して、MySQLを立ち上げましたが、
MySQL以外に、adminerとphpMyAdminも立ち上がっています。
Cloud9の仕様で、外部に公開出来るポートは `8080, 8081, 8082` に限られているため、adminerかphpMyAdminの使用する方のポートを8081に書き換える必要があります。

まずは、既に立ち上がっているdocker-composeを停止します。

以下のコマンドを実行するか、実行中のターミナルで`CTRL+C`で中断を送信します。

```sh：Cloud9のターミナル
$ docker-compose down
```

docker-compose.ymlを書き換えます。

```yml:docker-compose.yml(adminerを使用する場合)
  adminer:
    image: adminer
    ports:
      # - 10080:8080
      # adminerを使用する場合、10080:8080 -> 8081:8080に変更する
      - 8081:8080
    depends_on:
      - mysql
```

```yml:docker-compose.yml(phpMyAdminを使用する場合)
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_HOST: mysql
      PMA_USER: root
      PMA_PASSWORD: password
    ports:
      # - 9080:80
      # phpMyAdminを使用する場合、9080:80 -> 8081:80に変更する
      - 8081:80
    depends_on:
      - mysql
```

再び、dockerを起動します。

```sh：Cloud9のターミナル
$ docker-compose up
```

　そのあと、ブラウザから `https://<環境ID>.vfs.cloud9.<AWSリージョン>.amazonaws.com:8081/` にアクセスします。

<img width="875" alt="phpMyAdmin　アクセス例" src="https://qiita-image-store.s3.amazonaws.com/0/193814/a936ee6e-cdc5-5bf1-33bf-56cd9ef87b15.png">


# まとめ

普段Go言語の開発をしているVSCodeと比べると、支援機能は正直いまいちです。

しかし、AWS Cloud9で大体のGo言語の開発は出来そうです。
大抵の必要なものは初めからインストール済みなので入門用の環境としては良いのではないでしょうか。