diff --git a/go/.dockerignore b/go/.dockerignore new file mode 100644 index 0000000..94084c7 --- /dev/null +++ b/go/.dockerignore @@ -0,0 +1,13 @@ +# Go 编译产物 +electric-monitor +*.exe + +# 数据文件(历史记录 + 会话缓存) +data/ +*.json + +# 环境配置(含账号密码,切勿提交) +.env + +# 日志 +*.log diff --git a/go/.env.example b/go/.env.example new file mode 100644 index 0000000..3e41292 --- /dev/null +++ b/go/.env.example @@ -0,0 +1,16 @@ +# 宿舍电费监控 - 环境配置模板 +# 复制为 .env 后填入真实账号密码: cp .env.example .env +# 切勿将 .env 提交到版本库 + +LZU_USERNAME=your_student_id +LZU_PASSWORD=your_password + +# 以下为平台参数,一般无需修改 +LZU_SERVICE_ID=29615 +XF_PLATFORM=QHIT_EDU +XF_AUTH_APPID=2606161276416311297 +XF_SCHOOL_CODE=10730 +XF_YM_APPID=1810181825222034 +LZU_AES_KEY=your_aes_key_16bytes +LZU_MD5_KEY=your_md5_key +XF_CACHE_TTL=518400 diff --git a/go/Dockerfile b/go/Dockerfile new file mode 100644 index 0000000..0598404 --- /dev/null +++ b/go/Dockerfile @@ -0,0 +1,46 @@ +# 宿舍电费监控 - 多阶段构建 +# 阶段1: 编译 Go 静态二进制 +FROM golang:1.22-alpine AS builder +WORKDIR /build +# 复制源码(go:embed 需要 static/ 在同一构建上下文) +COPY go.mod ./ +COPY *.go ./ +COPY static/ ./static/ +# CGO_ENABLED=0 纯静态编译,适用于 scratch/alpine 运行 +RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o electric-monitor . + +# 阶段2: 最小运行镜像 +FROM alpine:3.20 +# 时区: 定时任务需按北京时间 00:00 触发 +RUN apk add --no-cache tzdata \ + && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && echo "Asia/Shanghai" > /etc/timezone \ + && apk del tzdata +# 数据目录(历史记录 + 缓存挂载点) +RUN mkdir -p /app/data +WORKDIR /app +COPY --from=builder /build/electric-monitor . + +# 端口与健康检查 +EXPOSE 8000 +HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ + CMD wget -qO- http://127.0.0.1:8000/api/electric > /dev/null || exit 1 + +# 数据持久化卷 +VOLUME ["/app/data"] + +# 默认值(可由 docker-compose/.env 覆盖;账号密码与加密密钥必须由运行环境注入) +ENV HOST=0.0.0.0 \ + PORT=8000 \ + LZU_USERNAME= \ + LZU_PASSWORD= \ + LZU_SERVICE_ID=29615 \ + XF_PLATFORM=QHIT_EDU \ + XF_AUTH_APPID=2606161276416311297 \ + XF_SCHOOL_CODE=10730 \ + XF_YM_APPID=1810181825222034 \ + CACHE_FILE=/app/data/electric_cache.json \ + HISTORY_FILE=/app/data/electric_history.json \ + XF_CACHE_TTL=518400 + +CMD ["./electric-monitor"] diff --git a/go/docker-compose.yml b/go/docker-compose.yml new file mode 100644 index 0000000..27df26c --- /dev/null +++ b/go/docker-compose.yml @@ -0,0 +1,22 @@ +services: + electric-monitor: + build: . + container_name: electric-monitor + restart: unless-stopped + ports: + - "8000:8000" + environment: + # 账号密码与加密密钥必须通过 .env 注入(见 .env.example) + LZU_USERNAME: "${LZU_USERNAME}" + LZU_PASSWORD: "${LZU_PASSWORD}" + LZU_SERVICE_ID: "${LZU_SERVICE_ID:-29615}" + XF_PLATFORM: "${XF_PLATFORM:-QHIT_EDU}" + XF_AUTH_APPID: "${XF_AUTH_APPID:-2606161276416311297}" + XF_SCHOOL_CODE: "${XF_SCHOOL_CODE:-10730}" + XF_YM_APPID: "${XF_YM_APPID:-1810181825222034}" + LZU_AES_KEY: "${LZU_AES_KEY}" + LZU_MD5_KEY: "${LZU_MD5_KEY}" + XF_CACHE_TTL: "${XF_CACHE_TTL:-518400}" + TZ: Asia/Shanghai + volumes: + - ./data:/app/data diff --git a/go/run_docker.sh b/go/run_docker.sh new file mode 100644 index 0000000..c66cc73 --- /dev/null +++ b/go/run_docker.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# 重新构建并部署 Docker 容器 +# 配置从 .env 读取(参照 .env.example 创建) +cd "$(dirname "$0")" +set -a; source .env 2>/dev/null || { echo "缺少 .env 配置,请先参照 .env.example 创建"; exit 1; }; set +a + +docker rm -f electric-monitor 2>/dev/null +docker build -t electric-monitor:latest . 2>&1 | tail -3 +echo "=== 启动 ===" +docker run -d --name electric-monitor \ + -p 6983:8000 \ + -e LZU_USERNAME="$LZU_USERNAME" \ + -e LZU_PASSWORD="$LZU_PASSWORD" \ + -e LZU_AES_KEY="$LZU_AES_KEY" \ + -e LZU_MD5_KEY="$LZU_MD5_KEY" \ + -e LZU_SERVICE_ID="${LZU_SERVICE_ID:-29615}" \ + -e TZ=Asia/Shanghai \ + -v "$(pwd)/data:/app/data" \ + electric-monitor:latest +sleep 8 +echo "=== 容器状态 ===" +docker ps --filter name=electric-monitor --format "{{.Status}}" +echo "=== 内存 ===" +docker stats --no-stream electric-monitor --format "MEM: {{.MemUsage}} CPU: {{.CPUPerc}}" +echo "=== 日志 ===" +docker logs electric-monitor 2>&1 | head -8 +echo "=== API 测试 ===" +curl -s --max-time 40 http://127.0.0.1:6983/api/electric +echo +curl -s -o /dev/null -w 'index: %{http_code}\n' http://127.0.0.1:6983/