docker-composeで作ったgoサーバーを雑にawsのec2にデプロイする

# はじめに
以前docker-composeで作成したgoサーバを簡易的にデプロイする必要があるタイミングがあったのですが、いい感じにハマりまくって地獄を見たのでとりあえずでawsにデプロイする方法を簡単にまとめておきたいと思います

# ローカルでdocker-composeで動くgoサーバを作る
まずはソースツリーから、、、

```
test-docker
│ 
├── docker
│   ├── app
│   │   └── Dockerfile
│   └── db
│       └── conf.d
│           └── mysql.conf
├── docker-compose.yml
├── go.mod
├── go.sum
├── main.go
└── models
    └── init.go

```
## Docker周り

```dockerfile:docker/app/Dockerfile
FROM golang:latest
RUN mkdir test-docker
WORKDIR /test-docker

RUN apt-get update \
  && apt-get install -y mariadb-client

COPY . .

RUN CGO_ENABLED=0 go build -o main main.go

CMD ["./main"]

```

```conf:docker/db/conf.d/mysql.conf
[mysqld]
character-set-server=utf8mb4
explicit-defaults-for-timestamp=1
general-log=1
general-log-file=/var/log/mysql/mysqld.log

[client]
default-character-set=utf8mb4

```

```yml:docker-compose.yml
version: "3"
services:
  app:
    build:
      context: .
      dockerfile: ./docker/app/Dockerfile
    container_name: test-docker-app
    volumes:
      - .:/go/src/test-docker
    ports:
      - "80:8080"
    depends_on:
      - mysql
    restart: always
  mysql:
    image: mysql:8.0
    restart: always
    container_name: test-docker-db
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: test
    hostname: mysql
    ports:
      - "3306:3306"
    volumes:
      - ./docker/db/conf.d:/etc/mysql/conf.d
      - ./log/mysql:/var/log/mysql

```

## goサーバー

```golang:main.go
package main

import (
	"test-docker/models"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})

	r.GET("/products", func(c *gin.Context) {
		var product models.Product

		models.DB.First(&product, 1)
		c.JSON(200, product)
	})
	r.Run()
}

```

```go:models/init.go
package models

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type Product struct {
	gorm.Model
	Code  string
	Price uint
}

var DB *gorm.DB

func init() {
	var err error

	DB, err = gorm.Open("mysql", "root:password@tcp(test-docker-db:3306)/test?charset=utf8&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}

	// スキーマのマイグレーション
	DB.AutoMigrate(&Product{})

	// Create
	DB.Create(&Product{Code: "L1212", Price: 1000})

	// Read
	var product Product
	DB.First(&product, 1)
}

```

```terminal:ターミナル
$ go mod init
go: creating new go.mod: module test-docker
```

以上で準備完了

```terminal:ターミナル
$ docker-compose up
```

# ec2インスタンスを立てる

1. awsのec2ダッシュボードに行く
<img width="600" alt="スクリーンショット 2020-05-13 14.37.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/79ff15a8-fa02-05c4-5986-3c1af8872dd3.png">

2. インスタンス作成ボタンを押す
<img width="600" alt="スクリーンショット 2020-05-13 14.37.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/178e5818-4753-afa5-472a-3d65f271a08e.png">

3. Linuxを選択
<img width="600" alt="スクリーンショット 2020-05-13 14.38.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/8144784f-4e87-8bda-054a-7c5f17c51ca0.png">

4. t2.microを選択
<img width="600" alt="スクリーンショット 2020-05-13 14.38.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/c7581d63-1b6f-3b30-a081-4e3a721b94af.png">

5. インスタンスの詳細設定で、「自動割り当てパブリックIP」を「無効」→「有効」に変更し次へ
<img width="600" alt="スクリーンショット 2020-05-13 14.38.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/97e8c8a7-d0b6-6655-3cdf-4d33701643e6.png">

6. ストレージ追加 >> タグの追加 という項目があるがデフォルトのまま次へを押す
7. 「ルール追加」ボタンを押しタイプを「http」に変更次へを押す（httpでのリクエストを受け付ける様にしています）
<img width="600" alt="スクリーンショット 2020-05-13 14.54.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/433eab11-3adb-c376-1889-4708abc56fd8.png">

8. 確認画面が出るのでそのまま次へ
<img width="600" alt="スクリーンショット 2020-05-13 14.39.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/1e137b81-18d1-8b77-201f-8927ab3e62a5.png">

9. 「新しいキーペアを作成」しキーペアをダウンロード >> 「インスタンスの作成」を押す
<img width="600" alt="スクリーンショット 2020-05-13 14.40.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/fe896efd-accf-34b7-d934-a277a8533f38.png">

10. 作成されたインスタンスを確認し「IPv4 パブリック IP」という項目のIPアドレスをコピーしておく
<img width="600" alt="スクリーンショット 2020-05-13 15.13.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/92971a98-d9af-050c-5f25-0af0ed68e1a2.png">


11. 起動したec2インスタンスにsshする

```terminal:ターミナル
$ mv ~/Downloads/test-docker.pem ~/.ssh
$ chmod 400 ~/.ssh/test-docker.pem
$ sh -i ~/.ssh/test-docker.pem ec2-user@コピーしたIPアドレス
```

# ec2インスタンスの環境構築

1.sshすると「本当につなげますか？」みたいなことが聞かれるので「yes」をタイピング

```terminal:ターミナル
$ssh -i ~/.ssh/test-docker.pem ec2-user@13.231.224.154

〜省略〜

Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '13.231.224.154' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
1 package(s) needed for security, out of 10 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-0-0-85 ~]$
```

2.docker, docker-composeをインストール

```terminal:ターミナル（ec2内部）
# dockerのインストール
$ sudo yum install -y docker          
$ sudo service docker start           # dockerの起動
$ sudo usermod -a -G docker ec2-user  # ec2-userをdockerグループに入れる

# docker-composeのインストール
$ sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
```

3.立ち上げたec2インスタンスに作成したファイルを送る

```terminal:ターミナル（ローカル）
# ローカルのディレクトリを立ち上げたインスタンスのhomeディレクトリにコピー
$ scp -r -i ~/.ssh/test-docker.pem ../test-docker ec2-user@コピーしたIPアドレス:~/

# 改めてたちあげたインスタンスにssh
$ ssh -i ~/.ssh/test-docker.pem ec2-user@
```

# 確認する

1.dockerを立ち上げ

```terminal:ターミナル（ec2内部）
$ cd test-docker # コピーしたディレクトリに移動

$ docker-compose up -d # バックグラウンドでdocker-composeを起動

$ docker ps # 正常に起動できてるかを確認
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
27042b2e038d        test-docker_app     "sh ./start.sh"          57 seconds ago      Up 55 seconds       0.0.0.0:80->8080/tcp                test-docker-app
6c820a45602e        mysql:8.0           "docker-entrypoint.s…"   57 seconds ago      Up 56 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   test-docker-db
```

2.ブラウザを起動し「コピーしたIPアドレス/products」で下記の様なレスポンスが返ってきたら成功です
<img width="600" alt="スクリーンショット 2020-05-13 15.53.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/7c68648d-81bf-440f-1138-348bd700acb1.png">


# まとめ
本当に雑ですがとりあえずこんな感じで簡単にdocker-composeをデプロイすることができます
sshをマイIPに制限するとか、scpするんじゃなくてgithubからpullできる様にするとか、、、
というかそもそもfagate使うとかまあツッコミどころはいいろいろありますが、とりあえずデプロイしないといけない時はこんな感じで十分なのかなと思います。

# 参考文献
- Go + gorm + gin と mysqlの環境をDockerで作ったった  
(https://qiita.com/Bmouthf/items/d3cfdbee74caeda77e3f)

- AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法
(https://qiita.com/y-do/items/e127211b32296d65803a)