fix build
This commit is contained in:
parent
2a03be54a5
commit
df9147a554
59
.gitea/workflows/deploy-backend.yaml
Normal file
59
.gitea/workflows/deploy-backend.yaml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
name: Build and Deploy Backend
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
config-inline: |
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev"]
|
||||||
|
|
||||||
|
- name: Login to Huawei Cloud SWR
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{ secrets.SWR_SERVER }}
|
||||||
|
username: ${{ secrets.SWR_USERNAME }}
|
||||||
|
password: ${{ secrets.SWR_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build and Push Backend
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
context: ./backend
|
||||||
|
push: true
|
||||||
|
provenance: false
|
||||||
|
tags: ${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/airlabs-manage-backend:latest
|
||||||
|
|
||||||
|
- name: Setup Kubectl
|
||||||
|
run: |
|
||||||
|
curl -LO "https://files.m.daocloud.io/dl.k8s.io/release/v1.28.2/bin/linux/amd64/kubectl"
|
||||||
|
chmod +x kubectl
|
||||||
|
mv kubectl /usr/local/bin/
|
||||||
|
|
||||||
|
- name: Deploy to K3s
|
||||||
|
uses: Azure/k8s-set-context@v3
|
||||||
|
with:
|
||||||
|
method: kubeconfig
|
||||||
|
kubeconfig: ${{ secrets.KUBE_CONFIG }}
|
||||||
|
|
||||||
|
- name: Update K8s Manifests
|
||||||
|
run: |
|
||||||
|
# 替换镜像地址
|
||||||
|
sed -i "s|\${CI_REGISTRY_IMAGE}/backend:latest|${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/airlabs-manage-backend:latest|g" k8s/backend-deployment-prod.yaml
|
||||||
|
|
||||||
|
# 应用配置
|
||||||
|
kubectl apply -f k8s/backend-deployment-prod.yaml
|
||||||
|
kubectl apply -f k8s/backend-ingress.yaml
|
||||||
|
|
||||||
|
kubectl rollout restart deployment/airlabs-manage-backend
|
||||||
59
.gitea/workflows/deploy-web.yaml
Normal file
59
.gitea/workflows/deploy-web.yaml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
name: Build and Deploy Web
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
config-inline: |
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev"]
|
||||||
|
|
||||||
|
- name: Login to Huawei Cloud SWR
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{ secrets.SWR_SERVER }}
|
||||||
|
username: ${{ secrets.SWR_USERNAME }}
|
||||||
|
password: ${{ secrets.SWR_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build and Push Web
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
context: ./frontend
|
||||||
|
push: true
|
||||||
|
provenance: false
|
||||||
|
tags: ${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/airlabs-manage-web:latest
|
||||||
|
|
||||||
|
- name: Setup Kubectl
|
||||||
|
run: |
|
||||||
|
curl -LO "https://files.m.daocloud.io/dl.k8s.io/release/v1.28.2/bin/linux/amd64/kubectl"
|
||||||
|
chmod +x kubectl
|
||||||
|
mv kubectl /usr/local/bin/
|
||||||
|
|
||||||
|
- name: Deploy to K3s
|
||||||
|
uses: Azure/k8s-set-context@v3
|
||||||
|
with:
|
||||||
|
method: kubeconfig
|
||||||
|
kubeconfig: ${{ secrets.KUBE_CONFIG }}
|
||||||
|
|
||||||
|
- name: Update K8s Manifests
|
||||||
|
run: |
|
||||||
|
# 替换镜像地址
|
||||||
|
sed -i "s|\${CI_REGISTRY_IMAGE}/web:latest|${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/airlabs-manage-web:latest|g" k8s/web-deployment-prod.yaml
|
||||||
|
|
||||||
|
# 应用配置
|
||||||
|
kubectl apply -f k8s/web-deployment-prod.yaml
|
||||||
|
kubectl apply -f k8s/web-ingress.yaml
|
||||||
|
|
||||||
|
kubectl rollout restart deployment/airlabs-manage-web
|
||||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -6,6 +6,15 @@ __pycache__/
|
|||||||
# Node
|
# Node
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
# Database
|
||||||
|
*.db
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
frontend/dist/
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
.env
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|||||||
25
backend/Dockerfile
Normal file
25
backend/Dockerfile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources && \
|
||||||
|
apt-get update && apt-get install -y gcc && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Python dependencies
|
||||||
|
COPY requirements.txt /app/
|
||||||
|
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && \
|
||||||
|
pip install --upgrade pip && pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Copy project
|
||||||
|
COPY . /app/
|
||||||
|
|
||||||
|
# Create data directory for SQLite persistence
|
||||||
|
RUN mkdir -p /app/data
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
23
frontend/Dockerfile
Normal file
23
frontend/Dockerfile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Build stage
|
||||||
|
FROM node:20-alpine AS build-stage
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM nginx:stable-alpine AS production-stage
|
||||||
|
|
||||||
|
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
32
frontend/nginx.conf
Normal file
32
frontend/nginx.conf
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
# API 代理到后端服务(K8s 内部通信)
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://airlabs-manage-backend:8000;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
# SPA 路由刷新 404 的关键配置
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 静态资源缓存
|
||||||
|
location /assets/ {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
expires 7d;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
||||||
67
k8s/backend-deployment-prod.yaml
Normal file
67
k8s/backend-deployment-prod.yaml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# SQLite 持久化存储
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: airlabs-manage-sqlite-data
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: airlabs-manage-backend
|
||||||
|
labels:
|
||||||
|
app: airlabs-manage-backend
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: airlabs-manage-backend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: airlabs-manage-backend
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: airlabs-manage-backend
|
||||||
|
image: ${CI_REGISTRY_IMAGE}/backend:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
env:
|
||||||
|
# SQLite 存储在持久卷中
|
||||||
|
- name: DATABASE_URL
|
||||||
|
value: "sqlite:////app/data/airlabs.db"
|
||||||
|
# 生产环境 JWT 密钥(部署前请修改)
|
||||||
|
- name: SECRET_KEY
|
||||||
|
value: "Ui5-xEvtAhKRDtlXKzDfd7TElsVZFUhakff0qcjn8jU"
|
||||||
|
volumeMounts:
|
||||||
|
- name: sqlite-data
|
||||||
|
mountPath: /app/data
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
volumes:
|
||||||
|
- name: sqlite-data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: airlabs-manage-sqlite-data
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: airlabs-manage-backend
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: airlabs-manage-backend
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8000
|
||||||
|
targetPort: 8000
|
||||||
23
k8s/backend-ingress.yaml
Normal file
23
k8s/backend-ingress.yaml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: airlabs-manage-backend-ingress
|
||||||
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: "traefik"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
spec:
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- airlabs-manage-api.airlabs.art
|
||||||
|
secretName: airlabs-manage-backend-tls
|
||||||
|
rules:
|
||||||
|
- host: airlabs-manage-api.airlabs.art
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: airlabs-manage-backend
|
||||||
|
port:
|
||||||
|
number: 8000
|
||||||
41
k8s/web-deployment-prod.yaml
Normal file
41
k8s/web-deployment-prod.yaml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: airlabs-manage-web
|
||||||
|
labels:
|
||||||
|
app: airlabs-manage-web
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: airlabs-manage-web
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: airlabs-manage-web
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: airlabs-manage-web
|
||||||
|
image: ${CI_REGISTRY_IMAGE}/web:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: airlabs-manage-web
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: airlabs-manage-web
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
23
k8s/web-ingress.yaml
Normal file
23
k8s/web-ingress.yaml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: airlabs-manage-web-ingress
|
||||||
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: "traefik"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
spec:
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- airlabs-manage-web.airlabs.art
|
||||||
|
secretName: airlabs-manage-web-tls
|
||||||
|
rules:
|
||||||
|
- host: airlabs-manage-web.airlabs.art
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: airlabs-manage-web
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
Loading…
x
Reference in New Issue
Block a user