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_modules/
|
||||
|
||||
# Database
|
||||
*.db
|
||||
|
||||
# Build output
|
||||
frontend/dist/
|
||||
|
||||
# Environment
|
||||
.env
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
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