続きます
6. mattn/go-oci8 ⇒ sijms/go-ora への変更
結局mattn/go-oci8
がOracle提供のOracle Instant Clientに依存していることがすべの原因なので、mattn/go-oci8
からOracle Instant Clientに依存していないGoのみで実装したsijms/go-ora
に変更することにします。
書き直したコードは下記となります。
package main
import (
"database/sql"
"log"
_ "github.com/sijms/go-ora/v2"
)
var (
VERSION = "default"
REVISION = "dev"
)
func main() {
log.Printf("Version:%s, Revision:%s", VERSION, REVISION)
conn, err := sql.Open("oracle", "oracle://gouser:pwd@localhost:1521/GOPDB")
if err != nil {
log.Printf("Can't open the driver: %s", err)
return
}
defer func() {
err = conn.Close()
if err != nil {
log.Printf("Can't close connection: %s", err)
}
}()
rows, err := conn.Query("SELECT USER_ID, USER_NAME FROM SAMPLE_USER")
if err != nil {
log.Printf("Query error: %s", err)
return
}
defer func() {
err = rows.Close()
if err != nil {
log.Printf("Can't close dataset: %s", err)
}
}()
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
log.Printf("ID : %d, Name : %s", id, name)
}
log.Printf("Finished.")
}
ローカルでの実行も問題なく動きました。
2022/10/05 21:50:37 Version:default, Revision:dev
2022/10/05 21:50:37 ID : 1, Name : testuser01
2022/10/05 21:50:37 ID : 2, Name : testuser02
2022/10/05 21:50:37 ID : 3, Name : testuser03
2022/10/05 21:50:37 Finished.
ひとまずこのコードをクロスコンパイル&マルチステージビルドしてみます。
7. マルチステージビルド再び
前回の DBの接続文字列をlocalhost
からoracke19c
に変更してマルチステージビルドを試します。
マルチステージビルド用のDockerfileは下記です。
OCIのインストールがなくなったのでかなりスッキリしました。
# ===================== #
# Builder
# ===================== #
FROM golang:1.18.5 as builder
WORKDIR /workspace
COPY ./ ./
RUN set -x && \
echo "==== go build ====" && \
go mod download && \
CGO_ENABLED=0 GOOS=linux go build -x -o goapp && \
ls -la
# ===================== #
# Production
# ===================== #
FROM scratch as prod
ENV ROOT_PATH=/go/app
WORKDIR ${ROOT_PATH}
COPY --from=builder /workspace/goapp ${ROOT_PATH}
CMD ["/go/app/goapp"]
無事ビルドも成功しました。
イメージのサイズも10.2MBととても小さくなっています。
$ docker build -t sample-go .
… ビルドログ省略
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
go-sample latest 5271d522481f 18 seconds ago 10.2MB
golang 1.18.5 06c366130191 1 weeks ago 965MB
oracle/database 19.3.0-ee b29bba5ef6ba 1 weeks ago 6.53GB
前回の通りネットワーク設定を追加してrun
コマンドを実行します。
$ docker run --name go-sample --net desktop_default go-sample:latest
2022/10/05 12:49:53 Version:default, Revision:dev
2022/10/05 12:49:53 ID : 1, Name : testuser01
2022/10/05 12:49:53 ID : 2, Name : testuser02
2022/10/05 12:49:53 ID : 3, Name : testuser03
2022/10/05 12:49:53 Finished.
成功!!!!!!!!!!!!!!!!!!!!!!
結論
OracleにCRUD操作を発行するだけのコードで軽量コンテナで動かすことを前提とした場合はmattn/go-oci8
ではなくsijms/go-ora
などのGoだけで実装したライブラリの利用を推奨します。
一方、Oracleの機能をフルで使いたい場合はmattn/go-oci8
を推奨しますが、Oracle Clientの静的ライブラリを生成してからの静的リンクでのビルドなど頑張ってください。