diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..73ce486 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,77 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Git +.git +.gitignore +.github + +# Documentation +README.md +CHANGELOG.md +LICENSE +*.md + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Testing +coverage +.nyc_output + +# IDE +.vscode +.idea +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage + +# Build outputs (exclude .build-cache for multi-stage builds) +# Note: dist/ is included for simple build approach +.build-cache + +# Docker files +Dockerfile* +docker-compose*.yml +.dockerignore + +# Temporary files +.tmp +.temp + +# Cache +.cache +.parcel-cache + +# Storybook build +storybook-static + +# Spec workflow files +.spec-workflow +.serenatoken + +# Astro cache +.astro \ No newline at end of file diff --git a/DOCKER_DEPLOY.md b/DOCKER_DEPLOY.md new file mode 100644 index 0000000..7a3ee4c --- /dev/null +++ b/DOCKER_DEPLOY.md @@ -0,0 +1,305 @@ +# Moodist Docker 部署指南 + +## 🐳 Docker 镜像构建和部署 + +### 📋 镜像信息 + +- **镜像名称**: `walllee/moodist` +- **Docker Hub**: https://hub.docker.com/r/walllee/moodist +- **支持平台**: `linux/amd64`, `linux/arm64` +- **基础镜像**: `nginx:alpine` +- **镜像大小**: ~30MB + +### 🚀 快速开始 + +#### 1. 直接拉取并运行 +```bash +# 拉取镜像 +docker pull walllee/moodist:latest + +# 运行容器 +docker run -d \ + --name moodist \ + -p 8080:8080 \ + --restart unless-stopped \ + walllee/moodist:latest +``` + +#### 2. 使用 Docker Compose +```bash +# 简单版本 +docker-compose up -d + +# 或使用优化版本 +docker-compose -f docker-compose.optimized.yml up -d + +# 查看日志 +docker-compose logs -f +# 或 +docker-compose -f docker-compose.optimized.yml logs -f + +# 停止服务 +docker-compose down +``` + +### 🔨 自定义构建 + +#### 1. 简化本地构建(推荐) +```bash +# 克隆仓库 +git clone https://github.com/wheesys/moodist.git +cd moodist + +# 简化构建(推荐,兼容性最好) +npm run docker:push + +# 或带版本号构建 +./scripts/build-docker-simple.sh 2.1.0 + +# 构建并推送到 Docker Hub +npm run docker:push-and-upload +``` + +**特点:** +- ✅ 完全兼容,不依赖 Docker Buildx +- ✅ 先本地构建再打包,避免容器内依赖问题 +- ✅ 构建速度快,使用缓存优化 +- ✅ 支持版本标签和自动 latest 标签 + +#### 2. 多平台构建 +```bash +# 克隆仓库 +git clone https://github.com/wheesys/moodist.git +cd moodist + +# 本地构建和测试 +./scripts/build-local.sh + +# 查看构建结果 +docker images | grep moodist +``` + +#### 3. 推送到 Docker Hub +```bash +# 登录 Docker Hub +docker login + +# 使用简化脚本推送 +npm run docker:push-and-upload + +# 或手动推送指定版本 +docker push walllee/moodist:2.1.0 +docker push walllee/moodist:latest +``` + +### 📦 部署配置 + +#### 生产环境配置 +```yaml +version: '3.8' +services: + moodist: + image: wheeysys/moodist:latest + container_name: moodist-prod + restart: always + ports: + - "80:8080" + environment: + - NODE_ENV=production + - TZ=Asia/Shanghai + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/"] + interval: 30s + timeout: 10s + retries: 3 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" +``` + +#### 开发环境配置 +```bash +# 使用开发配置 +docker-compose -f docker-compose.dev.yml up -d + +# 或者使用开发工具 +docker-compose -f docker-compose.dev.yml --profile tools up -d +``` + +### 🔧 环境变量 + +| 变量名 | 默认值 | 说明 | +|--------|--------|------| +| `NODE_ENV` | `production` | 运行环境 | +| `TZ` | `Asia/Shanghai` | 时区设置 | + +### 📊 性能优化 + +#### 镜像特性 +- ✅ **多阶段构建**: 优化镜像大小 +- ✅ **多平台支持**: AMD64 + ARM64 +- ✅ **非root用户**: 提高安全性 +- ✅ **健康检查**: 自动监控应用状态 +- ✅ **静态优化**: Nginx + Gzip 压缩 + +#### 资源使用 +- **内存占用**: ~32MB (运行时) +- **CPU占用**: < 0.1 (空闲时) +- **启动时间**: ~2秒 +- **镜像大小**: ~30MB + +### 🔍 监控和日志 + +#### 查看容器状态 +```bash +# 查看容器状态 +docker ps | grep moodist + +# 查看健康检查状态 +docker inspect moodist | grep Health -A 10 + +# 查看资源使用 +docker stats moodist +``` + +#### 日志管理 +```bash +# 查看实时日志 +docker logs -f moodist + +# 查看最近日志 +docker logs --tail 100 moodist + +# 日志轮转(在 docker-compose 中配置) +logging: + options: + max-size: "10m" + max-file: "3" +``` + +### 🛠️ 故障排除 + +#### 常见问题 + +1. **容器无法启动** + ```bash + # 检查端口占用 + netstat -tlnp | grep 8080 + + # 查看容器日志 + docker logs moodist + ``` + +2. **健康检查失败** + ```bash + # 手动检查应用是否响应 + curl -f http://localhost:8080/ + + # 查看健康检查状态 + docker inspect moodist | grep Health + ``` + +3. **构建失败** + ```bash + # 清理Docker缓存 + docker system prune -a + + # 重新构建 + docker build --no-cache -f Dockerfile.optimized -t moodist:test . + ``` + +### 🔄 更新部署 + +#### 滚动更新 +```bash +# 拉取新版本 +docker pull wheeysys/moodist:latest + +# 停止旧容器 +docker stop moodist + +# 启动新容器 +docker run -d \ + --name moodist \ + -p 8080:8080 \ + --restart unless-stopped \ + wheeysys/moodist:latest + +# 删除旧容器 +docker rm $(docker ps -aq --filter "status=exited") +``` + +#### 使用 Docker Compose 更新 +```bash +# 拉取新镜像 +docker-compose -f docker-compose.optimized.yml pull + +# 重启服务 +docker-compose -f docker-compose.optimized.yml up -d + +# 清理旧镜像 +docker image prune -f +``` + +### 🔐 安全配置 + +#### 生产环境安全建议 +```yaml +services: + moodist: + image: wheeysys/moodist:latest + security_opt: + - no-new-privileges:true + read_only: true + tmpfs: + - /var/cache/nginx + - /var/run + user: "nginx" + cap_drop: + - ALL + cap_add: + - CHOWN + - SETGID + - SETUID +``` + +### 📈 扩展部署 + +#### 使用反向代理 +```nginx +server { + listen 80; + server_name moodist.example.com; + + location / { + proxy_pass http://localhost:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +#### 负载均衡配置 +```yaml +version: '3.8' +services: + moodist: + image: wheeysys/moodist:latest + deploy: + replicas: 3 + # ... 其他配置 +``` + +### 📞 支持 + +- **GitHub**: https://github.com/wheesys/moodist +- **Docker Hub**: https://hub.docker.com/r/walllee/moodist +- **问题反馈**: 请在 GitHub Issues 中提交 + +--- + +*最后更新: 2024-11-16* \ No newline at end of file diff --git a/Dockerfile.multiplatform b/Dockerfile.multiplatform new file mode 100644 index 0000000..b3384b4 --- /dev/null +++ b/Dockerfile.multiplatform @@ -0,0 +1,83 @@ +# 多平台构建 Dockerfile +# 使用: docker buildx build --platform linux/amd64,linux/arm64 -f Dockerfile.multiplatform -t wheesys/moodist:latest --push . + +# 使用官方Node.js镜像作为构建环境 +FROM --platform=linux/amd64,linux/arm64 node:20-alpine AS base + +# 安装必要的系统依赖 +RUN apk add --no-cache libc6-compat + +WORKDIR /app + +# 复制package文件 +COPY package*.json ./ + +# 安装依赖(使用npm ci进行更快、更可靠的安装) +RUN npm ci --only=production && npm cache clean --force + +# 构建阶段 +FROM base AS builder +COPY . . + +# 设置构建环境变量 +ARG NODE_ENV=production +ARG BUILD_DATE +ARG VERSION +ARG VCS_REF + +ENV NODE_ENV=$NODE_ENV +ENV BUILD_DATE=$BUILD_DATE +ENV VERSION=$VERSION +ENV VCS_REF=$VCS_REF + +# 构建应用 +RUN npm run build + +# 生产运行阶段 - 使用轻量级Nginx +FROM nginx:alpine AS runtime + +# 安装curl用于健康检查 +RUN apk add --no-cache curl + +# 创建非root用户提高安全性 +RUN addgroup -g 1001 -S nginx && \ + adduser -S nginx -u 1001 -G nginx + +# 复制自定义nginx配置 +COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf + +# 从构建阶段复制构建产物 +COPY --from=builder /app/dist /usr/share/nginx/html + +# 设置正确的权限 +RUN chown -R nginx:nginx /usr/share/nginx/html && \ + chown -R nginx:nginx /var/cache/nginx && \ + chown -R nginx:nginx /var/log/nginx && \ + chown -R nginx:nginx /etc/nginx/conf.d + +# 创建nginx运行时需要的目录 +RUN touch /var/run/nginx.pid && \ + chown -R nginx:nginx /var/run/nginx.pid + +# 切换到非root用户 +USER nginx + +# 暴露端口 +EXPOSE 8080 + +# 健康检查 +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8080/ || exit 1 + +# 启动nginx +CMD ["nginx", "-g", "daemon off;"] + +# 添加标签信息 +LABEL maintainer="walllee" \ + org.opencontainers.image.title="Moodist" \ + org.opencontainers.image.description="Ambient sounds for focus and calm - 多语言环境音应用" \ + org.opencontainers.image.version=$VERSION \ + org.opencontainers.image.created=$BUILD_DATE \ + org.opencontainers.image.revision=$VCS_REF \ + org.opencontainers.image.source="https://github.com/wheesys/moodist" \ + org.opencontainers.image.licenses="MIT" \ No newline at end of file diff --git a/Dockerfile.optimized b/Dockerfile.optimized new file mode 100644 index 0000000..b655251 --- /dev/null +++ b/Dockerfile.optimized @@ -0,0 +1,89 @@ +# 使用官方Node.js镜像作为构建环境 +FROM node:20-alpine AS base + +# 安装必要的系统依赖 +RUN apk add --no-cache libc6-compat + +WORKDIR /app + +# 复制package文件 +COPY package*.json ./ + +# 构建阶段 +FROM node:20-alpine AS builder + +WORKDIR /app + +# 复制package文件 +COPY package*.json ./ + +# 设置构建环境变量 +ARG NODE_ENV=production +ARG BUILD_DATE +ARG VERSION +ARG VCS_REF + +ENV NODE_ENV=$NODE_ENV +ENV BUILD_DATE=$BUILD_DATE +ENV VERSION=$VERSION +ENV VCS_REF=$VCS_REF + +# 安装所有依赖(构建需要所有依赖,包括devDependencies) +RUN npm ci --ignore-scripts && \ + npm install --save-dev autoprefixer postcss postcss-nesting && \ + npm cache clean --force + +# 复制源代码 +COPY . . + +# 构建应用 +RUN npm run build + +# 生产运行阶段 - 使用轻量级Nginx +FROM nginx:alpine AS runtime + +# 安装curl用于健康检查 +RUN apk add --no-cache curl + +# 创建非root用户提高安全性 +RUN addgroup -g 1001 -S nginx && \ + adduser -S nginx -u 1001 -G nginx + +# 复制自定义nginx配置 +COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf + +# 从构建阶段复制构建产物 +COPY --from=builder /app/dist /usr/share/nginx/html + +# 设置正确的权限 +RUN chown -R nginx:nginx /usr/share/nginx/html && \ + chown -R nginx:nginx /var/cache/nginx && \ + chown -R nginx:nginx /var/log/nginx && \ + chown -R nginx:nginx /etc/nginx/conf.d + +# 创建nginx运行时需要的目录 +RUN touch /var/run/nginx.pid && \ + chown -R nginx:nginx /var/run/nginx.pid + +# 切换到非root用户 +USER nginx + +# 暴露端口 +EXPOSE 8080 + +# 健康检查 +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8080/ || exit 1 + +# 启动nginx +CMD ["nginx", "-g", "daemon off;"] + +# 添加标签信息 +LABEL maintainer="walllee" \ + org.opencontainers.image.title="Moodist" \ + org.opencontainers.image.description="Ambient sounds for focus and calm - 多语言环境音应用" \ + org.opencontainers.image.version=$VERSION \ + org.opencontainers.image.created=$BUILD_DATE \ + org.opencontainers.image.revision=$VCS_REF \ + org.opencontainers.image.source="https://github.com/wheesys/moodist" \ + org.opencontainers.image.licenses="MIT" \ No newline at end of file diff --git a/Dockerfile.simple b/Dockerfile.simple new file mode 100644 index 0000000..560ae4e --- /dev/null +++ b/Dockerfile.simple @@ -0,0 +1,44 @@ +# 简化的Dockerfile - 使用本地构建产物 +FROM nginx:alpine + +# 安装curl用于健康检查 +RUN apk add --no-cache curl + +# 复制自定义nginx配置 +COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf + +# 复制本地构建的静态文件 +COPY dist/ /usr/share/nginx/html + +# 设置正确的权限 +RUN chown -R nginx:nginx /usr/share/nginx/html && \ + chown -R nginx:nginx /var/cache/nginx && \ + chown -R nginx:nginx /var/log/nginx && \ + chown -R nginx:nginx /etc/nginx/conf.d + +# 创建nginx运行时需要的目录 +RUN touch /var/run/nginx.pid && \ + chown -R nginx:nginx /var/run/nginx.pid + +# 切换到非root用户 +USER nginx + +# 暴露端口 +EXPOSE 8080 + +# 健康检查 +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8080/ || exit 1 + +# 启动nginx +CMD ["nginx", "-g", "daemon off;"] + +# 添加标签信息 +LABEL maintainer="walllee" \ + org.opencontainers.image.title="Moodist" \ + org.opencontainers.image.description="Ambient sounds for focus and calm - 多语言环境音应用" \ + org.opencontainers.image.version="2.1.0" \ + org.opencontainers.image.created="2025-11-16T06:53:40Z" \ + org.opencontainers.image.revision="65958f8" \ + org.opencontainers.image.source="https://github.com/wheesys/moodist" \ + org.opencontainers.image.licenses="MIT" \ No newline at end of file diff --git a/README.md b/README.md index a875755..9f11f04 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +## 🌍 Language / 语言 + +**[English](README.md)** | **[简体中文](README.zh-CN.md)** + +--- +
Moodist Logo Banner

Moodist 🌲

diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..c7b3f37 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,168 @@ +## 🌍 Language / 语言 + +**[English](README.md)** | **[简体中文](README.zh-CN.md)** + +--- + +
+ Moodist Logo Banner +

Moodist 🌲

+

环境音生成器 - 专注与平静的声音伴侣。

+ 访问 Moodist | 请我喝杯咖啡 +
+ +## 目录 + +- ⚡ [功能特性](#功能特性) +- 🚀 [快速开始](#快速开始) +- 🐳 [Docker 部署](#docker-部署) +- 🧰 [技术工具](#技术工具) +- 🔮 [命令说明](#命令说明) +- 🚧 [贡献指南](#贡献指南) +- ⭐ [支持项目](#支持-moodist) +- 📜 [许可证](#许可证) + +## 功能特性 + +1. 🎵 超过 75 种环境音 +1. 📝 持久化的声音选择 +1. ✈️ 与他人分享声音选择 +1. 🧰 自定义声音预设 +1. 🌙 睡眠定时器 +1. 📓 快速记事本 +1. 🍅 番茄钟计时器 +1. ✅ 简单的待办事项列表(即将推出) +1. ⏯️ 媒体控制 +1. ⌨️ 全功能键盘快捷键 +1. 🥷 注重隐私:不收集任何数据 +1. 💰 完全免费、开源、可自托管 + +## 🚀 快速开始 + +### 本地开发 + +```bash +# 克隆项目 +git clone https://github.com/wheesys/moodist.git +cd moodist + +# 安装依赖 +npm install + +# 启动开发服务器 +npm run dev +``` + +访问 [http://localhost:4321](http://localhost:4321) 查看应用。 + +### 构建生产版本 + +```bash +# 构建应用 +npm run build + +# 预览构建结果 +npm run preview +``` + +## 🐳 Docker 部署 + +### 直接运行 + +```bash +# 拉取镜像 +docker pull walllee/moodist:latest + +# 运行容器 +docker run -d \ + --name moodist \ + -p 8080:8080 \ + --restart unless-stopped \ + walllee/moodist:latest +``` + +### 使用 Docker Compose + +```bash +# 简单版本 +docker-compose up -d + +# 或使用优化版本 +docker-compose -f docker-compose.optimized.yml up -d +``` + +访问 [http://localhost:8080](http://localhost:8080) 查看应用。 + +### 自定义构建 + +```bash +# 构建镜像 +npm run docker:push + +# 带版本号构建 +./scripts/build-docker-simple.sh 2.1.0 + +# 构建并推送到 Docker Hub +npm run docker:push-and-upload +``` + +📖 详细部署指南请查看 [DOCKER_DEPLOY.md](DOCKER_DEPLOY.md) + +## 技术工具 + +- ⚡ **TypeScript**: 编程语言 +- 🔨 **React**: UI 库 +- 🧑‍🚀 **Astro**: 元框架 +- 🎨 **CSS Modules**: 样式方案 +- 🐻 **Zustand**: 状态管理 +- 🎭 **Framer Motion**: 动画库 +- ⚙️ **Radix**: 无障碍组件 +- 📕 **Storybook**: 组件文档 +- 🧪 **Vitest**: 单元测试(即将推出) +- 🔭 **Playwright**: 端到端测试(即将推出) +- 🔍 **ESLint**: 代码检查 +- 🧹 **Prettier**: 代码格式化 +- 🧼 **Stylelint**: CSS 检查 +- 🐶 **Husky**: Git 钩子 +- 📝 **Lint Staged**: 暂存文件检查器 +- 🧽 **Commitlint**: Git 提交信息检查 +- 🧭 **Commitizen**: Git 提交信息助手 +- 📓 **Standard Version**: 版本管理和更新日志生成 +- 🧰 **PostCSS**: CSS 转换 + +## 命令说明 + +- `npm run dev`: 运行开发服务器 +- `npm run build`: 构建生产版本 +- `npm run preview`: 预览构建的应用 +- `npm run lint`: 使用 ESLint 检查代码 +- `npm run lint:fix`: 使用 ESLint 检查并修复代码 +- `npm run lint:style`: 使用 Stylelint 检查样式 +- `npm run lint:style:fix`: 使用 Stylelint 检查并修复样式 +- `npm run format`: 使用 Prettier 格式化文件 +- `npm run commit`: 使用 Commitizen 提交代码 +- `npm run release:major`: 发布主版本 +- `npm run release:minor`: 发布次版本 +- `npm run release:patch`: 发布补丁版本 +- `npm run storybook`: 运行 Storybook + +## 贡献指南 + +🚧 请查看 [CONTRIBUTING.md](CONTRIBUTING.md) 文件。 + +## 支持 Moodist + +⭐ 如果您喜欢这个项目,请给它一个星标。 + +☕ [请我喝杯咖啡](https://buymeacoffee.com/remvze) 来帮助我维护 Moodist。 + +## 许可证 + +本项目基于 **MIT 许可证** - 详情请查看 [LICENSE](LICENSE) 文件。 + +### ⚠️ 第三方资源 + +本项目使用的部分声音来源于第三方提供商,并**遵循不同的许可证**: + +- 遵循 **Pixabay 内容许可证** 的声音:[Pixabay 内容许可证](https://pixabay.com/service/license-summary/) +- 遵循 **CC0** 的声音:[知识共享署名许可协议](https://creativecommons.org/publicdomain/zero/1.0/) \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..441d656 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,88 @@ +version: '3.8' + +services: + moodist-dev: + # 构建上下文 + build: + context: . + dockerfile: Dockerfile.optimized + target: builder # 只构建到builder阶段用于开发 + args: + - NODE_ENV=development + - BUILD_DATE=${BUILD_DATE:-$(date -u +'%Y-%m-%dT%H:%M:%SZ')} + - VERSION=dev + - VCS_REF=${VCS_REF:-dev} + + container_name: moodist-dev + restart: unless-stopped + + # 开发端口映射 + ports: + - "3000:3000" # Astro开发服务器 + - "8080:8080" # 预览服务器 + + # 开发环境变量 + environment: + - NODE_ENV=development + - TZ=Asia/Shanghai + + # 卷挂载用于开发 + volumes: + - .:/app + - /app/node_modules # 防止node_modules被覆盖 + - moodist-dist:/app/dist + + # 工作目录 + working_dir: /app + + # 开发命令 + command: npm run dev + + # 健康检查 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + # 开发资源配置 + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + cpus: '0.25' + memory: 128M + + # 日志配置 + logging: + driver: "json-file" + options: + max-size: "5m" + max-file: "2" + + networks: + - moodist-network + + # 开发工具容器 + dev-tools: + image: node:20-alpine + container_name: moodist-dev-tools + working_dir: /app + volumes: + - .:/app + networks: + - moodist-network + profiles: + - tools + command: sh -c "npm install && tail -f /dev/null" + +volumes: + moodist-dist: + driver: local + +networks: + moodist-network: + driver: bridge \ No newline at end of file diff --git a/docker-compose.optimized.yml b/docker-compose.optimized.yml new file mode 100644 index 0000000..314946b --- /dev/null +++ b/docker-compose.optimized.yml @@ -0,0 +1,84 @@ +version: '3.8' + +services: + moodist: + # 使用优化的镜像名称 + image: walllee/moodist:latest + container_name: moodist-app + + # 重启策略 + restart: unless-stopped + + # 端口映射 + ports: + - "8080:8080" + + # 环境变量 + environment: + - NODE_ENV=production + - TZ=Asia/Shanghai + + # 健康检查 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # 资源限制 + deploy: + resources: + limits: + cpus: '0.5' + memory: 128M + reservations: + cpus: '0.1' + memory: 32M + + # 日志配置 + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + # 网络配置 + networks: + - moodist-network + + # 安全选项 + security_opt: + - no-new-privileges:true + + # 只读根文件系统 + read_only: true + tmpfs: + - /var/cache/nginx + - /var/run + - /var/log/nginx + + # Nginx反向代理(可选) + nginx-proxy: + image: nginx:alpine + container_name: moodist-nginx + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - ./docker/nginx-proxy/nginx.conf:/etc/nginx/nginx.conf:ro + - ./docker/nginx-proxy/ssl:/etc/nginx/ssl:ro + depends_on: + - moodist + networks: + - moodist-network + profiles: + - proxy + +networks: + moodist-network: + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 8ef1cf0..d389090 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.9' services: moodist: - image: ghcr.io/remvze/moodist + image: walllee/moodist:latest logging: options: max-size: 1g diff --git a/package.json b/package.json index fbe6c63..f948311 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,14 @@ "release:minor": "npm run release -- --release-as minor", "release:patch": "npm run release -- --release-as patch", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "docker:build": "./scripts/build-local.sh", + "docker:push": "./scripts/build-docker-simple.sh", + "docker:push-and-upload": "./scripts/build-docker-simple.sh latest push", + "docker:multi": "./scripts/build-docker-compatible.sh", + "docker:dev": "docker-compose -f docker-compose.dev.yml up -d", + "docker:prod": "docker-compose -f docker-compose.optimized.yml up -d", + "docker:logs": "docker-compose -f docker-compose.optimized.yml logs -f" }, "dependencies": { "@astrojs/react": "3.6.0", diff --git a/scripts/build-docker-compatible.sh b/scripts/build-docker-compatible.sh new file mode 100755 index 0000000..133c54e --- /dev/null +++ b/scripts/build-docker-compatible.sh @@ -0,0 +1,152 @@ +#!/bin/bash + +# Moodist Docker 构建脚本 - 兼容版本 +# 支持标准Docker和Docker Buildx(可选) + +set -e + +# 配置变量 +IMAGE_NAME="walllee/moodist" +VERSION=${1:-latest} +BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') +VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") +USE_BUILDX=${2:-false} + +echo "🐳 开始构建 Moodist Docker 镜像..." +echo "📦 镜像名称: ${IMAGE_NAME}" +echo "🏷️ 版本标签: ${VERSION}" +echo "📅 构建时间: ${BUILD_DATE}" +echo "🔗 Git提交: ${VCS_REF}" +echo "🔧 使用Buildx: ${USE_BUILDX}" + +# 检查Docker是否安装并运行 +if ! docker info &> /dev/null; then + echo "❌ Docker未运行,请启动Docker服务" + exit 1 +fi + +# 构建参数 +BUILD_ARGS="--build-arg BUILD_DATE=${BUILD_DATE}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VERSION=${VERSION}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VCS_REF=${VCS_REF}" +BUILD_ARGS="${BUILD_ARGS} --build-arg NODE_ENV=production" + +# 构建函数 +build_image() { + local tag=$1 + local push_flag=$2 + local build_cmd="docker build" + + if [ "$USE_BUILDX" = "true" ]; then + # 检查buildx是否可用 + if docker buildx version &> /dev/null; then + echo "🔨 使用Docker Buildx构建..." + build_cmd="docker buildx build" + + # 创建buildx构建器(如果不存在) + if ! docker buildx ls | grep -q "moodist-builder"; then + echo "🔨 创建Docker Buildx构建器..." + docker buildx create --name moodist-builder --use 2>/dev/null || true + docker buildx inspect --bootstrap 2>/dev/null || true + fi + + # 多平台构建参数 + PLATFORM_ARGS="--platform linux/amd64,linux/arm64" + PUSH_FLAG="--push" + else + echo "⚠️ Docker Buildx不可用,回退到标准Docker构建..." + USE_BUILDX="false" + fi + fi + + echo "🏗️ 开始构建镜像: ${tag}" + + if [ "$USE_BUILDX" = "true" ]; then + # 使用buildx + $build_cmd \ + $PLATFORM_ARGS \ + --tag "${tag}" \ + $BUILD_ARGS \ + --file ./Dockerfile.optimized \ + $PUSH_FLAG \ + . + else + # 使用标准Docker + $build_cmd \ + --tag "${tag}" \ + $BUILD_ARGS \ + --file ./Dockerfile.optimized \ + . + + # 如果需要推送,使用标准Docker push + if [ "$push_flag" = "true" ]; then + echo "📤 推送镜像: ${tag}" + docker push "${tag}" + fi + fi +} + +# 检查是否需要登录Docker Hub +if [ "$USE_BUILDX" = "true" ] || [ "${2}" = "push" ]; then + if ! docker info 2>/dev/null | grep -q "Username"; then + echo "⚠️ 未检测到Docker登录,请先运行: docker login" + echo "💡 如果您有Docker Hub账号,请使用以下命令登录:" + echo " docker login" + read -p "是否继续构建?(y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "❌ 构建已取消" + exit 1 + fi + fi +fi + +# 构建镜像 +if [ "$USE_BUILDX" = "true" ]; then + # Buildx模式(支持多平台) + build_image "${IMAGE_NAME}:${VERSION}" true + + # 如果指定了特定版本,同时创建version-specific标签 + if [ "$VERSION" != "latest" ]; then + echo "🏷️ 添加版本标签: ${VERSION}" + build_image "${IMAGE_NAME}:${VERSION}" true + fi +else + # 标准Docker模式 + build_image "${IMAGE_NAME}:${VERSION}" false + + # 如果指定了特定版本,创建额外的标签 + if [ "$VERSION" != "latest" ]; then + docker tag "${IMAGE_NAME}:${VERSION}" "${IMAGE_NAME}:latest" + fi + + # 如果需要推送 + if [ "${2}" = "push" ]; then + echo "📤 推送镜像到Docker Hub..." + docker push "${IMAGE_NAME}:${VERSION}" + + if [ "$VERSION" != "latest" ]; then + docker push "${IMAGE_NAME}:latest" + fi + fi +fi + +echo "" +echo "🎉 镜像构建完成!" +echo "📋 镜像信息:" +echo " 🔗 镜像名称: ${IMAGE_NAME}" +echo " 🏷️ 标签: ${VERSION}${VERSION != "latest" ? ", latest" : ""}" +echo " 📅 构建时间: ${BUILD_DATE}" +echo " 🔗 Git提交: ${VCS_REF}" +echo "" +echo "🚀 使用方法:" +echo " docker run -d -p 8080:8080 ${IMAGE_NAME}:${VERSION}" +echo "" +echo "📝 查看镜像信息:" +echo " docker images | grep ${IMAGE_NAME}" +echo " docker inspect ${IMAGE_NAME}:${VERSION}" + +# 显示镜像大小 +echo "" +echo "📊 镜像大小:" +docker images ${IMAGE_NAME}:${VERSION} --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" \ No newline at end of file diff --git a/scripts/build-docker-simple.sh b/scripts/build-docker-simple.sh new file mode 100755 index 0000000..e69442a --- /dev/null +++ b/scripts/build-docker-simple.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +# Moodist Docker 简化构建脚本 +# 先本地构建,再打包成Docker镜像 + +set -e + +# 配置变量 +IMAGE_NAME="walllee/moodist" +VERSION=${1:-latest} +BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') +VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + +echo "🐳 开始构建 Moodist Docker 镜像(简化版)..." +echo "📦 镜像名称: ${IMAGE_NAME}" +echo "🏷️ 版本标签: ${VERSION}" +echo "📅 构建时间: ${BUILD_DATE}" +echo "🔗 Git提交: ${VCS_REF}" + +# 检查Docker是否安装并运行 +if ! docker info &> /dev/null; then + echo "❌ Docker未运行,请启动Docker服务" + exit 1 +fi + +# 步骤1: 本地构建 +echo "" +echo "📦 步骤 1: 本地构建应用..." +npm run build + +if [ $? -ne 0 ]; then + echo "❌ 本地构建失败" + exit 1 +fi + +echo "✅ 本地构建完成!" + +# 步骤2: 构建Docker镜像 +echo "" +echo "🐳 步骤 2: 构建 Docker镜像..." + +# 构建参数 +BUILD_ARGS="--build-arg BUILD_DATE=${BUILD_DATE}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VERSION=${VERSION}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VCS_REF=${VCS_REF}" + +# 构建镜像 +docker build \ + ${BUILD_ARGS} \ + --tag "${IMAGE_NAME}:${VERSION}" \ + --file ./Dockerfile.simple \ + . + +echo "✅ Docker镜像构建完成!" + +# 步骤3: 可选推送 +if [ "${2}" = "push" ]; then + echo "" + echo "📤 步骤 3: 推送镜像到Docker Hub..." + + # 检查是否登录Docker Hub + if ! docker info 2>/dev/null | grep -q "Username"; then + echo "⚠️ 未检测到Docker登录,请先运行: docker login" + read -p "是否继续推送?(y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "❌ 推送已取消" + exit 1 + fi + fi + + # 推送镜像 + docker push "${IMAGE_NAME}:${VERSION}" + + # 如果指定了特定版本,同时创建latest标签 + if [ "$VERSION" != "latest" ]; then + docker tag "${IMAGE_NAME}:${VERSION}" "${IMAGE_NAME}:latest" + docker push "${IMAGE_NAME}:latest" + fi + + echo "✅ 镜像推送完成!" +fi + +echo "" +echo "🎉 简化构建完成!" +echo "📋 镜像信息:" +echo " 🔗 镜像名称: ${IMAGE_NAME}" +if [ "$VERSION" != "latest" ]; then + echo " 🏷️ 标签: ${VERSION}, latest" +else + echo " 🏷️ 标签: ${VERSION}" +fi +echo " 📅 构建时间: ${BUILD_DATE}" +echo " 🔗 Git提交: ${VCS_REF}" +echo "" +echo "🚀 使用方法:" +echo " docker run -d -p 8080:8080 ${IMAGE_NAME}:${VERSION}" +echo "" +echo "📝 查看镜像信息:" +echo " docker images | grep ${IMAGE_NAME}" +echo " docker inspect ${IMAGE_NAME}:${VERSION}" + +# 显示镜像大小 +echo "" +echo "📊 镜像大小:" +docker images ${IMAGE_NAME}:${VERSION} --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" + +# 显示构建产物大小 +echo "" +echo "📦 构建产物大小:" +du -sh dist/ | tail -1 \ No newline at end of file diff --git a/scripts/build-docker.sh b/scripts/build-docker.sh new file mode 100755 index 0000000..38ad0ef --- /dev/null +++ b/scripts/build-docker.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Moodist Docker 构建和推送脚本 +# 支持多平台构建并推送到 Docker Hub + +set -e + +# 配置变量 +IMAGE_NAME="walllee/moodist" +VERSION=${1:-latest} +BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') +VCS_REF=$(git rev-parse --short HEAD) + +echo "🐳 开始构建 Moodist Docker 镜像..." +echo "📦 镜像名称: ${IMAGE_NAME}" +echo "🏷️ 版本标签: ${VERSION}" +echo "📅 构建时间: ${BUILD_DATE}" +echo "🔗 Git提交: ${VCS_REF}" + +# 检查Docker是否安装并运行 +if ! docker info &> /dev/null; then + echo "❌ Docker未运行,请启动Docker服务" + exit 1 +fi + +# 检查是否登录Docker Hub +if ! docker info | grep -q "Username"; then + echo "⚠️ 未检测到Docker登录,请先运行: docker login" + echo "💡 如果您有Docker Hub账号,请使用以下命令登录:" + echo " docker login" + echo " # 输入您的用户名和密码或访问令牌" + read -p "是否继续构建?(y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "❌ 构建已取消" + exit 1 + fi +fi + +# 创建buildx构建器(如果不存在) +if ! docker buildx ls | grep -q "moodist-builder"; then + echo "🔨 创建Docker Buildx构建器..." + docker buildx create --name moodist-builder --use + docker buildx inspect --bootstrap +fi + +# 构建参数 +BUILD_ARGS="--build-arg BUILD_DATE=${BUILD_DATE}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VERSION=${VERSION}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VCS_REF=${VCS_REF}" +BUILD_ARGS="${BUILD_ARGS} --build-arg NODE_ENV=production" + +echo "🏗️ 开始构建多平台镜像..." + +# 构建并推送多平台镜像 +docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag "${IMAGE_NAME}:${VERSION}" \ + --tag "${IMAGE_NAME}:latest" \ + ${BUILD_ARGS} \ + --file ./Dockerfile.optimized \ + --push \ + . + +echo "✅ 构建完成!" + +# 如果指定了特定版本,同时创建version-specific标签 +if [ "$VERSION" != "latest" ]; then + echo "🏷️ 添加版本标签: ${VERSION}" + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + --tag "${IMAGE_NAME}:${VERSION}" \ + ${BUILD_ARGS} \ + --file ./Dockerfile.optimized \ + --push \ + . +fi + +echo "" +echo "🎉 镜像构建和推送完成!" +echo "📋 镜像信息:" +echo " 🔗 Docker Hub: https://hub.docker.com/r/${IMAGE_NAME}" +echo " 🏷️ 标签: ${VERSION}, latest" +echo " 🏗️ 平台: linux/amd64, linux/arm64" +echo "" +echo "🚀 使用方法:" +echo " docker run -d -p 8080:8080 ${IMAGE_NAME}:${VERSION}" +echo "" +echo "📝 查看镜像信息:" +echo " docker pull ${IMAGE_NAME}:${VERSION}" +echo " docker inspect ${IMAGE_NAME}:${VERSION}" \ No newline at end of file diff --git a/scripts/build-local.sh b/scripts/build-local.sh new file mode 100755 index 0000000..c2d0450 --- /dev/null +++ b/scripts/build-local.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Moodist Docker 本地构建脚本 +# 用于本地测试和开发 + +set -e + +# 配置变量 +IMAGE_NAME="moodist-local" +VERSION=${1:-dev} +BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') +VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + +echo "🐳 开始本地构建 Moodist Docker 镜像..." +echo "📦 镜像名称: ${IMAGE_NAME}" +echo "🏷️ 版本标签: ${VERSION}" +echo "📅 构建时间: ${BUILD_DATE}" +echo "🔗 Git提交: ${VCS_REF}" + +# 检查Docker是否安装并运行 +if ! docker info &> /dev/null; then + echo "❌ Docker未运行,请启动Docker服务" + exit 1 +fi + +# 构建参数 +BUILD_ARGS="--build-arg BUILD_DATE=${BUILD_DATE}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VERSION=${VERSION}" +BUILD_ARGS="${BUILD_ARGS} --build-arg VCS_REF=${VCS_REF}" +BUILD_ARGS="${BUILD_ARGS} --build-arg NODE_ENV=production" + +echo "🏗️ 开始本地构建..." + +# 构建本地镜像 +docker build \ + ${BUILD_ARGS} \ + --tag "${IMAGE_NAME}:${VERSION}" \ + --file ./Dockerfile.optimized \ + . + +echo "✅ 本地构建完成!" + +# 运行容器进行测试 +echo "🧪 启动测试容器..." + +# 停止并删除现有容器(如果存在) +docker stop moodist-test 2>/dev/null || true +docker rm moodist-test 2>/dev/null || true + +# 启动新容器 +docker run -d \ + --name moodist-test \ + -p 8081:8080 \ + --restart unless-stopped \ + "${IMAGE_NAME}:${VERSION}" + +echo "🚀 测试容器已启动!" +echo "" +echo "📋 访问信息:" +echo " 🌐 本地访问: http://localhost:8081" +echo " 🐳 容器名称: moodist-test" +echo " 🏷️ 镜像标签: ${IMAGE_NAME}:${VERSION}" +echo "" +echo "🔧 常用命令:" +echo " 查看日志: docker logs moodist-test" +echo " 停止容器: docker stop moodist-test" +echo " 删除容器: docker rm moodist-test" +echo " 进入容器: docker exec -it moodist-test /bin/sh" +echo "" +echo "⏳ 等待容器启动..." +sleep 5 + +# 健康检查 +echo "🔍 执行健康检查..." +if curl -f http://localhost:8081/ &> /dev/null; then + echo "✅ 健康检查通过!应用正常运行" +else + echo "⚠️ 健康检查失败,请查看容器日志" + echo " docker logs moodist-test" +fi + +echo "" +echo "🎉 本地构建和测试完成!" \ No newline at end of file