hzDocs

产品发布

基于 cmdr 的 app 有哪些额外检查表

List

如果你基于 cmdr 开发 CLI app,那么注意我们对发布构建脚本也有所要求:

  • 你需要在 conf 子包(github.com/hedzr/cmdr/v2/conf)中写入构建信息
    • 包括版本号,git 标记,等等

这些信息将会被用于在多个内建命令和标志中被体现,同时它们也是供应链信息清单的一部分。

它们是通过 go build 命令行参数的方式实现的。

Dockerfile

为了简化文档书写,我们简单地提供一个 Dockerfile 样本,用于向你展示打包应用程序时应该写入的内容:

ARG BASE_BUILD_IMAGE
FROM ${BASE_BUILD_IMAGE:-golang:1.23} AS builder
 
ARG VERSION
ARG W_PKG
ARG GO111MODULE
ARG GOPROXY
ARG CN
ARG WORKDIR
ARG APPNAME
 
ENV AN=${APPNAME:-fluent}
ENV SRCS=./examples/${AN}
ENV WDIR=${WORKDIR:-/var/lib/$AN}
ENV GIT_REVISION	""
ENV GOVERSION		"1.15"
ENV BUILDTIME		""
ENV LDFLAGS			""
 
WORKDIR /go/src/github.com/hedzr/$AN/
COPY    .    .
RUN ls -ls ./; \
		W_PKG=${W_PKG:-github.com/hedzr/cmdr/v2/conf}; \
		GOPROXY=${GOPROXY:-https://goproxy.io,direct}; \
		V1=$(grep -E "Version[ \t]+=[ \t]+" doc.go|grep -Eo "[0-9.]+"); \
		VERSION=${VERSION:-$V1}; \
		GIT_REVISION="$(git rev-parse --short HEAD)"; \
		GOVERSION="$(go version)"; \
		BUILDTIME="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"; \
		LDFLAGS="-s -w \
			-X '$W_PKG.Githash=$GIT_REVISION' \
			-X '$W_PKG.GoVersion=$GOVERSION' \
			-X '$W_PKG.Buildstamp=$BUILDTIME' \
			-X '$W_PKG.Version=$VERSION'"; \
		echo;echo;echo "Using GOPROXY: $GOPROXY";echo "    CN: $CN";echo; \
		CGO_ENABLED=0 GOOS=linux go build -v -a -installsuffix cgo \
			-ldflags "$LDFLAGS" \
			-o bin/$AN $SRCS && \
		ls -la bin/
 
 
 
 
 
 
ARG BASE_IMAGE
FROM ${BASE_IMAGE:-alpine:latest}
 
ARG CN
ARG VERSION
ARG WORKDIR
ARG CONFDIR
ARG APPNAME
 
ENV AN=${APPNAME:-fluent}
ENV SRCS=./examples/fluent
ENV WDIR=${WORKDIR:-/var/lib/$AN}
ENV CDIR=${CONFDIR:-/etc/$AN}
 
LABEL by="hedzr" \
	version="$VERSION" \
	com.hedzr.cmdr-fluent.version="$VERSION" \
	com.hedzr.cmdr-fluent.release-date="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
	description="awesome-tool a command-line tool to retrieve the stars of all repos in an awesome-list"
 
COPY --from=builder /go/src/github.com/hedzr/$AN/ci/etc/$AN /etc/$AN
 
RUN ls -la $CDIR/ $CDIR/conf.d && echo "    CN: $CN"; \
    [[ "$CN" != "" ]] && { \
      cp /etc/apk/repositories /etc/apk/repositories.bak; \
      echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories; \
      echo;echo;echo "apk updating...";apk update; }; \
    apk --no-cache add ca-certificates && \
    mkdir -p $WDIR/output /var/log/$AN /var/run/$AN && \
    ls -la $WDIR/output /var/log/$AN /var/run/$AN
 
 
VOLUME  [ "$WDIR/output", "$CDIR/conf.d" ]
WORKDIR $WDIR
COPY --from=builder /go/src/github.com/hedzr/$AN/bin/$AN .
RUN echo $WDIR && echo $AN && ls -la $WDIR
 
ENTRYPOINT [ "./fluent" ]
CMD [ "--help" ]

使用这个 Dockerfile 的方法是发出下面的命令:

APPNAME=urcontainer
VERSION=v1.1.1
GIT_REVISION="$(git rev-parse --short HEAD)"
GIT_SUMMARY="$(git describe --tags --dirty --always)"
GIT_DESC="$(git log --oneline -1)"
GOVERSION="$(go version)"
BUILDTIME="$(date -u '+%Y-%m-%d_%H-%M-%S')"
BUILDTIMESTAMP="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
 
docker build -f Dockerfile \
	     --build-arg CN=1 \
	     --build-arg CI=1 \
	     --build-arg PORT="" \
	     --build-arg APPNAME="$APPNAME" \
	     --build-arg VERSION="$VERSION" \
	     --build-arg TIMESTAMP="$BUILDTIMESTAMP" \
	     --build-arg GIT_REVISION="$GIT_REVISION" \
	     --build-arg GIT_SUMMARY="$GIT_SUMMARY" \
	     --build-arg GIT_DESC="$GIT_DESC" \
	     --build-arg BUILDER_COMMENT="$BUILDER_COMMENT" \
	     -t $DOCKER_ORG_NAME/$APPNAME:latest \
	     -t $DOCKER_ORG_NAME/$APPNAME:$VERSION

你需要修订 Dockerfile 的具体内容,替换你的 metadata。

Bash 脚本方式

下面也提供一个 Bash 脚本来展示恰当的打包方式:

build.sh
#!/usr/bin/env bash
 
is_darwin() { [[ $OSTYPE == *darwin* ]]; }
 
is_darwin && LS_OPTS="-G" || LS_OPTS="--color"
 
test_docgo() {
  local DOCGO="${1:-doc.go}"
  if [ -f "$DOCGO" ]; then
    if grep -E "Version[ \t]+=[ \t]+" $DOCGO; then
      :
    else
      false
    fi
  else
    false
  fi
}
 
build-app() {
  local name="${1:-blueprint}"
  local SRCS="./examples/${name}/"
  local AN="${name}"
 
  W_PKG="${W_PKG:-github.com/hedzr/cmdr/v2/conf}"
  GOPROXY="${GOPROXY:-https://goproxy.io,direct}"
  DOCGO="doc.go"
  test_docgo "$DOCGO" || {
    DOCGO="./_examples/doc.go" && test_docgo "$DOCGO" || {
      DOCGO="./examples/doc.go" && test_docgo "$DOCGO" || {
        DOCGO="./examples/demo/doc.go" && test_docgo "$DOCGO" || {
          echo "CANNOT locate where is the Version."
          exit -1
        }
      }
    }
  }
  V1="$(grep -E "Version[ \t]+=[ \t]+" doc.go|grep -Eo "[0-9.]+")"
  VERSION="${VERSION:-$V1}"
  GIT_REVISION="$(git rev-parse --short HEAD)"
  GIT_SUMMARY="$(git describe --tags --dirty --always)"
  GIT_DESC="$(git log --oneline -1)"
  GOVERSION="$(go version)"
  BUILDTIME="$(date -u '+%Y-%m-%d_%H-%M-%S')"
  BUILDTIMESTAMP="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
  LDFLAGS="-s -w \
    -X '${W_PKG}.Githash=$GIT_REVISION' \
    -X '${W_PKG}.GitSummary=$GIT_SUMMARY' \
    -X '${W_PKG}.GitDesc=$GIT_DESC' \
    -X '${W_PKG}.BuilderComments=$BUILDER_COMMENT' \
    -X '${W_PKG}.GoVersion=$GOVERSION' \
    -X '${W_PKG}.Version=$VERSION' \
    -X '${W_PKG}.AppName=$APPNAME'
    -X '${W_PKG}.Buildstamp=$BUILDTIMESTAMP'"
 
  echo;echo;echo "Using GOPROXY: $GOPROXY";echo "    CN: $CN";echo
 
  GOOS="${GOOS:-linux}"
  CGO_ENABLED="${CGO_ENABLED:-0}"
 
  go build -v -a -installsuffix cgo \
    -ldflags "$LDFLAGS" \
    -o bin/$AN $SRCS && \
  chmod +x bin/$AN && \
  ls -la $LS_OPTS bin/$AN && \
  echo "version" && ./bin/$AN --version && \
  echo "build-info" && ./bin/$AN --built-info
  # echo
  # echo "$LDFLAGS"
}
 
cmd="${1:-build-app}"
(($#)) && shift
$cmd "$@"

要素

上面的 Dockerfile 所展示的要素包括:

在 go build 命令行中提供 -X "github.com/hedzr/cmdr/conf.Version=${VERSION}" 等选项,具体细节请参考相应的 conf 包中的变量定义,以此方式来提供基础的 metadata。

在制作 Docker 容器的时候,通过 bash 方式搜集 metadata,并提供给 Dockerfile。

部署目录

根据惯例,典型的应用程序部署目的地是 /usr/local/lib/<appname>

而惯用的相关文件夹首选为

  • /var/run/<app>.sock

  • /var/run/<app>.pid

  • /var/log/<app>/<app>.log

  • /var/cache/<app>/

  • /etc/<app>/<app>.toml

  • /etc/<app>/conf.d/*.toml

等等。

:end:

How is this guide?

Edit on GitHub

Last updated on

On this page