Repository: zeromicro/go-zero
Pull request #3682 (2023-10-29 10:52:46)

feat: Improve Docker build
* Run binaries as unprivileged user to improve security
* Copy whole timezone database to allow setting TZ env variable
* `docker run kevinwan/goctl --help` instead of `docker run kevinwan/goctl goctl --help`
* Remove files from Docker build context not needed for the resulting image
* Let Dependabot update Docker images and GitHub Actions

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/zeromicro/go-zero/pull/3682?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) Report
> Merging [#3682](https://app.codecov.io/gh/zeromicro/go-zero/pull/3682?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) (ec3afa5) into [master](https://app.codecov.io/gh/zeromicro/go-zero/commit/6ecc5e7b73822697e923c7ceb603cd83a9fe3500?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) (6ecc5e7) will **decrease** coverage by `0.02%`.
> The diff coverage is `n/a`.


[see 1 file with indirect coverage changes](https://app.codecov.io/gh/zeromicro/go-zero/pull/3682/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro)

kevwan: It's in a docker image, not requiring the root privillege on the host. I don't think there are problems. Would you please explain more on this?
reneleonhardt: If it's not needed, why run as root with all it's special permissions and widen your attack surface intentionally? 😉
Maybe looking at Kubernetes makes it clearer, for example in my current project we are not allowed anymore to run root images on AWS, starting from static linters like hadolint and kube-linter to in-cluster linters like kyverno:
https://www.atatus.com/blog/rootless-containers-guide/
https://github.com/moby/buildkit/blob/master/examples/kubernetes/pod.rootless.yaml
https://github.com/hadolint/hadolint/issues/184
https://github.com/hadolint/hadolint/wiki/DL3002
https://github.com/stackrox/kube-linter
https://docs.kubelinter.io/#/generated/checks?id=run-as-non-root
https://kyverno.io/policies/pod-security/restricted/require-run-as-nonroot/require-run-as-nonroot/
https://kyverno.io/policies/other/rec-req/require-non-root-groups/require-non-root-groups/

Patch:
diff --git a/.dockerignore b/.dockerignore
index f3b64113..af9645a7 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,1 +1,7 @@
 **/.git
+.dockerignore
+Dockerfile
+goctl
+Makefile
+readme.md
+readme-cn.md
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index a687e57b..c9454581 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -5,6 +5,14 @@
 
 version: 2
 updates:
+  - package-ecosystem: "docker" # Update image tags in Dockerfile
+    directory: "/"
+    schedule:
+      interval: "weekly"
+  - package-ecosystem: "github-actions" # Update GitHub Actions
+    directory: "/"
+    schedule:
+      interval: "weekly"
   - package-ecosystem: "gomod" # See documentation for possible values
     directory: "/" # Location of package manifests
     schedule:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index f3a3d561..1e866055 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -17,7 +17,7 @@ jobs:
       - name: Set up Go 1.x
         uses: actions/setup-go@v4
         with:
-          go-version: 1.19
+          go-version: '1.19'
           check-latest: true
           cache: true
         id: go
@@ -53,7 +53,7 @@ jobs:
         uses: actions/setup-go@v4
         with:
           # use 1.19 to guarantee Go 1.19 compatibility
-          go-version: 1.19
+          go-version: '1.19'
           check-latest: true
           cache: true
 
diff --git a/readme-cn.md b/readme-cn.md
index 30c5c997..86c7aeac 100644
--- a/readme-cn.md
+++ b/readme-cn.md
@@ -120,12 +120,12 @@ GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/zeromicro
     # docker for amd64 architecture
     docker pull kevinwan/goctl
     # run goctl like
-    docker run --rm -it -v `pwd`:/app kevinwan/goctl goctl --help
+    docker run --rm -it -v `pwd`:/app kevinwan/goctl --help
     
     # docker for arm64(Mac) architecture
     docker pull kevinwan/goctl:latest-arm64
     # run goctl like
-    docker run --rm -it -v `pwd`:/app kevinwan/goctl:latest-arm64 goctl --help
+    docker run --rm -it -v `pwd`:/app kevinwan/goctl:latest-arm64 --help
     ```
     
     确保 goctl 可执行
diff --git a/readme.md b/readme.md
index f629149c..8498d835 100644
--- a/readme.md
+++ b/readme.md
@@ -127,12 +127,12 @@ go get -u github.com/zeromicro/go-zero
    # docker for amd64 architecture
    docker pull kevinwan/goctl
    # run goctl like
-   docker run --rm -it -v `pwd`:/app kevinwan/goctl goctl --help
+   docker run --rm -it -v `pwd`:/app kevinwan/goctl --help
    
    # docker for arm64(Mac) architecture
    docker pull kevinwan/goctl:latest-arm64
    # run goctl like
-   docker run --rm -it -v `pwd`:/app kevinwan/goctl:latest-arm64 goctl --help
+   docker run --rm -it -v `pwd`:/app kevinwan/goctl:latest-arm64 --help
    ```
    
    make sure goctl is executable.
diff --git a/tools/goctl/.dockerignore b/tools/goctl/.dockerignore
new file mode 100644
index 00000000..105c6dbd
--- /dev/null
+++ b/tools/goctl/.dockerignore
@@ -0,0 +1,8 @@
+test/
+.dockerignore
+.go-version
+Dockerfile
+goctl
+Makefile
+readme.md
+readme-cn.md
diff --git a/tools/goctl/Dockerfile b/tools/goctl/Dockerfile
index 44c43af2..10eb9e1d 100644
--- a/tools/goctl/Dockerfile
+++ b/tools/goctl/Dockerfile
@@ -8,13 +8,12 @@ ENV GOPROXY https://goproxy.cn,direct
 RUN apk update --no-cache && apk add --no-cache tzdata
 RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
 RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
+RUN addgroup -g 1000 -S app && adduser -u 1000 -S app -G app
 
 WORKDIR /build
 
-ADD go.mod .
-ADD go.sum .
-RUN go mod download
 COPY . .
+RUN go mod download
 RUN go build -ldflags="-s -w" -o /app/goctl ./goctl.go
 
 
@@ -22,13 +21,20 @@ FROM golang:alpine
 
 RUN apk update --no-cache && apk add --no-cache protoc
 
-COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
-COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
-COPY --from=builder /go/bin/protoc-gen-go /usr/bin/protoc-gen-go
-COPY --from=builder /go/bin/protoc-gen-go-grpc /usr/bin/protoc-gen-go-grpc
+COPY --from=builder /etc/passwd /etc/group /etc/
+COPY --from=builder /usr/share/zoneinfo/ /usr/share/zoneinfo/
+COPY --from=builder --chown=1000:1000 /go/bin/protoc-gen-go* /app/goctl /usr/local/bin/
 ENV TZ Asia/Shanghai
 
 WORKDIR /app
-COPY --from=builder /app/goctl /usr/bin/goctl
+USER app
+
+LABEL org.opencontainers.image.authors="Kevin Wan"
+LABEL org.opencontainers.image.base.name="docker.io/library/golang:alpine"
+LABEL org.opencontainers.image.description="A cloud-native Go microservices framework with cli tool for productivity."
+LABEL org.opencontainers.image.licenses="MIT"
+LABEL org.opencontainers.image.source="https://github.com/zeromicro/go-zero"
+LABEL org.opencontainers.image.title="goctl (cli)"
+LABEL org.opencontainers.image.version="v1.6.0"
 
-CMD ["goctl"]
+ENTRYPOINT ["/usr/local/bin/goctl"]


Test patch:
diff --git a/tools/goctl/test/integration/model/mongo/Dockerfile b/tools/goctl/test/integration/model/mongo/Dockerfile
index 91bce4fc..8d8a2ac9 100644
--- a/tools/goctl/test/integration/model/mongo/Dockerfile
+++ b/tools/goctl/test/integration/model/mongo/Dockerfile
@@ -1,12 +1,11 @@
-FROM golang:1.19
+FROM golang:1.21-alpine
 
 ENV TZ Asia/Shanghai
 ENV GOPROXY https://goproxy.cn,direct
 
 WORKDIR /app
-ADD goctl /usr/bin/goctl
-ADD cmd.sh .
+COPY goctl /usr/bin/
+COPY cmd.sh .
 
-RUN chmod +x /usr/bin/goctl
-RUN chmod +x cmd.sh
+RUN chmod +x /usr/bin/goctl cmd.sh
 CMD ["/bin/bash", "cmd.sh"]
diff --git a/tools/goctl/test/integration/model/mongo/mongo.sh b/tools/goctl/test/integration/model/mongo/mongo.sh
index 73c80ef3..1d580eb0 100644
--- a/tools/goctl/test/integration/model/mongo/mongo.sh
+++ b/tools/goctl/test/integration/model/mongo/mongo.sh
@@ -25,7 +25,7 @@ fi
 
 # run docker image
 console_step "docker running"
-docker run $image
+docker run --rm $image
 if [ $? -ne 0 ]; then
 	rm -f $buildFile
 	console_red "docker run failed"