diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 37a6725..3012330 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -56,4 +56,6 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha - cache-to: type=gha,mode=max \ No newline at end of file + cache-to: type=gha,mode=max + build-args: | + VERSION=${{ github.sha }} \ No newline at end of file diff --git a/Dockerfile.server b/Dockerfile.server index 49cebf3..19bb10d 100644 --- a/Dockerfile.server +++ b/Dockerfile.server @@ -18,6 +18,8 @@ FROM golang:1.25-alpine AS builder # 기본값을 지정해두면 로컬 docker build 시에도 별도 인자 없이 빌드 가능합니다. ARG TARGETOS=linux ARG TARGETARCH=amd64 +# Git 태그/커밋 정보를 main.version 에 주입하기 위한 VERSION 인자 (기본 dev) +ARG VERSION=dev WORKDIR /src @@ -32,7 +34,8 @@ RUN go mod download COPY . . # 서버 바이너리 빌드 (멀티 아키텍처: TARGETOS/TARGETARCH 기반) -RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/hop-gate-server ./cmd/server +# -ldflags 를 통해 main.version 에 VERSION 값을 주입합니다. +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags "-X main.version=${VERSION}" -o /out/hop-gate-server ./cmd/server # ---------- Runtime stage ---------- FROM alpine:3.20 diff --git a/Makefile b/Makefile index 6cb0bc6..85629c4 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,9 @@ BIN_DIR := ./bin SERVER_BIN := $(BIN_DIR)/hop-gate-server CLIENT_BIN := $(BIN_DIR)/hop-gate-client -VERSION ?= $(shell git describe --tags --dirty --always 2>/dev/null || echo dev) +# VERSION 은 현재 커밋의 7글자 SHA 를 사용합니다 (예: 1a2b3c4). +# git 정보가 없으면 dev 로 fallback 합니다. +VERSION ?= $(shell git rev-parse --short=7 HEAD 2>/dev/null || echo dev) # .env 파일 로드 include .env diff --git a/cmd/client/main.go b/cmd/client/main.go index daa5ce5..ad0848d 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -15,6 +15,10 @@ import ( "github.com/dalbodeule/hop-gate/internal/proxy" ) +// version 은 빌드 시 -ldflags "-X main.version=xxxxxxx" 로 덮어쓰이는 필드입니다. +// 기본값 "dev" 는 로컬 개발용입니다. +var version = "dev" + func getEnvOrPanic(logger logging.Logger, key string) string { value, exists := os.LookupEnv(key) if !exists || strings.TrimSpace(value) == "" { @@ -124,6 +128,7 @@ func main() { logger.Info("hop-gate client starting", logging.Fields{ "stack": "prometheus-loki-grafana", + "version": version, "server_addr": finalCfg.ServerAddr, "domain": finalCfg.Domain, "local_target": finalCfg.LocalTarget, diff --git a/cmd/server/main.go b/cmd/server/main.go index 930ba0c..5f7f08f 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -29,6 +29,10 @@ import ( "github.com/dalbodeule/hop-gate/internal/store" ) +// version 은 빌드 시 -ldflags "-X main.version=xxxxxxx" 로 덮어쓰이는 필드입니다. +// 기본값 "dev" 는 로컬 개발용입니다. +var version = "dev" + type dtlsSessionWrapper struct { sess dtls.Session mu sync.Mutex @@ -815,6 +819,7 @@ func main() { logger.Info("hop-gate server starting", logging.Fields{ "stack": "prometheus-loki-grafana", + "version": version, "http_listen": cfg.HTTPListen, "https_listen": cfg.HTTPSListen, "dtls_listen": cfg.DTLSListen, diff --git a/tools/build_server_image.sh b/tools/build_server_image.sh new file mode 100644 index 0000000..87ff21e --- /dev/null +++ b/tools/build_server_image.sh @@ -0,0 +1,43 @@ +. #!/usr/bin/env bash + +set -euo pipefail + +# Build hop-gate server image from Dockerfile.server. +# VERSION is derived from current git commit (7-char SHA). + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +REPO_ROOT="${SCRIPT_DIR}/.." +cd "${REPO_ROOT}" + +VERSION="$(git rev-parse --short=7 HEAD 2>/dev/null || echo dev)" + +# Default image name; can be overridden by first argument. +# Usage: +# ./tools/build_server_image.sh # builds ghcr.io/dalbodeule/hop-gate: and :latest +# ./tools/build_server_image.sh my/image/name # builds my/image/name: and :latest +IMAGE_NAME="${1:-ghcr.io/dalbodeule/hop-gate}" + +echo "Building hop-gate server image" +echo " context : ${REPO_ROOT}" +echo " image : ${IMAGE_NAME}:${VERSION}" +echo " version : ${VERSION}" + +# Use docker buildx if available; fallback to docker build. +if command -v docker >/dev/null 2>&1 && docker buildx version >/dev/null 2>&1; then + BUILD_CMD=(docker buildx build) +else + BUILD_CMD=(docker build) +fi + +# Optional environment variables: +# PLATFORM=linux/amd64,linux/arm64 (for buildx) +# PUSH=1 (for buildx --push) + +"${BUILD_CMD[@]}" \ + ${PLATFORM:+--platform "${PLATFORM}"} \ + -f Dockerfile.server \ + --build-arg VERSION="${VERSION}" \ + -t "${IMAGE_NAME}:${VERSION}" \ + -t "${IMAGE_NAME}:latest" \ + ${PUSH:+--push} \ + . \ No newline at end of file