thread-master/Makefile

230 lines
9.5 KiB
Makefile
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 巡樓 monorepo Makefile
# 兩種模式:
# dev - 本機開發docker 起 Mongo/Redisgo run / vite dev
# prod - 建置產物(前端 dist + linux Go binary並可部署成 systemd 服務 + nginx
#
# 常用:
# make dev-infra # 起本機 Mongo/Redis
# make dev-backend # 跑 gateway (:8890)
# make dev-frontend # 跑前端 (:5173proxy 到 :8890)
# make build # 產出 frontend/dist + backend/bin/{gateway,worker}
# sudo make install # 部署到目標主機(見 infra/README.md
SHELL := /bin/bash
# --- 路徑 ---
BACKEND_DIR := backend
FRONTEND_DIR := frontend
INFRA_DIR := infra
BIN_DIR := $(BACKEND_DIR)/bin
# --- 部署目標install 用)---
DEPLOY_ROOT := /opt/haixun
WEB_ROOT := /var/www/haixun
# --- 交叉編譯目標(在 mac 上 build 給 linux 主機)---
GOOS ?= linux
GOARCH ?= amd64
# --- docker compose ---
COMPOSE := docker compose -f $(INFRA_DIR)/docker-compose.yml --env-file $(INFRA_DIR)/.env
# --- dev 用 worker secret對應 etc/gateway.yaml 的 InternalWorker.Secret---
DEV_WORKER_SECRET := haixun-dev-worker-secret
DEV_BACKEND_URL := http://127.0.0.1:8890
.DEFAULT_GOAL := help
.PHONY: help
help: ## 顯示可用指令
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
| awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}'
# ============================================================
# DEV
# ============================================================
$(INFRA_DIR)/.env:
@test -f $(INFRA_DIR)/.env || (cp $(INFRA_DIR)/.env.example $(INFRA_DIR)/.env && echo "已從 .env.example 建立 $(INFRA_DIR)/.env請視需要修改密碼")
.PHONY: dev-infra
dev-infra: $(INFRA_DIR)/.env ## [dev] 起本機 Mongo + Redis (docker)
$(COMPOSE) up -d
$(COMPOSE) ps
.PHONY: dev-infra-down
dev-infra-down: ## [dev] 停掉本機 Mongo + Redis
$(COMPOSE) down
.PHONY: dev-backend
dev-backend: ## [dev] 跑 gateway API (:8890)
cd $(BACKEND_DIR) && go run . -f etc/gateway.yaml
.PHONY: dev-worker
dev-worker: ## [dev] 跑 Go job worker (:8891)
cd $(BACKEND_DIR) && go run ./cmd/worker -f etc/gateway.worker.yaml
.PHONY: dev-node-worker
dev-node-worker: ## [dev] 跑 Node playwright worker (style-8d)
cd $(BACKEND_DIR)/worker && npm install && \
HAIXUN_WORKER_SECRET=$(DEV_WORKER_SECRET) HAIXUN_BACKEND_URL=$(DEV_BACKEND_URL) npm run style-8d
.PHONY: dev-frontend
dev-frontend: ## [dev] 跑前端 dev server (:5173)
cd $(FRONTEND_DIR) && npm install && npm run dev
.PHONY: dev-init
dev-init: ## [dev] 初始化 DB索引/權限)並建立 admin 帳號(可用 INIT_ADMIN_EMAIL / INIT_ADMIN_PASSWORD 覆寫)
cd $(BACKEND_DIR) && go run ./cmd/tool init -f etc/gateway.yaml
.PHONY: dev
dev: ## [dev] 顯示本機開發要開的終端
@echo "本機開發請分開幾個終端執行:"
@echo " 1) make dev-infra # Mongo/Redis"
@echo " 2) make dev-backend # gateway :8890"
@echo " 3) make dev-worker # go worker可選"
@echo " 4) make dev-node-worker # node worker需 style-8d 時)"
@echo " 5) make dev-frontend # 前端 :5173"
# ============================================================
# 安裝依賴(新機器 clone 後執行一次)
# ============================================================
.PHONY: bootstrap-sys
bootstrap-sys: ## [需 sudo] 安裝系統依賴Go, Node.js, Docker, Nginx— Ubuntu 專用
@echo "=== 安裝系統套件: nginx, curl, gnupg ==="
sudo apt-get update -qq
sudo apt-get install -y -qq nginx curl gnupg ca-certificates
@echo ""
@echo "=== 安裝 Go 1.22+ ==="
@GO_VER=$$(curl -sL https://go.dev/VERSION?m=text 2>/dev/null | head -1 || echo "go1.22"); \
echo "下載 $$GO_VER.linux-amd64.tar.gz"; \
curl -sL "https://go.dev/dl/$$GO_VER.linux-amd64.tar.gz" -o /tmp/go.tar.gz && \
sudo rm -rf /usr/local/go && \
sudo tar -C /usr/local -xzf /tmp/go.tar.gz && \
rm /tmp/go.tar.gz; \
echo 'export PATH=/usr/local/go/bin:$$PATH' | sudo tee /etc/profile.d/go.sh
@echo ""
@echo "=== 安裝 Node.js LTS ==="
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y -qq nodejs
@echo ""
@echo "=== 安裝 Docker Engine + Compose ==="
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $(USER) 2>/dev/null || true
@echo ""
@echo "=== 安裝 Nginx ==="
sudo apt-get install -y -qq nginx
@echo ""
@echo "✓ 系統依賴安裝完成。"
@echo " 登出再登入後Go/Node/Docker 即可使用group 變更生效)。"
@echo " 接著執行 make bootstrap 安裝專案層依賴。"
@echo ""
.PHONY: bootstrap
bootstrap: ## 安裝專案層依賴Go modules + npm + Playwright需先執行 make bootstrap-sys
@echo "=== [1/4] Go modules ==="
cd $(BACKEND_DIR) && go mod tidy
@echo ""
@echo "=== [2/4] 前端 npm ==="
cd $(FRONTEND_DIR) && npm install
@echo ""
@echo "=== [3/4] Node worker npm ==="
cd $(BACKEND_DIR)/worker && npm install
@echo ""
@echo "=== [4/4] Playwright 瀏覽器chromium+ 系統依賴 ==="
cd $(BACKEND_DIR)/worker && sudo npx playwright install --with-deps chromium
@echo ""
@echo "✓ 全裝完成。後續步驟:"
@echo " 1) make dev-infra # 起 Mongo/Redis (Docker)"
@echo " 2) make dev-init # 初始化 DB + 建立 admin"
@echo " 3) make dev-backend # 啟動 gateway (:8890)"
@echo " 4) sudo make install # 正式部署(含 systemd + nginx"
# ============================================================
# BUILD (prod 產物)
# ============================================================
.PHONY: build
build: build-frontend build-backend ## [prod] 建置前端 dist 與 Go binary
.PHONY: build-frontend
build-frontend: ## [prod] 前端靜態建置 (tsc + vite) -> frontend/dist
cd $(FRONTEND_DIR) && npm ci && npm run build
.PHONY: build-backend
build-backend: ## [prod] 交叉編譯 gateway + worker -> backend/bin (linux)
cd $(BACKEND_DIR) && CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
go build -trimpath -ldflags "-s -w" -o bin/gateway .
cd $(BACKEND_DIR) && CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
go build -trimpath -ldflags "-s -w" -o bin/worker ./cmd/worker
cd $(BACKEND_DIR) && CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) \
go build -trimpath -ldflags "-s -w" -o bin/tool ./cmd/tool
@echo "binary 已輸出到 $(BIN_DIR)/gateway / worker / tool"
# ============================================================
# PROD (部署)
# ============================================================
.PHONY: prod-infra
prod-infra: $(INFRA_DIR)/.env ## [prod] 起 Mongo + Redis (docker背景)
$(COMPOSE) up -d
.PHONY: prod-infra-down
prod-infra-down: ## [prod] 停掉 Mongo + Redis
$(COMPOSE) down
.PHONY: prod-init
prod-init: ## [prod] 目標主機初始化 DB + 建立 admin讀 /opt/haixun/etc/haixun.env可加 INIT_ADMIN_EMAIL/PASSWORD
@test -x $(DEPLOY_ROOT)/bin/tool || (echo "缺少 $(DEPLOY_ROOT)/bin/tool請先 make install" && exit 1)
set -a; . $(DEPLOY_ROOT)/etc/haixun.env; set +a; \
$(DEPLOY_ROOT)/bin/tool init -f $(DEPLOY_ROOT)/etc/gateway.prod.yaml
.PHONY: install
install: ## [prod] 安裝 binary/前端/設定/systemd/nginx需 root在目標主機執行
@test -f $(BIN_DIR)/gateway || (echo "缺少 $(BIN_DIR)/gateway請先在能 build 的機器執行 make build" && exit 1)
@test -d $(FRONTEND_DIR)/dist || (echo "缺少 $(FRONTEND_DIR)/dist請先 make build-frontend" && exit 1)
id haixun >/dev/null 2>&1 || useradd --system --home $(DEPLOY_ROOT) --shell /usr/sbin/nologin haixun
install -d $(DEPLOY_ROOT)/bin $(DEPLOY_ROOT)/etc $(DEPLOY_ROOT)/node-worker $(WEB_ROOT)
install -m 0755 $(BIN_DIR)/gateway $(DEPLOY_ROOT)/bin/gateway
install -m 0755 $(BIN_DIR)/worker $(DEPLOY_ROOT)/bin/worker
install -m 0755 $(BIN_DIR)/tool $(DEPLOY_ROOT)/bin/tool
install -m 0644 $(BACKEND_DIR)/etc/gateway.prod.yaml $(DEPLOY_ROOT)/etc/gateway.prod.yaml
install -m 0644 $(BACKEND_DIR)/etc/gateway.worker.prod.yaml $(DEPLOY_ROOT)/etc/gateway.worker.prod.yaml
rm -rf $(WEB_ROOT)/* && cp -r $(FRONTEND_DIR)/dist/* $(WEB_ROOT)/
cp -r $(BACKEND_DIR)/worker/* $(DEPLOY_ROOT)/node-worker/
cd $(DEPLOY_ROOT)/node-worker && npm ci && npx playwright install --with-deps chromium
install -m 0644 $(INFRA_DIR)/systemd/haixun-gateway.service /etc/systemd/system/haixun-gateway.service
install -m 0644 $(INFRA_DIR)/systemd/haixun-worker.service /etc/systemd/system/haixun-worker.service
install -m 0644 $(INFRA_DIR)/systemd/haixun-node-worker.service /etc/systemd/system/haixun-node-worker.service
install -m 0644 $(INFRA_DIR)/nginx/haixun.conf /etc/nginx/conf.d/haixun.conf
chown -R haixun:haixun $(DEPLOY_ROOT) $(WEB_ROOT)
@echo "----"
@echo "接著(只做一次)建立 secret 檔:"
@echo " cp $(INFRA_DIR)/etc/haixun.env.example $(DEPLOY_ROOT)/etc/haixun.env && chmod 600 $(DEPLOY_ROOT)/etc/haixun.env && sudoedit $(DEPLOY_ROOT)/etc/haixun.env"
@echo "再啟用服務:"
@echo " systemctl daemon-reload && systemctl enable --now haixun-gateway haixun-worker haixun-node-worker"
@echo " nginx -t && systemctl reload nginx"
# ============================================================
# 驗證 / 維護
# ============================================================
.PHONY: tidy
tidy: ## go mod tidy
cd $(BACKEND_DIR) && go mod tidy
.PHONY: fmt
fmt: ## gofmt 後端
cd $(BACKEND_DIR) && gofmt -w .
.PHONY: test
test: ## 跑後端測試
cd $(BACKEND_DIR) && go test ./...
.PHONY: verify
verify: ## 後端 build/test + 前端 build + compose 語法
cd $(BACKEND_DIR) && go build ./... && go test ./...
cd $(FRONTEND_DIR) && npm ci && npm run build
$(COMPOSE) config >/dev/null && echo "docker compose config OK"