From 56e9f0cdb4c44fa12cf912790b61b6f38583cc24 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Wed, 22 Jul 2026 13:06:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 7 ++++++- Caddyfile | 24 +++++++++++++-------- Dockerfile.backend | 14 ++++++------- Makefile | 52 ++++++++++++++++++++++++++++++++++------------ docker-compose.yml | 21 +++++++++---------- 5 files changed, 77 insertions(+), 41 deletions(-) diff --git a/.env.example b/.env.example index d767be0..ee90fa1 100644 --- a/.env.example +++ b/.env.example @@ -7,4 +7,9 @@ OPEN_API_SECRET=sk_source_dev_secret_change_me OPEN_SIGN_SKEW=300 OPEN_API_DEBUG=false LOG_FILE=logs/app.log -# For Caddy production, no need for frontend env since built static \ No newline at end of file +# Caddy 镜像配置:make docker-up 会先拉取来源镜像并标记成本地运行镜像 +CADDY_RUNTIME_IMAGE=affiliate-caddy:2 +CADDY_SOURCE_IMAGE=caddy:2 +CADDY_FALLBACK_IMAGES=docker.m.daocloud.io/library/caddy:2 registry.cn-hangzhou.aliyuncs.com/caddy/caddy:2 + +# Caddy 生产环境无需前端运行时环境变量,前端会构建为静态文件 diff --git a/Caddyfile b/Caddyfile index a999cb3..4a3de19 100644 --- a/Caddyfile +++ b/Caddyfile @@ -1,14 +1,20 @@ { - # admin off # disable admin if wanted + # 如需关闭管理接口,可取消下一行注释 / Uncomment to disable admin API + # admin off } skin.khhao.com { - # Reverse proxy all /api* requests to the backend service - reverse_proxy /api* backend:8080 + encode gzip zstd - # Serve static files for the frontend (SPA) - file_server / { - root * /usr/share/caddy - try_files {path} {path}/index.html - } -} \ No newline at end of file + # API 请求反向代理到后端服务 / Proxy API requests to backend + handle /api* { + reverse_proxy backend:8080 + } + + # 前端 SPA 静态文件 / Serve frontend SPA + handle { + root * /usr/share/caddy + try_files {path} {path}/ /index.html + file_server + } +} diff --git a/Dockerfile.backend b/Dockerfile.backend index bf1f9a6..44d4600 100644 --- a/Dockerfile.backend +++ b/Dockerfile.backend @@ -2,26 +2,26 @@ FROM golang:1.26-alpine AS builder WORKDIR /app -# Copy Go files +# 复制 Go 依赖文件 / Copy Go dependency files COPY backend/go.mod backend/go.sum ./ RUN go mod download COPY backend ./backend WORKDIR /app/backend -# Build the Go binary +# 构建 Go 二进制文件 / Build Go binary RUN CGO_ENABLED=0 GOOS=linux go build -o /server ./cmd/server -# Final stage +# 最终运行镜像 / Runtime image FROM alpine:latest -RUN apk --no-cache add ca-certificates tzdata +RUN apk --no-cache add ca-certificates tzdata curl WORKDIR /app COPY --from=builder /server ./server -# Expose port +# 暴露服务端口 / Expose service port EXPOSE 8080 -# Run the server -CMD ["./server"] \ No newline at end of file +# 启动服务 / Run server +CMD ["./server"] diff --git a/Makefile b/Makefile index c7e548c..46e9e2e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,13 @@ -.PHONY: start dev backend frontend install stop docker-build docker-up docker-down +.PHONY: start dev backend frontend install stop frontend-build docker-pull-caddy docker-build docker-up docker-down docker-logs + +ifneq (,$(wildcard .env)) +include .env +export +endif + +CADDY_RUNTIME_IMAGE ?= affiliate-caddy:2 +CADDY_SOURCE_IMAGE ?= caddy:2 +CADDY_FALLBACK_IMAGES ?= docker.m.daocloud.io/library/caddy:2 registry.cn-hangzhou.aliyuncs.com/caddy/caddy:2 # 一键启动前后端(推荐) start dev: @@ -20,21 +29,38 @@ stop: @-lsof -tiTCP:5173 -sTCP:LISTEN | xargs kill 2>/dev/null || true @echo "已尝试停止 8080 / 5173 端口服务" -# Docker deployment targets -docker-build: - @echo "Building backend Docker image..." - docker build -f Dockerfile.backend -t affiliate-backend:latest . - @echo "Frontend must be built separately: cd frontend && npm run build" - @echo "Then run: docker compose up -d --build" +# Docker 部署相关命令 +frontend-build: + @echo "构建前端静态文件..." + cd frontend && npm ci && npm run build -docker-up: - @echo "Starting services with docker-compose (pulls Caddy image if needed)..." - docker compose up -d +docker-pull-caddy: + @set -e; \ + echo "准备 Caddy 运行镜像: $(CADDY_RUNTIME_IMAGE)"; \ + for image in $(CADDY_SOURCE_IMAGE) $(CADDY_FALLBACK_IMAGES); do \ + echo "尝试拉取 Caddy 镜像: $$image"; \ + if docker pull "$$image"; then \ + docker tag "$$image" "$(CADDY_RUNTIME_IMAGE)"; \ + echo "已将 $$image 标记为 $(CADDY_RUNTIME_IMAGE)"; \ + exit 0; \ + fi; \ + done; \ + echo "错误: Caddy 镜像拉取失败,可在 .env 中设置 CADDY_SOURCE_IMAGE 或 CADDY_FALLBACK_IMAGES"; \ + exit 1 + +docker-build: frontend-build docker-pull-caddy + @echo "构建后端 Docker 镜像..." + docker build -f Dockerfile.backend -t affiliate-backend:latest . + @echo "构建完成,可执行: docker compose up -d --build" + +docker-up: frontend-build docker-pull-caddy + @echo "启动 Docker Compose 服务..." + docker compose up -d --build docker-down: - @echo "Stopping and removing containers..." + @echo "停止并移除容器..." docker compose down docker-logs: - @echo "Showing backend and caddy logs..." - docker compose logs -f backend caddy \ No newline at end of file + @echo "查看 backend 和 caddy 日志..." + docker compose logs -f backend caddy diff --git a/docker-compose.yml b/docker-compose.yml index 81cde4b..85bcd91 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,3 @@ -# Docker Compose for affiliate_dash (skin.khhao.com) -# In China, Docker Hub pull often hits rate limits on mirrors (e.g. docker.xuanyuan.me). -# Fix: Run "docker pull caddy:2" first, or use a mirror like registry.cn-hangzhou.aliyuncs.com/caddy/caddy:2 -# Recommended: manually pull first, then docker compose up -d (no --build for caddy) - -version: '3.8' - services: backend: build: @@ -26,23 +19,29 @@ services: - backend-data:/data restart: unless-stopped healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 caddy: - image: caddy:2 + image: ${CADDY_RUNTIME_IMAGE:-affiliate-caddy:2} + pull_policy: never ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - ./frontend/dist:/usr/share/caddy + - caddy-data:/data + - caddy-config:/config command: caddy run --config /etc/caddy/Caddyfile --adapter caddyfile depends_on: - - backend + backend: + condition: service_healthy restart: unless-stopped volumes: - backend-data: \ No newline at end of file + backend-data: + caddy-data: + caddy-config: