HaloLight 后台管理系统的 容器化自托管版本,支持 Docker Compose 一键部署,集成 Traefik 反向代理和 Let's Encrypt 自动证书。
- Docker Compose:一键启动完整环境
- Traefik 反向代理:自动路由和负载均衡
- Let's Encrypt:自动 HTTPS 证书
- 多阶段构建:优化镜像体积
- 健康检查:容器健康监控
- 日志管理:集中日志收集
# 克隆仓库
git clone https://github.com/halolight/halolight-docker.git
cd halolight-docker
# 复制环境变量
cp .env.example .env
# 启动服务
docker compose up -d
# 查看日志
docker compose logs -f# 拉取镜像
docker pull halolight/halolight-docker:latest
# 运行容器
docker run -d \
--name halolight \
-p 3000:3000 \
-e NEXT_PUBLIC_API_URL=/api \
halolight/halolight-docker:latest# 构建阶段FROM node:20-alpine AS builder
WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
# 运行阶段FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]version: '3.8'services:
app:
build: .restart: unless-stoppedenvironment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=/apilabels:
- "traefik.enable=true"
- "traefik.http.routers.halolight.rule=Host(`halolight.example.com`)"
- "traefik.http.routers.halolight.tls.certresolver=letsencrypt"traefik:
image: traefik:v3.0restart: unless-stoppedports:
- "80:80"
- "443:443"volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik:/etc/traefikpostgres:
image: postgres:16-alpinerestart: unless-stoppedenvironment:
POSTGRES_DB: halolightPOSTGRES_USER: halolightPOSTGRES_PASSWORD: ${DB_PASSWORD}volumes:
- postgres_data:/var/lib/postgresql/datavolumes:
postgres_data:cp .env.example .env
# 编辑 .env 配置域名、数据库密码等# traefik/traefik.ymlentryPoints:
web:
address: ":80"http:
redirections:
entryPoint:
to: websecurewebsecure:
address: ":443"certificatesResolvers:
letsencrypt:
acme:
email: admin@halolight.h7ml.cnstorage: /etc/traefik/acme.jsonhttpChallenge:
entryPoint: webdocker compose -f docker-compose.prod.yml up -dhealthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]interval: 30stimeout: 10sretries: 3