DockerとGoで簡単にapiサーバーを立ててみる

# はじめる前に
こんにちはRIN1208です 
この記事はDockerとGoを少し触れている程度の学生が書いていますので分からない点、間違っている点等がございましたらコメントして頂けると幸いです。
今回の書いたDockerfileなどは[こちら](https://github.com/rin1208/docker-hands-on)に置いてあります。

## この記事の対象
- Dockerについてなんとなく知っている人
- Goを知っている人
- とりあえず両方触ってみたい人

## この記事で触れない事
- Dockerがどのように動いているか
- Dockerの環境構築について
- Docker Hubの詳細について
- Dockerとは何か
- Goのコードの詳細について
- マルチステージビルド

##開発環境
- macOS Catalina
- Go(ver 1.14.4)こちらはなくても問題ありません
- Docker（後半でDocker-composeも使用します）
- VSCode（お好みのエディターを使用して下さい）
上記の環境で説明していきます

# さわってみる
### 今回やる事
- コンテナの起動などの基本動作
- Dockerfileを書く
- Goで簡単なWebサーバーを立てる

### 今回触れない事
- Docker Networkを使用したコンテナ間通信

##Nginxをdockerで起動してみる

下記のコマンドを実行してみましょう

```
docker run --name hoge -d -p 8080:80 nginx
```
起動後に`http://localhost:8080/`に接続するとWelcome to nginx!と表示されます。
#### 今入力したコマンドの説明
docker run:  コンテナを起動するコマンドです
--name:　起動するコンテナに名前をつけられます。今回はhogeという名前です
-d: このオプションを使用するとバックグラウンドで起動することができます
-p: ポートのオプションです`ホストのポート:コンテナのポート`で指定できます。今回はホストが8080、コンテナが80で起動しています。

### 起動したコンテナの確認

下記のコマンドを実行してみましょう

```
docker ps
```
すると以下のように表示されると思います

```
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
63940a31eae8        nginx               "/docker-entrypoint.…"   3 seconds ago       Up 2 seconds        0.0.0.0:8080->80/tcp   hoge
```


#### 表示項目の説明
CONTAINER ID: コンテナのIDです。コンテナを指定する際に使用します
IMAGE:　使用したDockerimageです。今回はnginxを使用したのでnginxになっています
COMMAND: コンテナが起動する際に与らたコマンドです
CREATED: コンテナを作成してからの時間です
STATUS: 起動、停止してからの経過時間です
PORTS: コンテナ及びホストの使用ポート
NAMES: コンテナの名前です。こちらの名前を使用してコンテナを指定することもできます

### 起動したコンテナの停止
下記のコマンドを実行してみましょう

```
docker stop hoge
```
実行するとコンテナが停止しました。`docker ps`で確認してみましょう

```
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

とだけ表示されます。こちらの項目に先ほど確認したコンテナが存在しなければコンテナの停止ができています。
また`docker ps`コマンドは起動しているコンテナを確認するコマンドなので他にも起動しているコンテナがある場合は表示されます

## Dockerfileを書いてコンテナを作成する
次はDockerfileを書いてGoのapiサーバーを立ち上げてみましょう。 
今回はGoのwebフレームワークである[Gin](https://github.com/gin-gonic/gin)を使用します。
### 今回触れない事
- マルチステージビルド
-  Go Modules

### Dockerfileとmain.goを作成する


適当な同じディレクトリに内にDockerfileとmain.goを作成しましょう。

```main.go

package main

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

func main() {
	r := gin.Default()
	r.GET("/", hoge)
	r.Run() // デフォルトが8080ポートなので今回は変更しません
}

func hoge(c *gin.Context) {
	c.JSON(200, "hogeeeeeeee")
}

```

### dockerfile

```dockerfile

FROM golang:1.14

RUN  go get -u github.com/gin-gonic/gin

WORKDIR /app　
COPY . /app

ENV CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64

EXPOSE 8080

CMD ["go", "run", "main.go"]

```
#### 設定項目の説明

FROM : 実行する環境を指定します。DockerHubにあるimageをしますので使用する際はDockerHubにあるかどうか確認してください。バージョン指定がない場合は最新バージョン(latest)が使用されます。  

RUN : コマンドを実行します

WORKDIR : 作業ディレクトリを設定します

COPY : コンテナにディレクトリ、ファイルるをコピーします。

ENV : コンテナに永続的な環境変数を定義します。`コピーする対象  コンテナ内のコピー先`で指定できます

EXPOSE : コンテナの使用ポートを指定します

CMD : 実行するコンテナにコマンドと引数を提供します


### Dockerfileからimageを作成し起動する。

以下のコマンドでbuildしimageを作成します。Dockerfileのあるディレクトリ内で実行しましょう。
今回はmy-imageという名前のimageを作成し起動します。

```
docker build -t my-image .
```

buildが完了しましたら下記のコマンドを実行しREPOSITORYの項目にmy-imageという名前があるのを確認しましょう。

```
docker images
```

下記のようにREPOSITORYの項目にmy-imageとあれば問題ありません。

```
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
my-image                         latest              b498e18e4087        6 hours ago         956MB
```

確認することができましたら以下のコマンドでコンテナを起動させましょう。
今回は先ほど作成したimageのmy-imageを使用しmy-apiという名前のコンテナを作成しています。

```
docker run -it --name my-api  my-image 
```
今回は-dオプションをつけていないのでバックグラウンドで動作させていませんが-dオプションを指定すればバックグラウンドで動かすことができます。

```
docker run  -d -it --name my-api  my-image
```

上記のコマンドでapiサーバーが起動できたのを確認できます。
今回は`http://localhost:8080/`にて立ち上がっています。

## docker-composeを使ってみる

次は先ほど立ち上げたコンテナをdocker-composeで立ち上げます。
Mysql等との接続は記事が長くなるのに加え、少しややこしいので今回は触りません。

####docker-compose.yml

```yml
version: "3" 
services:
  api: # コンテナの名前
    build: .　# dockerfileの場所を指定できます。
    ports:
      - "8080:8080"
    tty: true
```
##### コンテナのビルド

下記のコマンドでビルドします。
ymlファイルを書き換えた際はbuildしないと反映されません。ちょくちょく忘れてやらかします

```
docker-compose build
```

##### コンテナの起動

下記のコマンドでコンテナを立ち上げます。 今回は -d オプションを使用しバックグラウンドにて立ち上げています

```
docker-compose up -d 
```

起動できましたら`http://localhost:8080/`にて確認してみましょう。

##### 起動したコンテナの確認
立ち上がっているコンテナは下記のコマンドにて確認することができます。

```
docker-compose ps
```
すると以下のように表示されると思います。

```
      Name             Command       State           Ports
-------------------------------------------------------------------
docker-test_api_1   go run main.go   Up      0.0.0.0:8080->8080/tcp
```

Name : コンテナの名前
Command : コンテナが起動する際に与らたコマンドです
State : コンテナのステータスです
Ports :　コンテナ及びホストの使用ポートです

##### 起動したコンテナの停止

下記のコマンドでコンテナを停止させることができます。

```
docker-compose down
```
 

#終わりに
ここまで読んでくださりありがとうございます。
この記事は友人のDockerの勉強のためになればと思い書きました。また初めてDocker触る方の手助けになれば幸いです。
間違っている点などがございましたらコメントなどで指摘していただけると助かります。