# 使用 Node.js 官方镜像作为基础 FROM node:20-alpine AS builder WORKDIR /app # 复制项目文件 COPY . . # 安装依赖 RUN npm ci --omit=dev || npm install # 构建项目 RUN npm run build || echo "Build will run at runtime" # 运行阶段 FROM node:20-alpine WORKDIR /app # 安装 nginx 和运行时依赖 RUN apk add --no-cache nginx # 复制构建产物和源码 COPY --from=builder /app /app # 创建必要的目录 RUN mkdir -p /app/dist /app/config /app/bookmarks /run/nginx /var/log/nginx # 配置 nginx RUN cat > /etc/nginx/nginx.conf << 'EOF' pid /tmp/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /tmp/access.log; error_log /tmp/error.log; server { listen 7860; server_name localhost; root /app/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } } } EOF # 设置环境变量 ENV PORT=7860 ENV MENAV_PORT=7860 ENV MENAV_ENABLE_SYNC=false ENV MENAV_IMPORT_BOOKMARKS=false EXPOSE 7860 # 创建 entrypoint.sh RUN cat > /entrypoint.sh << 'EOF' #!/bin/sh set -e echo "[$(date)] Starting Menav..." if [ "$MENAV_IMPORT_BOOKMARKS" = "true" ] && [ -d /app/bookmarks ]; then echo "[$(date)] Importing bookmarks..." npm run import-bookmarks || echo "Import failed, continuing" fi if [ "$MENAV_ENABLE_SYNC" = "true" ]; then echo "[$(date)] Syncing data..." npm run sync-all || echo "Sync failed, continuing" fi echo "[$(date)] Building project..." npm run build echo "[$(date)] Starting nginx on port 7860..." nginx -c /etc/nginx/nginx.conf tail -f /dev/null EOF RUN chmod +x /entrypoint.sh CMD ["/entrypoint.sh"]