DockerでGo言語のREST APIの構築

# 環境
- macOS Monterey 12.6.0

# Docker Desktopをインストール
- [Docker.dmgをダウンロード](https://docs.docker.com/desktop/install/mac-install/)
- Docker .dmgをダブルクリックし、Docker iconをApplicationフォルダへ移動
- ApplicationフォルダーでDocker iconをダブルクリックし、Dockerを起動
![スクリーンショット 2022-12-21 13.29.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987895/c73f52b5-f670-9fd7-87e2-6b7724f3b24b.png)

# ターミナルを開き、REST API用のプロジェクトを作成
- 普段プロジェクトのフォルダーへ移動し、新たなフォルダーを作成（自分の場合、Projectsフォルダーへ移動、RESTAPITESTのフォルダーを作成）

~~~linux
  ~  cd Projects

 ~/Projects  mkdir RESTAPITEST

 ~/Projects  cd RESTAPITEST

 ~/Projects/RESTAPITEST
~~~


# golang Imageを取得する
###### Dockerfileを作成
~~~linux
~/Projects/RESTAPITEST  touch Dockerfile
 ~/Projects/RESTAPITEST  vi  Dockerfile
~~~
###### 下記内容をDockerfileへ追加
- latest--最新バージョンを指定
- 作成したImageはLinux環境で、Linuxの`/usr/src`したに`app`というフォルダーを作成
~~~linux
From golang:latest

WORKDIR /usr/src/app
~~~

###### コンフィグファイルdocker-compose.ymlを作成
~~~linux
~/Projects/RESTAPITEST  touch docker-compose.yml
 ~/Projects/RESTAPITEST  vi  docker-compose.yml
~~~
###### 下記内容をdocker-compose.ymlへ追加
- build--Dockerfileなどのコンフィグファイルのパースを指定
- ports--Webサバーのポート番号を指定
- volumes--作成したデータなどの保存先を指定
~~~linux
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3003:3003"
    volumes:
      - .:/usr/src/app
~~~

###### コンテナを立ち上げる
- go imageを取得
- コンテナを立ち上げる
~~~linux
~/Projects/RESTAPITEST  docker compose up                                                ok  32s  15:12:56
[+] Building 3.2s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                    0.0s
 => => transferring dockerfile: 78B                                                                     0.0s
 => [internal] load .dockerignore                                                                       0.0s
 => => transferring context: 2B                                                                         0.0s
 => [internal] load metadata for docker.io/library/golang:latest                                        3.1s
 => [1/2] FROM docker.io/library/golang:latest@sha256:54184d6d892f9d79dd332a6794bb11085c3f8b31f8be8e09  0.0s
 => CACHED [2/2] WORKDIR /usr/src/app                                                                   0.0s
 => exporting to image                                                                                  0.0s
 => => exporting layers                                                                                 0.0s
 => => writing image sha256:1c2a7cf5404773b5da9baf4e02dfd05664c62a350ddf3517dec970ad4486becf            0.0s
 => => naming to docker.io/library/restapitest-web                                                      0.0s
[+] Running 2/1
 ⠿ Network restapitest_default  Created                                                                 0.0s
 ⠿ Container restapitest-web-1  Created                                                                 0.1s
Attaching to restapitest-web-1
restapitest-web-1 exited with code 0

 ~/Projects/RESTAPITEST
~~~

###### コンテナに入って、ファイルをチェックし、goバージョンを確認する
~~~linux
 ~/Projects/RESTAPITEST  docker compose run --service-ports web bash                      126 err  15:17:55
root@44adff578407:/usr/src/app#
root@44adff578407:/usr/src/app# ls -al
total 12
drwxr-xr-x 4 root root  128 Dec 21 06:12 .
drwxr-xr-x 1 root root 4096 Dec 16 01:53 ..
-rw-r--r-- 1 root root   41 Dec 21 05:47 Dockerfile
-rw-r--r-- 1 root root  113 Dec 21 06:12 docker-compose.yml
root@44adff578407:/usr/src/app# go version
go version go1.19.4 linux/arm64
root@44adff578407:/usr/src/app#
~~~

###### Docker DesktopでもImagesとContainersが表示されます
- Images
![スクリーンショット 2022-12-21 15.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987895/a99264f8-626f-8bae-cc7e-4ad710c1b6d2.png)

- Container
![スクリーンショット 2022-12-21 15.25.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987895/bf7c6ca3-26d1-7794-fa94-82bfb07a2679.png)

# Go Fiberフレームワークをインストール
###### 自分のGitHubと紐つける
~~~linux
root@44adff578407:/usr/src/app# go mod init github.com/yourgithubspace/yourgithubrep
go: creating new go.mod: module github.com/yourgithubspace/yourgithubrep
root@44adff578407:/usr/src/app#
~~~

###### Fiberフレームワークをインストール
~~~linux
root@44adff578407:/usr/src/app# go get github.com/gofiber/fiber/v2
go: downloading github.com/gofiber/fiber v1.14.6
go: downloading github.com/gofiber/fiber/v2 v2.40.1
go: downloading github.com/mattn/go-colorable v0.1.13
go: downloading github.com/mattn/go-isatty v0.0.16
go: downloading github.com/mattn/go-runewidth v0.0.14
go: downloading github.com/valyala/bytebufferpool v1.0.0
go: downloading github.com/valyala/fasthttp v1.41.0
go: downloading github.com/rivo/uniseg v0.2.0
go: downloading golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
go: downloading github.com/klauspost/compress v1.15.9
go: downloading github.com/andybalholm/brotli v1.0.4
go: downloading github.com/valyala/tcplisten v1.0.0
go: added github.com/andybalholm/brotli v1.0.4
go: added github.com/gofiber/fiber/v2 v2.40.1
go: added github.com/klauspost/compress v1.15.9
go: added github.com/mattn/go-colorable v0.1.13
go: added github.com/mattn/go-isatty v0.0.16
go: added github.com/mattn/go-runewidth v0.0.14
go: added github.com/rivo/uniseg v0.2.0
go: added github.com/valyala/bytebufferpool v1.0.0
go: added github.com/valyala/fasthttp v1.41.0
go: added github.com/valyala/tcplisten v1.0.0
go: added golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
root@44adff578407:/usr/src/app#
~~~

###### Go　Fiberの`Quickstart`で試す

- cmd/main.goを作成
~~~linux
root@44adff578407:/usr/src/app# mkdir cmd
root@44adff578407:/usr/src/app# touch cmd/main.go
root@44adff578407:/usr/src/app# vi cmd/main.go
~~~

- [下記のサンプルコードをmain.goに追加](https://github.com/gofiber/fiber#%EF%B8%8F-quickstart)
~~~linux
package main

import "github.com/gofiber/fiber/v2"

func main() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World 👋!")
    })

    app.Listen(":3000")
}
~~~

- Webサーバーを起動する
~~~linux
root@44adff578407:/usr/src/app# go run cmd/main.go -b 0.0.0.0

 ┌───────────────────────────────────────────────────┐
 │                   Fiber v2.40.1                   │
 │               http://127.0.0.1:3003               │
 │       (bound on host 0.0.0.0 and port 3003)       │
 │                                                   │
 │ Handlers ............. 2  Processes ........... 1 │
 │ Prefork ....... Disabled  PID ............... 333 │
 └───────────────────────────────────────────────────┘

~~~
- Safariでhttp://localhost:3003/を開くと、下図のように表示される　　
![スクリーンショット 2022-12-21 16.52.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987895/77c759d7-757f-a99e-3108-71b8db81ea17.png)

###### コンテナ内のワークスペースの指定&[goモジュールの関連パッケージの自動チェック](https://go.dev/ref/mod#go-mod-tidy)をDockerfileへ追加

-  Dockerfileは下記のようになる
~~~linux
From golang:latest

WORKDIR /usr/src/app

RUN go install github.com/cosmtrek/air@latest

COPY . .
RUN go mod tidy
~~~

###### アプリサーバの起動をdocker-compose.ymlへ追加

- docker-compose.ymlは下記のようになる
~~~linux
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3003:3003"
    volumes:
      - .:/usr/src/app
    command: go run cmd/main.go -b 0.0.0.0
~~~

###### ターミナルで、下記のコマンドを実行して、appが立ち上げる
- もしコンテナが起動中の場合、先にコンテナを停止する
~~~linux
root@44adff578407:/usr/src/app# exit
exit

 ~/Projects/RESTAPITEST
~~~

- アプリを起動する
~~~linux
 ~/Projects/RESTAPITEST  docker compose up                                                     ok  17:29:30
[+] Running 1/0
 ⠿ Container restapitest-web-1  Recreated                                                               0.1s
Attaching to restapitest-web-1
restapitest-web-1  | go: downloading github.com/gofiber/fiber/v2 v2.40.1
restapitest-web-1  | go: downloading github.com/mattn/go-colorable v0.1.13
restapitest-web-1  | go: downloading github.com/mattn/go-isatty v0.0.16
restapitest-web-1  | go: downloading github.com/mattn/go-runewidth v0.0.14
restapitest-web-1  | go: downloading github.com/valyala/bytebufferpool v1.0.0
restapitest-web-1  | go: downloading github.com/valyala/fasthttp v1.41.0
restapitest-web-1  | go: downloading golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab
restapitest-web-1  | go: downloading github.com/rivo/uniseg v0.2.0
restapitest-web-1  | go: downloading github.com/andybalholm/brotli v1.0.4
restapitest-web-1  | go: downloading github.com/klauspost/compress v1.15.9
restapitest-web-1  | go: downloading github.com/valyala/tcplisten v1.0.0
restapitest-web-1  |
restapitest-web-1  |  ┌───────────────────────────────────────────────────┐
restapitest-web-1  |  │                   Fiber v2.40.1                   │
restapitest-web-1  |  │               http://127.0.0.1:3003               │
restapitest-web-1  |  │       (bound on host 0.0.0.0 and port 3003)       │
restapitest-web-1  |  │                                                   │
restapitest-web-1  |  │ Handlers ............. 2  Processes ........... 1 │
restapitest-web-1  |  │ Prefork ....... Disabled  PID ............... 228 │
restapitest-web-1  |  └───────────────────────────────────────────────────┘
restapitest-web-1  |

~~~

#### <font color = 'red'>Next Step</font>
- DBサーバーの追加

## FYI
明日は、@takurUNさんが、APIゲートウェイ Kongを使って開発してる話　というタイトルで発表します！ぜひ、お楽しみください〜