Ginを使ったAPIサーバーをnginx, mysql,そしてdockerで構築します。
ファイルをただ並べていくだけの記事です。
やっていること
mysql, nginx, goの最低限のファイルをメモがわりに並べています。
(DBへの接続、マイグレーションなどはここでは割愛してます)
全体像
全体像としては以下のようになっています。
├── backend
│ ├── Dockerfile
│ ├── Dockerfile.local
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
├── docker-compose.yml
├── mysql
│ ├── Dockerfile
│ └── my.cnf
└── nginx
├── Dockerfile
└── nginx.conf
docker-compose
go, mysql, nginxの3つのサーバーを立てます。nginxは80にアクセスがくると、8080のほうに流すように設定していきます。
version: '3'
services:
go:
build:
context: ./backend
dockerfile: Dockerfile.local
volumes:
- ./backend:/go/src/backend
working_dir: /go/src/backend
environment:
TZ: Asia/Tokyo
ports:
- 8080:8080
- 2345:2345
security_opt:
- apparmor:unconfined
cap_add:
- SYS_PTRACE
mysql:
build: ./mysql
environment:
TZ: Asia/Tokyo
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: backend
ports:
- 13306:3306
volumes:
- mysql_volume:/var/lib/mysql
nginx:
container_name: "nginx"
build: ./nginx
ports:
- "80:80"
depends_on:
- "go"
volumes:
mysql_volume:
go
delveでデバッグできるようにしたいので、ローカル用のDockerfileを作成しています。
.air.tomlはGithubのページからコピペできます。
FROM golang:1.15.2
COPY . /go/src/sample
WORKDIR /go/src/sample
RUN go get -u github.com/cosmtrek/air
RUN go get -u github.com/go-delve/delve/cmd/dlv
CMD ["air", "-c", ".air.toml"]**
Herokuにデプロイするときのことも考えて USE_HEROKU
という環境変数が入っています。ですがこれはなくてもデフォルトで8080を選ぶようになっているので設定する必要はありません。今のところAPIのパスは何も用意していないのですが、、、
package main
import (
"os"
"github.com/joho/godotenv"
"github.com/zeroboard-dev/zeroboard-toC/backend/lib"
"github.com/zeroboard-dev/zeroboard-toC/backend/router"
)
func main() {
if os.Getenv("USE_HEROKU") != "1" {
err := godotenv.Load()
if err != nil {
panic(err)
}
}
r := gin.Default()
if os.Getenv("USE_HEROKU") != "1" {
// local
r.Run(os.Getenv("HTTP_HOST") + ":" + os.Getenv("HTTP_PORT")) // listen and serve on 0.0.0.0:8080
} else {
// heroku
deployPort := os.Getenv("PORT")
if deployPort == "" {
deployPort = "8080"
}
r.Run(":" + deployPort)
}
}
mysql
mysqlはいつも通りという感じです。
FROM mysql:8.0.21
# FROM mysql@sha256:77b7e09c906615c1bb59b2e9d7703f728b1186a5a70e547ce2f1079ef4c1c5ca
RUN echo "USE mysql;" > /docker-entrypoint-initdb.d/timezones.sql && mysql_tzinfo_to_sql /usr/share/zoneinfo >> /docker-entrypoint-initdb.d/timezones.sql
COPY ./my.cnf /etc/mysql/conf.d/my.cnf
# MySQLサーバーへの設定
[mysqld]
# 文字コード/照合順序の設定
character_set_server=utf8mb4
collation_server=utf8mb4_bin
# タイムゾーンの設定
default_time_zone=SYSTEM
log_timestamps=SYSTEM
# デフォルト認証プラグインの設定
default_authentication_plugin=mysql_native_password
# mysqlオプションの設定
[mysql]
# 文字コードの設定
default_character_set=utf8mb4
# mysqlクライアントツールの設定
[client]
# 文字コードの設定
default_character_set=utf8mb4
nginx
Dockerfileは以下です。もっと新しくしたほうがいいのでしょうか、、
FROM nginx:1.17.4-alpine
ADD ./nginx.conf /etc/nginx/conf.d/default.conf
こちら http://go:8080
としているのは、docker-composeにてserviceの名前がgoとなっているからです。サービスの名前(コンテナの名前)にする必要があります。
server {
listen 80 default_server;
listen [::]:80 default_server;
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://go:8080;
}
}
アクセスしたときの挙動
ページを何も用意していないので404が帰ってきていますが、nginxがちゃんと仕事をしているのはわかります。
go_1 | [GIN] 2021/06/28 - 01:42:25 | 404 | 22.6µs | 172.28.0.4 | GET "/"
nginx | 172.28.0.1 - - [27/Jun/2021:16:42:25 +0000] "GET / HTTP/1.1" 404 18 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36" "-"
go_1 | [GIN] 2021/06/28 - 01:42:25 | 404 | 15.5µs | 172.28.0.4 | GET "/favicon.ico"
nginx | 172.28.0.1 - - [27/Jun/2021:16:42:25 +0000] "GET /favicon.ico HTTP/1.1" 404 18 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36" "-"
nginx | 172.28.0.1 - - [27/Jun/2021:16:47:26 +0000] " " 400 157 "-" "-" "-"
nginx | 172.28.0.1 - - [27/Jun/2021:16:53:18 +0000] " " 400 157 "-" "-" "-"
nginx | 172.28.0.1 - - [27/Jun/2021:16:59:10 +0000] " " 400 157 "-" "-" "-"