Golangの超シンプル構成webアプリをDockerで起動するところまで

## 前提
[Golangでクラスを分割したら疑問点が出た話](https://qiita.com/nitt_san/items/612212e4073c7a041801)の続き

## やること
* 前回作成したwebappについて、Dockerfileを書いてDocker imageを作成、コンテナ起動する

## ファイル構成
### ディレクトリ構成
```Directory.tree
golang_webapp_sample
├── Dockerfile
└── src
    └── main
        ├── golang_webapp_sample.go
        └── handler
            └── http_handler.go
```

### Dockerfile
```Dockerfile
# 基本にするイメージはgolang:alpineなんよ
# golangだけでも動くけどalpineにすると最低限の構成になるので、サイズがとても軽くなるんよ
FROM golang:alpine

# コンテナ上のWorking Directoryはここなんよ
WORKDIR /go/src/golang_webapp_sample/

# ローカル上の./配下を/go/src/golang_webapp_sample/にコピーするんよ
COPY ./ /go/src/golang_webapp_sample/

# ポートを開けるんよ
EXPOSE 8080

# golang_webapp_sampleを go run する
CMD ["go", "run", "./src/main/golang_webapp_sample.go"]
```

### 起動 
* `docker build . -t golang_webapp_sample`
    * `docker build .`で今いるDir配下をターゲットにしてDocker imageを作る
    * `-t golang_webapp_sample` でimageに名前をつける
    
```logs.txt
~/g/s/golang_webapp_sample ❯❯❯ docker build . -t golang_webapp_sample
Sending build context to Docker daemon  46.08kB
Step 1/5 : FROM golang:alpine
alpine: Pulling from library/golang
8e3ba11ec2a2: Pull complete
8e6b2bc60854: Pull complete
3d20cafe6dc8: Pull complete
a7b6bf1e1322: Pull complete
b95ef83a75ea: Pull complete
Digest: sha256:499b775c0954ce029c9db806c4543524b38eeb38bc5588c3ea81bb135f8c55db
Status: Downloaded newer image for golang:alpine
 ---> cace225819dc
Step 2/5 : WORKDIR /go/src/golang_webapp_sample/
 ---> Running in 1ef6b908dfc6
Removing intermediate container 1ef6b908dfc6
 ---> aefcc386d4c5
Step 3/5 : COPY ./ /go/src/golang_webapp_sample/
 ---> cd78360b7275
Step 4/5 : EXPOSE 8080
 ---> Running in ba1f97d334cf
Removing intermediate container ba1f97d334cf
 ---> 2bb6de51170a
Step 5/5 : CMD ["go", "run", "./src/main/golang_webapp_sample.go"]
 ---> Running in 9750576946e9
Removing intermediate container 9750576946e9
 ---> aacb0b6f6822
Successfully built aacb0b6f6822
~/g/s/golang_webapp_sample ❯❯❯ docker images
REPOSITORY             TAG                 IMAGE ID            CREATED              SIZE
golang_webapp_sample   latest              aacb0b6f6822        About a minute ago   260MB
golang                 alpine              cace225819dc        3 days ago           259MB
```

* `docker run -p 8080:8080 -td golang_webapp_sample`
    * `docker run golang_webapp_sample` で`golang_webapp_sample`を起動
    * `-p 8080:8080` でポート8080を指定開放
    * `-td` で擬似ターミナル割り当て＋バックグラウンド起動

```logs.txt
~/g/s/golang_webapp_sample ❯❯❯ docker run -p 8080:8080 -td golang_webapp_sample
97336c527d27f57e11f672736d75d34dbf024dcd48819fd6c382b9f1061d1878
~/g/s/golang_webapp_sample ❯❯❯ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
97336c527d27        golang_webapp_sample   "go run ./src/main/g…"   37 seconds ago      Up 37 seconds       0.0.0.0:8080->8080/tcp   nervous_hoover
```
### 確認
1. http://localhost:8080/ にアクセス
1. 画面に Hello, World! と表示されたら勝ち  
 ![result.png](https://qiita-image-store.s3.amazonaws.com/0/162984/db69e248-4015-c51c-6867-a47c88ad5ea7.png)  
勝った。

## ハマったこと
### Dockerでコンテナ起動するまでの流れを理解する
* ものすごく大雑把なことを書くと、こういう感じ
    1. **`Docker image`は超最低限の構成のlinuxをOSにして、その上に各アプリケーションをコンテナとして起動出来る状態で固めた状態のもの**
    2. **`Dockerfile`はDocker imageを作るための設計図**
    3. **`docker build`で出来上がった`Docker image`を`docker run`でコンテナとして起動する**
* Docker imageとDockerコンテナの違いはこちらがわかりやすいかと思います<br>
  [Dockerイメージの理解とコンテナのライフサイクル](https://www.slideshare.net/zembutsu/docker-images-containers-and-lifecycle)
* Dockerの概念をしっかり抑えるのなら、今月こういう記事が流行ってたので、理解して読むこと<br>
  [いまさらDockerに入門したので分かりやすくまとめます](https://qiita.com/gold-kou/items/44860fbda1a34a001fc1)
* 今回出て来ないけど、docker-composeはひとつのシステムに関連する各コンテナを一斉に起動して、コンテナ間を繋ぐためのもの。

### Dockerコンテナ上の構成をちゃんとする
```Dockerfile
WORKDIR /go/src/golang_webapp_sample/
COPY ./ /go/src/golang_webapp_sample/
CMD ["go", "run", "./src/main/golang_webapp_sample.go"]
```
* **WORKDIRは `/go/src/golang_webapp_sample/` なんよと設定し、<br>**
  **ローカルの`./`の内容をWORKDIR配下コピーするんよと明言し、<br>**
  **WORKDIR配下にコピーされた`./src/main/golang_webapp_sample.go` を `go run`するんよという流れを把握しておくこと。**
* このあたりの設定をちゃんと理解しておかないとハマる。モロメチャにハマった。
* 最初てきとうに設定していたが、コンテナ内linuxに設定されている$GOPATHとの兼ね合いで起動出来ず、だいぶわけがわからないことになった。