Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Dependencies
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Build outputs
dist
build

# Environment files
.env
.env.local
.env.*.local

# Configuration files (runtime generated)
public/config.json


# IDE and editor files
.vscode
.idea
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Git
.git
.gitignore

# Docker
Dockerfile
.dockerignore
docker-compose.yml

# Documentation
README.md
*.md

# Scripts
start.sh

# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Dependency directories
jspm_packages/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports = {
ecmaVersion: 2020,
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-console": "off",
"no-debugger": "off",
},
};
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ node_modules
.env.local
.env.*.local

# Configuration files (runtime generated)
public/config.json

# Log files
npm-debug.log*
yarn-debug.log*
Expand Down
56 changes: 56 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Multi-stage Dockerfile for DeliciousFoodMap-Web
# Stage 1: Build the Vue.js application
FROM node:18-alpine AS build-stage

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./
COPY pnpm-lock.yaml* ./

# Install dependencies
RUN npm install -g pnpm && pnpm install --frozen-lockfile

# Copy source code
COPY . .

# Build the application
RUN pnpm run build

# Stage 2: Production stage with Nginx
FROM nginx:1.25-alpine AS production-stage

# Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

# Copy built application from build stage
COPY --from=build-stage /app/dist /usr/share/nginx/html

# Copy nginx configuration
COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/default.conf /etc/nginx/conf.d/default.conf

# Copy config template for runtime substitution
COPY public/config.json.template /usr/share/nginx/html/config.json.template

# Copy startup script
COPY docker/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

# Set environment variables with defaults
ENV API_BASE_URL=http://localhost:8080
ENV AMAP_KEY=""

# Expose port
EXPOSE 80

EXPOSE 443



# Use custom entrypoint
ENTRYPOINT ["/docker-entrypoint.sh"]

# Start nginx
CMD ["nginx", "-g", "daemon off;"]
57 changes: 57 additions & 0 deletions dev-start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

# 本地开发环境启动脚本

set -e

echo "🍕 美食地图前端 - 本地开发环境"
echo "================================"

# 检查 Node.js
if ! command -v node &> /dev/null; then
echo "❌ Node.js 未安装,请先安装 Node.js (版本 14+)"
exit 1
fi

# 检查 npm
if ! command -v npm &> /dev/null; then
echo "❌ npm 未安装"
exit 1
fi

echo "✅ Node.js 版本: $(node --version)"
echo "✅ npm 版本: $(npm --version)"
echo ""

# 检查依赖
if [ ! -d "node_modules" ]; then
echo "📦 安装依赖..."
npm install
echo "✅ 依赖安装完成"
echo ""
fi

# 检查配置文件
if [ ! -f "public/config.json.local" ]; then
echo "⚙️ 创建本地配置文件..."
cp public/config.json public/config.json.local
echo "📝 请编辑 public/config.json.local 文件,设置正确的配置值:"
echo " - API_BASE_URL: 后端 API 地址"
echo " - AMAP_KEY: 高德地图 API 密钥"
echo ""
echo "配置文件位置: public/config.json.local"
echo ""
read -p "按回车键继续..."
fi

echo "🚀 启动开发服务器..."
echo "📍 应用将在 http://localhost:8080 启动"
echo "🔧 配置文件: public/config.json.local"
echo ""
echo "💡 提示:"
echo " - 修改代码后会自动热重载"
echo " - 按 Ctrl+C 停止服务器"
echo ""

# 启动开发服务器
npm run serve
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3.8'

services:
web:
build: .
container_name: delicious-food-map-web
ports:
- "80:80"
environment:
- API_BASE_URL=https://your-api-server.com
- AMAP_KEY=your_amap_key_here
restart: unless-stopped

96 changes: 96 additions & 0 deletions docker/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
index index.html;

# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

# Enable gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;

# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
}

# Cache config.json for a short time to allow updates
location = /config.json {
expires 5m;
add_header Cache-Control "public, max-age=300";
add_header Content-Type "application/json";
try_files $uri =404;
}

# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}

# Handle Vue.js routing (SPA)
location / {
try_files $uri $uri/ /index.html;

# Cache HTML files for a short time
location ~* \.html$ {
expires 5m;
add_header Cache-Control "public, max-age=300";
}
}

# Proxy API requests to backend (optional)
location /api/ {
# Remove this block if you're using absolute URLs for API calls
# proxy_pass http://backend: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;

# For now, return 404 for API calls (since we use absolute URLs)
return 404;
}

# Error pages
error_page 404 /index.html;
error_page 500 502 503 504 /50x.html;

location = /50x.html {
root /usr/share/nginx/html;
}

# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}

# Deny access to backup files
location ~ ~$ {
deny all;
access_log off;
log_not_found off;
}
}
Loading