diff --git a/.gitea/workflows/aurask-release.yml b/.gitea/workflows/aurask-release.yml
new file mode 100644
index 0000000..473194e
--- /dev/null
+++ b/.gitea/workflows/aurask-release.yml
@@ -0,0 +1,90 @@
+name: aurask-release
+
+on:
+ push:
+ branches:
+ - master
+ paths:
+ - .gitea/workflows/aurask-release.yml
+ - deploy/images/aurask-api/**
+ - deploy/images/aurask-web/**
+ - deploy/k3s/base/**
+ - src/aurask/**
+ - tests/**
+ - pyproject.toml
+ - README.md
+ - AGENTS.md
+ - Aurask_Technical_Operations_Plan.md
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+env:
+ REGISTRY_HOST: registry.mydevcloud.love
+ REGISTRY_NAMESPACE: devcloud
+ DEPLOY_HOST: 64.90.15.15
+ DEPLOY_USER: root
+ AURASK_NAMESPACE: aurask
+
+jobs:
+ build-and-deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install job dependencies
+ run: |
+ apt-get update
+ DEBIAN_FRONTEND=noninteractive apt-get install -y docker.io openssh-client curl
+
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Run unit tests
+ env:
+ PYTHONPATH: src
+ run: |
+ python3 -m unittest discover -s tests -v
+
+ - name: Prepare SSH key
+ run: |
+ install -m 700 -d ~/.ssh
+ printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
+ chmod 600 ~/.ssh/id_ed25519
+ ssh-keyscan -H "${DEPLOY_HOST}" >> ~/.ssh/known_hosts
+
+ - name: Login private registry
+ run: |
+ echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${REGISTRY_HOST}" --username "${{ secrets.REGISTRY_USER }}" --password-stdin
+
+ - name: Build and push aurask-api image
+ run: |
+ api_image="${REGISTRY_HOST}/${REGISTRY_NAMESPACE}/aurask-api"
+ docker build -t "${api_image}:${GITHUB_SHA}" -t "${api_image}:latest" -f deploy/images/aurask-api/Dockerfile .
+ docker push "${api_image}:${GITHUB_SHA}"
+ docker push "${api_image}:latest"
+
+ - name: Build and push aurask-web image
+ run: |
+ web_image="${REGISTRY_HOST}/${REGISTRY_NAMESPACE}/aurask-web"
+ docker build -t "${web_image}:${GITHUB_SHA}" -t "${web_image}:latest" deploy/images/aurask-web
+ docker push "${web_image}:${GITHUB_SHA}"
+ docker push "${web_image}:latest"
+
+ - name: Deploy aurask base manifests
+ run: |
+ scp -i ~/.ssh/id_ed25519 -r deploy/k3s/base "${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/aurask-release"
+ ssh -i ~/.ssh/id_ed25519 "${DEPLOY_USER}@${DEPLOY_HOST}" "
+ set -euo pipefail
+ kubectl create namespace ${AURASK_NAMESPACE} --dry-run=client -o yaml | kubectl apply -f -
+ kubectl -n ${AURASK_NAMESPACE} create secret docker-registry devcloud-registry \
+ --docker-server=${REGISTRY_HOST} \
+ --docker-username='${{ secrets.REGISTRY_USER }}' \
+ --docker-password='${{ secrets.REGISTRY_PASSWORD }}' \
+ --dry-run=client -o yaml | kubectl apply -f -
+ kubectl apply -k /tmp/aurask-release
+ kubectl -n ${AURASK_NAMESPACE} set image deployment/aurask-api api=${REGISTRY_HOST}/${REGISTRY_NAMESPACE}/aurask-api:${GITHUB_SHA}
+ kubectl -n ${AURASK_NAMESPACE} set image deployment/aurask-web web=${REGISTRY_HOST}/${REGISTRY_NAMESPACE}/aurask-web:${GITHUB_SHA}
+ kubectl -n ${AURASK_NAMESPACE} rollout status deployment/aurask-api --timeout=600s
+ kubectl -n ${AURASK_NAMESPACE} rollout status deployment/aurask-web --timeout=600s
+ kubectl -n ${AURASK_NAMESPACE} get pods -o wide
+ "
diff --git a/deploy/images/aurask-api/Dockerfile b/deploy/images/aurask-api/Dockerfile
new file mode 100644
index 0000000..8a8559c
--- /dev/null
+++ b/deploy/images/aurask-api/Dockerfile
@@ -0,0 +1,21 @@
+FROM python:3.12-slim
+
+ENV PYTHONDONTWRITEBYTECODE=1 \
+ PYTHONUNBUFFERED=1 \
+ PYTHONPATH=/app/src
+
+WORKDIR /app
+
+RUN useradd --system --create-home --uid 10001 aurask
+
+COPY pyproject.toml README.md /app/
+COPY src /app/src
+
+RUN python -m compileall /app/src && \
+ install -d -o aurask -g aurask /data
+
+USER aurask
+
+EXPOSE 8080
+
+CMD ["python", "-m", "aurask", "serve", "--data", "/data/state.json", "--host", "0.0.0.0", "--port", "8080"]
diff --git a/deploy/images/aurask-web/Dockerfile b/deploy/images/aurask-web/Dockerfile
new file mode 100644
index 0000000..133ed7d
--- /dev/null
+++ b/deploy/images/aurask-web/Dockerfile
@@ -0,0 +1,3 @@
+FROM caddy:2-alpine
+
+COPY index.html /usr/share/caddy/index.html
diff --git a/deploy/images/aurask-web/index.html b/deploy/images/aurask-web/index.html
new file mode 100644
index 0000000..055cd4a
--- /dev/null
+++ b/deploy/images/aurask-web/index.html
@@ -0,0 +1,138 @@
+
+
+
+
+
+ Aurask
+
+
+
+
+ Aurask
+ 当前站点提供 Aurask MVP 网关入口与部署说明页。生产可用接口位于同域名下的 /api 前缀。
+
+
+ 正在检查 API 健康状态...
+
+
+
+
+
+ Bootstrap
+ POST /api/demo/bootstrap
+
+
+
+ 鉴权接口使用 Authorization: Bearer <api_key>。当前前台页面为轻量入口页,后端能力直接来自 Aurask `master` 分支的 MVP 网关。
+
+
+
+
diff --git a/deploy/k3s/README.md b/deploy/k3s/README.md
index 9a383c2..9fb8a3f 100644
--- a/deploy/k3s/README.md
+++ b/deploy/k3s/README.md
@@ -1,4 +1,88 @@
-# Aurask `k3s` 部署计划(最新目录结构版)
+# Aurask `k3s` 部署方案(当前 DevCloud 部署与后续扩展)
+
+## 当前 DevCloud 落地方案
+
+当前 `master` 分支已经对接 DevCloud 的实际部署形态,先以 **Aurask MVP 网关 + 轻量前端入口页** 方式稳定上线,再逐步扩展为文档中规划的完整生产架构。
+
+### 当前已落地组件
+
+- `aurask-api`
+ - 镜像:`registry.mydevcloud.love/devcloud/aurask-api`
+ - 节点:`45.113.2.55`
+ - Kubernetes 节点名:`devcloud-trade-agent-1`
+ - Service:`NodePort 30091`
+- `aurask-web`
+ - 镜像:`registry.mydevcloud.love/devcloud/aurask-web`
+ - 节点:`154.193.250.23`
+ - Kubernetes 节点名:`devcloud-trade-agent-2`
+ - Service:`NodePort 30090`
+- `aurask` 命名空间
+- `aurask-api-state` PVC
+ - `StorageClass`: `local-path`
+ - 用于保存 MVP JSON 状态文件
+
+### 当前公网入口
+
+- 域名:`https://aurask.xyz`
+- 路由方式:
+ - `/` -> `aurask-web`
+ - `/api/*` -> `aurask-api`
+- 边界入口通过前端节点宿主机 `Caddy` 转发:
+ - `154.193.250.23:443` -> `NodePort 30090 / 30091`
+
+### 当前未纳入首版自动部署的组件
+
+以下内容仍属于后续扩展计划,**当前 `master` 分支自动发布不会部署**:
+
+- PostgreSQL
+- `PGVector` / 独立向量数据库
+- Redis
+- `aurask-worker`
+- Langflow Runtime
+- AnythingLLM
+- Observability / Longhorn / CNPG
+
+### 自动发布流水线
+
+仓库内置 Gitea Actions 工作流:
+
+- 文件:`.gitea/workflows/aurask-release.yml`
+- 触发条件:`master` 分支 push
+- 动作:
+ - 运行单元测试
+ - 构建 `aurask-api` 镜像
+ - 构建 `aurask-web` 镜像
+ - 推送镜像到私有仓库
+ - 通过 SSH 连接 `64.90.15.15`
+ - `kubectl apply -k deploy/k3s/base`
+ - 自动更新 `aurask-api` 与 `aurask-web` 镜像到当前 commit SHA
+
+### 仓库所需 Gitea Actions Secrets
+
+- `SSH_PRIVATE_KEY`
+- `REGISTRY_USER`
+- `REGISTRY_PASSWORD`
+
+### 当前仓库内的部署资产位置
+
+```text
+deploy/
+ images/
+ aurask-api/
+ Dockerfile
+ aurask-web/
+ Dockerfile
+ index.html
+ k3s/
+ base/
+ namespace.yaml
+ aurask-api-pvc.yaml
+ aurask-api.yaml
+ aurask-web.yaml
+ kustomization.yaml
+```
+
+## 目标扩展方案(300 名月度活跃用户)
本部署计划基于当前仓库结构更新:
diff --git a/deploy/k3s/base/aurask-api-pvc.yaml b/deploy/k3s/base/aurask-api-pvc.yaml
new file mode 100644
index 0000000..0eaa56e
--- /dev/null
+++ b/deploy/k3s/base/aurask-api-pvc.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: aurask-api-state
+ namespace: aurask
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 5Gi
+ storageClassName: local-path
diff --git a/deploy/k3s/base/aurask-api.yaml b/deploy/k3s/base/aurask-api.yaml
new file mode 100644
index 0000000..e156644
--- /dev/null
+++ b/deploy/k3s/base/aurask-api.yaml
@@ -0,0 +1,67 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: aurask-api
+ namespace: aurask
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: aurask-api
+ template:
+ metadata:
+ labels:
+ app: aurask-api
+ spec:
+ imagePullSecrets:
+ - name: devcloud-registry
+ nodeSelector:
+ kubernetes.io/hostname: devcloud-trade-agent-1
+ containers:
+ - name: api
+ image: registry.mydevcloud.love/devcloud/aurask-api:latest
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 8080
+ name: http
+ volumeMounts:
+ - name: aurask-api-state
+ mountPath: /data
+ readinessProbe:
+ httpGet:
+ path: /health
+ port: http
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ livenessProbe:
+ httpGet:
+ path: /health
+ port: http
+ initialDelaySeconds: 15
+ periodSeconds: 20
+ resources:
+ requests:
+ cpu: 250m
+ memory: 256Mi
+ limits:
+ cpu: "1"
+ memory: 1Gi
+ volumes:
+ - name: aurask-api-state
+ persistentVolumeClaim:
+ claimName: aurask-api-state
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: aurask-api
+ namespace: aurask
+spec:
+ type: NodePort
+ selector:
+ app: aurask-api
+ ports:
+ - name: http
+ port: 8080
+ targetPort: 8080
+ nodePort: 30091
diff --git a/deploy/k3s/base/aurask-web.yaml b/deploy/k3s/base/aurask-web.yaml
new file mode 100644
index 0000000..eb76f06
--- /dev/null
+++ b/deploy/k3s/base/aurask-web.yaml
@@ -0,0 +1,60 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: aurask-web
+ namespace: aurask
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: aurask-web
+ template:
+ metadata:
+ labels:
+ app: aurask-web
+ spec:
+ imagePullSecrets:
+ - name: devcloud-registry
+ nodeSelector:
+ kubernetes.io/hostname: devcloud-trade-agent-2
+ containers:
+ - name: web
+ image: registry.mydevcloud.love/devcloud/aurask-web:latest
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 80
+ name: http
+ readinessProbe:
+ httpGet:
+ path: /
+ port: http
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ livenessProbe:
+ httpGet:
+ path: /
+ port: http
+ initialDelaySeconds: 15
+ periodSeconds: 20
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
+ limits:
+ cpu: 500m
+ memory: 256Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: aurask-web
+ namespace: aurask
+spec:
+ type: NodePort
+ selector:
+ app: aurask-web
+ ports:
+ - name: http
+ port: 80
+ targetPort: 80
+ nodePort: 30090
diff --git a/deploy/k3s/base/kustomization.yaml b/deploy/k3s/base/kustomization.yaml
new file mode 100644
index 0000000..fd95a30
--- /dev/null
+++ b/deploy/k3s/base/kustomization.yaml
@@ -0,0 +1,7 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+ - namespace.yaml
+ - aurask-api-pvc.yaml
+ - aurask-api.yaml
+ - aurask-web.yaml
diff --git a/deploy/k3s/base/namespace.yaml b/deploy/k3s/base/namespace.yaml
new file mode 100644
index 0000000..7a01286
--- /dev/null
+++ b/deploy/k3s/base/namespace.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: aurask