Open23
go-zeroを学ぶ3
Docker サブコマンド
Dockerfile を作成するためのコマンドとのこと。
goctl docker --help
Generate Dockerfile
Usage:
goctl docker [flags]
Flags:
--base string The base image to build the docker image, default scratch (default "scratch")
--branch string The branch of the remote repo, it does work with --remote
--exe string The executable name in the built image
--go string The file that contains main function
-h, --help help for docker
--home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
--port int The port to expose, default none
--remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
--tz string The timezone of the container (default "Asia/Shanghai")
--version string The goctl builder golang image version
Dockerfile 生成
ユーザー管理モジュールと注文管理モジュールの Dockerfile
を作成する
ユーザー管理モジュール
mkdir deployments/docker/user
cd deployments/docker/user
goctl docker -go ../../../mall/user/rpc/user.go -tz Asia/Tokyo -port 8080
cd ../../../
deployments/docker/user/Dockerfile
FROM golang:alpine AS builder
LABEL stage=gobuilder
ENV CGO_ENABLED 0
RUN apk update --no-cache && apk add --no-cache tzdata
WORKDIR /build
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/user mall/user/rpc/user.go
FROM scratch
COPY /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY /usr/share/zoneinfo/Asia/Tokyo /usr/share/zoneinfo/Asia/Tokyo
ENV TZ Asia/Tokyo
WORKDIR /app
COPY /app/user /app/user
EXPOSE 8080
CMD ["./user"]
注文管理モジュール
mkdir deployments/docker/order
cd deployments/docker/order
goctl docker -go ../../../mall/user/api/order.go -tz Asia/Tokyo -port 8888
cd ../../../
deployments/docker/order/Dockerfile
FROM golang:alpine AS builder
LABEL stage=gobuilder
ENV CGO_ENABLED 0
RUN apk update --no-cache && apk add --no-cache tzdata
WORKDIR /build
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/order mall/order/api/order.go
FROM scratch
COPY /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY /usr/share/zoneinfo/Asia/Tokyo /usr/share/zoneinfo/Asia/Tokyo
ENV TZ Asia/Tokyo
WORKDIR /app
COPY /app/order /app/order
EXPOSE 8888
CMD ["./order"]
docker-compose.yaml の変更
作成した Dockerfile を docker-compose.yaml
に追加する
docker-compose.yaml
@@ -7,6 +7,18 @@ networks:
driver: bridge
services:
+ user:
+ build:
+ context: .
+ dockerfile: deployments/docker/user/Dockerfile
+ ports:
+ - 8080:8080
+ order:
+ build:
+ context: .
+ dockerfile: deployments/docker/order/Dockerfile
+ ports:
+ - 8888:8888
etcd:
image: bitnami/etcd:3.5
environment:
イメージビルド
docker compose build
サーバー起動
docker compose up -d
動作確認
curl -i -X GET http://localhost:8888/api/order/get/1
curl: (7) Failed to connect to localhost port 8888 after 4 ms: Couldn't connect to server
make: *** [test-get-order] Error 7
サーバーが起動できていないようだ。。。
ログを確認
docker compose logs user
docker-compose-user-1 | 2023/06/04 00:18:13 error: config file etc/user.yaml, open etc/user.yaml: no such file or directory
docker compose logs order
docker-compose-order-1 | 2023/06/04 00:18:13 error: config file etc/order.yaml, open etc/order.yaml: no such file or directory
設定ファイルが読み込めていなかった
Dockerfile修正
設定ファイルをコピーする処理を追加する
deployments/docker/user/Dockerfile
@@ -13,6 +13,7 @@ ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/user mall/user/rpc/user.go
+RUN cp ./mall/user/rpc/etc/user.yaml /app/user.yaml
FROM scratch
@@ -23,7 +24,8 @@ ENV TZ Asia/Tokyo
WORKDIR /app
COPY /app/user /app/user
+COPY /app/user.yaml /app/user.yaml
EXPOSE 8080
-CMD ["./user"]
+CMD ["./user", "-f", "user.yaml"]
deployments/docker/order/Dockerfile
@@ -13,6 +13,7 @@ ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/order mall/order/api/order.go
+RUN cp ./mall/order/api/etc/order.yaml /app/order.yaml
FROM scratch
@@ -23,7 +24,8 @@ ENV TZ Asia/Tokyo
WORKDIR /app
COPY /app/order /app/order
+COPY /app/order.yaml /app/order.yaml
EXPOSE 8888
-CMD ["./order"]
+CMD ["./order", "-f", "order.yaml"]
再起動
設定ファイルを読み込みできるように変更したので、改めて動作確認
docker compose up -d
起動確認
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
docker-compose-db-1 mysql:8.0 "docker-entrypoint.s…" db 31 seconds ago Up 30 seconds 33060/tcp, 0.0.0.0:13306->3306/tcp
docker-compose-etcd-1 bitnami/etcd:3.5 "/opt/bitnami/script…" etcd 31 seconds ago Up 30 seconds 0.0.0.0:12379->2379/tcp, 0.0.0.0:12380->2380/tcp
docker-compose-redis-1 redis:7.0 "docker-entrypoint.s…" redis 31 seconds ago Up 30 seconds 0.0.0.0:16379->6379/tcp
起動失敗。。。
再調査
ユーザー管理と注文管理が動作していないので再調査
docker compose logs user
docker-compose-user-1 | Starting rpc server at 0.0.0.0:8080...
docker-compose-user-1 | {"level":"warn","ts":"2023-06-04T01:57:43.927538+0900","logger":"etcd-client","caller":"v3@v3.5.8/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0x40005f6000/127.0.0.1:12379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing: dial tcp 127.0.0.1:12379: connect: connection refused\""}
docker-compose-user-1 | {"@timestamp":"2023-06-04T01:57:43.927+09:00","caller":"zrpc/server.go:92","content":"context deadline exceeded","level":"error"}
docker-compose-user-1 | panic: context deadline exceeded
docker-compose-user-1 |
docker-compose-user-1 | goroutine 1 [running]:
docker-compose-user-1 | github.com/zeromicro/go-zero/zrpc.(*RpcServer).Start(0x1c84d58?)
docker-compose-user-1 | /go/pkg/mod/github.com/zeromicro/go-zero@v1.5.2/zrpc/server.go:93 +0x80
docker-compose-user-1 | main.main()
docker-compose-user-1 | /build/mall/user/rpc/user.go:38 +0x1dc
docker compose logs order
docker-compose-order-1 | {"level":"warn","ts":"2023-06-04T01:57:43.740235+0900","logger":"etcd-client","caller":"v3@v3.5.8/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0x400023c1c0/127.0.0.1:12379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing: dial tcp 127.0.0.1:12379: connect: connection refused\""}
docker-compose-order-1 | 2023/06/04 01:57:43 rpc dial: etcd://127.0.0.1:12379/user.rpc, error: context deadline exceeded, make sure rpc service "user.rpc" is already started
docker compose
内でサーバー間の通信ができないんだった
再修正
サーバー間で接続できるようにプログラムの設定ファイルを変更する
mall/order/api/etc/order.yaml
@@ -4,5 +4,5 @@ Port: 8888
UserRpc:
Etcd:
Hosts:
- - 127.0.0.1:12379
+ - etcd:2379
Key: user.rpc
mall/user/rpc/etc/user.yaml
index 1218100..6f6a300 100644
--- a/mall/user/rpc/etc/user.yaml
+++ b/mall/user/rpc/etc/user.yaml
@@ -2,10 +2,10 @@ Name: user.rpc
ListenOn: 0.0.0.0:8080
Etcd:
Hosts:
- - 127.0.0.1:12379
+ - etcd:2379
Key: user.rpc
-DataSource: root:password@tcp(127.0.0.1:13306)/mall?parseTime=true
+DataSource: root:password@tcp(db:3306)/mall?parseTime=true
Table: user
Cache:
- - Host: 127.0.0.1:16379
+ - Host: redis:6379
docker compose
で、bridge ネットワーク使うとDNS引けなくなるので、docker-compose.yaml
も修正
deployments/docker-compose/docker-compose.yaml
@@ -1,11 +1,5 @@
version: '3'
-networks:
- etcd-network:
- driver: bridge
- db-network:
- driver: bridge
-
services:
user:
build:
@@ -27,8 +21,6 @@ services:
ports:
- "12379:2379"
- "12380:2380"
- networks:
- - etcd-network
db:
image: mysql:8.0
@@ -43,8 +35,6 @@ services:
restart: always
ports:
- "13306:3306"
- networks:
- - db-network
redis:
image: redis:7.0
再々起動
docker compose up -d
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
docker-compose-db-1 mysql:8.0 "docker-entrypoint.s…" db 4 minutes ago Up 4 minutes 33060/tcp, 0.0.0.0:13306->3306/tcp
docker-compose-etcd-1 bitnami/etcd:3.5 "/opt/bitnami/script…" etcd 4 minutes ago Up 4 minutes 0.0.0.0:12379->2379/tcp, 0.0.0.0:12380->2380/tcp
docker-compose-order-1 docker-compose-order "./order -f order.ya…" order 4 minutes ago Up 4 minutes 0.0.0.0:8888->8888/tcp
docker-compose-redis-1 redis:7.0 "docker-entrypoint.s…" redis 4 minutes ago Up 4 minutes 0.0.0.0:16379->6379/tcp
docker-compose-user-1 docker-compose-user "./user -f user.yaml" user 4 minutes ago Up 4 minutes 0.0.0.0:8080->8080/tcp
動作確認
接続成功
curl -i -X GET http://localhost:8888/api/order/get/1
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Traceparent: 00-f1e4a4cd0811641b4c48c0fb170cafc4-f07db5d7da0dfd15-00
Date: Sat, 03 Jun 2023 17:15:45 GMT
Content-Length: 30
{"id":"1","name":"test order"}%
接続できるようになったけど、動作確認するために都度コンパイルが必要なのは手間だな
環境変数とか使って、docker compose からでもローカル環境からでも接続できるように修正する
環境変数対応
go-zero の設定ファイルに環境変数が使えることがわかったので、環境変数から接続情報を注入できるように書き換える
該当箇所は、ここ
deployments/docker-compose/docker-compose.yaml
@@ -1,34 +1,48 @@
version: '3'
-networks:
- etcd-network:
- driver: bridge
- db-network:
- driver: bridge
-
services:
user:
build:
context: ../../
dockerfile: deployments/docker/user/Dockerfile
+ environment:
+ - CACHE_HOST=redis
+ - CACHE_PORT=6379
+ - DATABASE_NAME=${DATABASE_NAME:-mall}
+ - DATABASE_USER=${DATABASE_USER:-user}
+ - DATABASE_PASS=${DATABASE_PASS:-password}
+ - DATABASE_HOST=db
+ - DATABASE_PORT=3306
+ - ETCD_HOST=etcd
+ - ETCD_PORT=2379
ports:
- 8080:8080
+ depends_on:
+ - etcd
+ - db
+ - redis
+
order:
build:
context: ../../
dockerfile: deployments/docker/order/Dockerfile
+ environment:
+ - ETCD_HOST=etcd
+ - ETCD_PORT=2379
ports:
- 8888:8888
+ depends_on:
+ - etcd
+ - user
+
etcd:
image: bitnami/etcd:3.5
environment:
- ALLOW_NONE_AUTHENTICATION=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://0.0.0.0:2379
ports:
- - "12379:2379"
- - "12380:2380"
- networks:
- - etcd-network
+ - ${ETCD_PORT_1:-12379}:2379
+ - ${ETCD_PORT_2:-12380}:2380
db:
image: mysql:8.0
@@ -36,21 +50,19 @@ services:
- ../docker/mysql/data:/var/lib/mysql
- ../docker/mysql/conf.d:/etc/mysql/conf.d
environment:
- MYSQL_DATABASE: mall
- MYSQL_ROOT_PASSWORD: password
- MYSQL_USER: user
- MYSQL_PASSWOR: password
+ MYSQL_DATABASE: ${DATABASE_NAME:-mall}
+ MYSQL_USER: ${DATABASE_USER:-user}
+ MYSQL_PASSWORD: ${DATABASE_PASS:-password}
+ MYSQL_ROOT_PASSWORD: ${DATABASE_PASS:-password}
restart: always
ports:
- - "13306:3306"
- networks:
- - db-network
+ - ${DATABASE_PORT:-13306}:3306
redis:
image: redis:7.0
volumes:
- ../docker/redis/data:/data
ports:
- - "16379:6379"
+ - ${REDIS_PORT:-16379}:6379
mall/order/api/etc/order.yaml
@@ -4,5 +4,5 @@ Port: 8888
UserRpc:
Etcd:
Hosts:
- - 127.0.0.1:12379
+ - $ETCD_HOST:$ETCD_PORT
Key: user.rpc
mall/order/api/order.go
@@ -18,7 +18,7 @@ func main() {
flag.Parse()
var c config.Config
- conf.MustLoad(*configFile, &c)
+ conf.MustLoad(*configFile, &c, conf.UseEnv())
server := rest.MustNewServer(c.RestConf)
defer server.Stop()
mall/user/rpc/etc/user.yaml
@@ -2,10 +2,10 @@ Name: user.rpc
ListenOn: 0.0.0.0:8080
Etcd:
Hosts:
- - 127.0.0.1:12379
+ - $ETCD_HOST:$ETCD_PORT
Key: user.rpc
-DataSource: root:password@tcp(127.0.0.1:13306)/mall?parseTime=true
+DataSource: $DATABASE_USER:$DATABASE_PASS@tcp($DATABASE_HOST:$DATABASE_PORT)/$DATABASE_NAME?parseTime=true
Table: user
Cache:
- - Host: 127.0.0.1:16379
+ - Host: $CACHE_HOST:$CACHE_PORT
mall/user/rpc/user.go
@@ -22,7 +22,7 @@ func main() {
flag.Parse()
var c config.Config
- conf.MustLoad(*configFile, &c)
+ conf.MustLoad(*configFile, &c, conf.UseEnv())
ctx := svc.NewServiceContext(c)
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
また明日変更加えよう
conf.UseEnv()
のこと書いてなかった
conf.UseEnv() とは
conf.MustLoad
メソッド実行時にオプションに指定することで、読み込む設定ファイル内で環境変数が使えるようになる。
環境ファイルの置き換えには、os.ExpandEnvメソッド
を使っている。 ${var}
や $var
を展開する。