Golang×Nginx×EC2

以前からWebアプリケーションの勉強をしていたけど, 実際に作ったものをデプロイしたことはなかったので色々調べてみた. 今後使うことになると思うのでメモをしておく.

## 環境
Ubuntu 18.04.2 LTS

## AWSのサービスにも色々あった
アプリケーションをデプロイしたい!!と思ったときにまず頭に浮かんだのがAWSだった(それぐらいしか知らなかった)ので調べると, EC2やらElastic Beanstalkやら色々あったが, Elastic Beanstalkで使えるgoのバージョンが古かったのでEC2を使うことにした.

## インスタンスの作成
AWSのコンソールにログインし, 左上にある[サービス]からEC２を選択すると下の画像になる. 
![Screenshot from 2019-04-01 03-32-14.png](https://qiita-image-store.s3.amazonaws.com/0/316006/e9a10e93-4f93-72a4-d7fc-2a74f6c8e726.png)

[インスタンスの作成]を押すとマシンイメージの選択画面がででくる. 今回はAmazon Linux 2を使い, その後の設定は特にいじらずに進めた.
 起動する前にキーペアの作成をする必要があるので, キーペア名を入力し, ダウンロードする. 

## セキュリティグループの設定
インスタンスを作成し, インスタンスの管理画面に移動する.
インスタンスを選択した状態で下記画面から[launch-wizard]を選択.
![Screenshot from 2019-04-01 04-47-30.png](https://qiita-image-store.s3.amazonaws.com/0/316006/b4305bd1-fc65-faab-6a31-7b96cc4ddd23.png)
選択したあと, 下の方にある[インバウンド]の[編集]を選択. インバウンドのルールを編集　が出てくるので[ルールを追加]を選択し, [タイプ]をHTTPにしてほかは触らずに[保存]を押す.
これでセキュリティグループの設定は完了.

## sshでインスタンスにアクセス
ここからWindows, Mac, Linuxで操作が変わる.(今回はLinux)
インスタンスの管理画面に[接続]があり, それを押すと下の画像のようにsshを使った接続方法が書いてある.
![Screenshot from 2019-04-01 03-52-37.png](https://qiita-image-store.s3.amazonaws.com/0/316006/5b6e1009-0fba-806d-5537-8e46bc1b5591.png)

パブリックDNSはインスタンスを選択すると下の方に表示される.
インスタンスにsshで接続しようとすると「本当に接続しますか?」みたいな感じで確認されるので「yes」を入力. これでインスタンスに接続できる.

## インスタンスの環境設定
今回はgo言語で作ったアプリケーションをnginx(エンジンエックス)で動かすので, インスタンス内でインストールする必要がある.　
インストールする際は下記コマンドでインストールする.

```
$ sudo amazon-linux-extras install nginx1.12
$ sudo amazon-linux-extras install golang1.11
```
amazon-linux-extras install コマンドでGoやnginx以外にもdocker, php, postgresqlなどインストールできる. 下記コマンドでインストールできるもや, 使用中のサービス一覧を見れる.

```
$ amazon-linux-extras list
```

## Nginxの設定
次にNginxの設定をしていく. まずは正しく動かせるかどうか確認するために下記コマンドで起動する.

```
$ sudo systemctl start nginx.service 
```

その後, http://[インスタンスのパブリックDNSもしくはIP] にアクセスすると下記画面が表示される.
![Screenshot from 2019-04-01 04-19-30.png](https://qiita-image-store.s3.amazonaws.com/0/316006/b8282d39-695e-3547-12f4-8c6ca663fe00.png)

この画面が映れば成功している. 
次に設定ファイルを編集しアプリケーションサーバー(Webアプリ)と接続が可能な状態にする.

```
$ sudo vi /etc/nginx/nginx.conf
```
上記コマンドでテキストエディタを起動し, serverと書いてある箇所を編集する.

```
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  localhost; 
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                fastcgi_pass    127.0.0.1:9000; #接続先 
                include         fastcgi_params; 
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
}
```
変更を加えたら保存し, 下記コマンドでnginxをリロードする.

```
$ sudo systemctl reload nginx.service
```

## Go言語で書いたWebアプリケーションを用意する
メモ用なので簡単なWebサーバーを書いてコンパイル, バックグラウンドで実行する. 

```
$ sudo mkdir /var/app; cd /var/app
$ sudo vi app.go
```

テストコード

```golang:app.go
package main

import (
    "fmt"
    "net"
    "net/http"
    "net/http/fcgi"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}

func main() {
    l, err := net.Listen("tcp", "127.0.0.1:9000")
    if err != nil {
        return
    }
    http.HandleFunc("/", handler)
    fcgi.Serve(l, nil)
}
```

下記コマンドでコンパイル, 実行

```
$ sudo go build app.go
$ ./app &
```

先程と同様にパブリックDNSかIPアドレスでアクセスすると, うまくいっていればHello, World!が表示される.

## おわりに
少し苦戦したところもあったけれどとりあえず動かせて万々歳. 今後はDBを追加しもう少し規模を大きくしてみたり, dockerをデプロイしてみたりしたい. 
色々やりたいことが増えたが無料枠を超えないようにしなければ...

## 参考記事
 AWSでnginx+golangが動く環境を作る
-https://qiita.com/TECHFUND/items/1b005563a782d68f7c17

[Nginx + Golang でWebアプリケーション開発を試してみた](http://umegusa.hatenablog.jp/entry/2015/02/22/025832)