feat: 新增前端自动化部署
This commit is contained in:
1 parent
fb0121cced
commit
8741f019fa
5 files changed
+1574
-388
No files matched your search
@@ -0,0 +1,96 @@
|
||||
name: Deploy Frontend
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths:
|
||||
- 'frontend/**'
|
||||
- 'Dockerfile.frontend'
|
||||
- 'nginx.conf'
|
||||
- '.github/workflows/deploy_frontend.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
IMAGE_NAME: license-manager-frontend
|
||||
CONTAINER_NAME: license-manager-frontend
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
docker build -f Dockerfile.frontend -t ${{ env.IMAGE_NAME }}:latest .
|
||||
docker save ${{ env.IMAGE_NAME }}:latest > frontend-image.tar
|
||||
|
||||
- name: Copy files to server
|
||||
uses: appleboy/scp-action@v0.1.7
|
||||
with:
|
||||
host: ${{ secrets.HOST_1 }}
|
||||
username: root
|
||||
password: ${{ secrets.PASS_1 }}
|
||||
port: 22
|
||||
source: "frontend-image.tar"
|
||||
target: "/opt/license-manager/"
|
||||
|
||||
- name: Deploy to server
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
host: ${{ secrets.HOST_1 }}
|
||||
username: root
|
||||
password: ${{ secrets.PASS_1 }}
|
||||
port: 22
|
||||
script: |
|
||||
cd /opt/license-manager
|
||||
|
||||
# Stop and remove existing container
|
||||
docker stop ${{ env.CONTAINER_NAME }} || true
|
||||
docker rm ${{ env.CONTAINER_NAME }} || true
|
||||
|
||||
# Load new image
|
||||
docker load < frontend-image.tar
|
||||
|
||||
# Remove old image
|
||||
docker rmi ${{ env.IMAGE_NAME }}:old || true
|
||||
docker tag ${{ env.IMAGE_NAME }}:latest ${{ env.IMAGE_NAME }}:old || true
|
||||
|
||||
# Run new container
|
||||
docker run -d \
|
||||
--name ${{ env.CONTAINER_NAME }} \
|
||||
--restart unless-stopped \
|
||||
-p 18080:80 \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
${{ env.IMAGE_NAME }}:latest
|
||||
|
||||
# Clean up
|
||||
rm -f frontend-image.tar
|
||||
docker image prune -f
|
||||
|
||||
# Check deployment status
|
||||
sleep 5
|
||||
if docker ps | grep -q ${{ env.CONTAINER_NAME }}; then
|
||||
echo "✅ Frontend deployment successful! Container is running."
|
||||
docker logs --tail 10 ${{ env.CONTAINER_NAME }}
|
||||
else
|
||||
echo "❌ Frontend deployment failed! Container is not running."
|
||||
docker logs ${{ env.CONTAINER_NAME }}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Health check
|
||||
run: |
|
||||
sleep 10
|
||||
response=$(curl -s -o /dev/null -w "%{http_code}" http://${{ secrets.HOST_1 }}:18080/ || echo "000")
|
||||
if [ "$response" = "200" ]; then
|
||||
echo "✅ Frontend health check passed! Service is responding."
|
||||
else
|
||||
echo "⚠️ Frontend health check returned status: $response"
|
||||
echo "Service may still be starting up..."
|
||||
fi
|
||||
@@ -0,0 +1,65 @@
|
||||
# 前端自动化部署
|
||||
|
||||
基于Docker的前端自动化部署方案,使用GitHub Actions实现CI/CD。
|
||||
|
||||
## 部署特点
|
||||
|
||||
- 🐳 Docker容器化部署
|
||||
- 🚀 自动构建和部署
|
||||
- 🔄 零停机更新
|
||||
- 🌐 内置Nginx服务器
|
||||
- 📱 支持Vue Router history模式
|
||||
- 🔗 API代理到后端服务
|
||||
|
||||
## 配置要求
|
||||
|
||||
### GitHub Secrets
|
||||
在GitHub仓库设置以下Secrets:
|
||||
- `HOST_1`: 服务器IP地址
|
||||
- `PASS_1`: 服务器root密码
|
||||
|
||||
### 服务器要求
|
||||
- 安装Docker
|
||||
|
||||
## 部署流程
|
||||
|
||||
1. 推送代码到main分支(前端相关文件有变更时)
|
||||
2. GitHub Actions自动触发
|
||||
3. 构建Docker镜像(Vue3 + Nginx)
|
||||
4. 上传镜像到服务器
|
||||
5. 停止旧容器并启动新容器
|
||||
6. 健康检查
|
||||
|
||||
## 访问地址
|
||||
|
||||
部署完成后,前端服务将在以下地址提供:
|
||||
- **前端地址**: http://服务器IP:18080
|
||||
- **API代理**: 前端的 `/api/*` 请求会代理到后端 `http://localhost:18888/`
|
||||
|
||||
## 手动触发
|
||||
|
||||
可以在GitHub Actions页面手动触发部署,无需推送代码。
|
||||
|
||||
## 监控和维护
|
||||
|
||||
### 查看容器状态
|
||||
```bash
|
||||
docker ps | grep license-manager-frontend
|
||||
```
|
||||
|
||||
### 查看容器日志
|
||||
```bash
|
||||
docker logs license-manager-frontend
|
||||
```
|
||||
|
||||
### 重启容器
|
||||
```bash
|
||||
docker restart license-manager-frontend
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
1. **部署失败**: 检查GitHub Actions日志
|
||||
2. **容器无法启动**: 检查Docker镜像和容器配置
|
||||
3. **页面无法访问**: 检查服务器防火墙18080端口
|
||||
4. **API请求失败**: 确认后端服务运行在18888端口
|
||||
@@ -0,0 +1,30 @@
|
||||
# Multi-stage build for frontend
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY frontend/package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY frontend/ ./
|
||||
RUN npm run prod
|
||||
|
||||
# Production stage with Nginx
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy built assets
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Copy custom nginx configuration
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Create log directory
|
||||
RUN mkdir -p /var/log/nginx
|
||||
|
||||
# Expose port
|
||||
EXPOSE 80
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost/ || exit 1
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
Generated
+1319
-388
File diff suppressed because it is too large.
Load diff
+64
@@ -0,0 +1,64 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/json
|
||||
image/svg+xml;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
||||
|
||||
# Handle Vue Router history mode
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# API proxy to backend (if backend is on the same server)
|
||||
location /api/ {
|
||||
proxy_pass http://host.docker.internal:18888/;
|
||||
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;
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# Disable access to hidden files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# Custom error pages
|
||||
error_page 404 /index.html;
|
||||
error_page 500 502 503 504 /index.html;
|
||||
}
|
||||
Reference in new issue
Block a user