jenkins
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
server {
|
||||
listen 8080;
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
#charset koi8-r;
|
||||
#access_log logs/host.access.log main;
|
||||
|
||||
# K8s 部署:proxy_pass 的服务名由 Jenkins envsubst '$KRA_APP' 渲染为 <APP_NAME>-backend,
|
||||
# 产物写至 web/nginx.k8s.conf(不入库)。本地手动构建 web 镜像前需先执行渲染。
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||
@@ -17,10 +16,10 @@ server {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
rewrite ^/api/(.*)$ /$1 break; #重写
|
||||
proxy_pass http://177.7.0.12:8888; # 设置代理服务器的协议和地址
|
||||
proxy_pass http://${KRA_APP}-backend:8000; # Kubernetes Service
|
||||
}
|
||||
|
||||
location /api/swagger/index.html {
|
||||
proxy_pass http://127.0.0.1:8888/swagger/index.html;
|
||||
proxy_pass http://${KRA_APP}-backend:8000/swagger/index.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,3 +3,6 @@ ENV = 'production'
|
||||
#下方为上线需要用到的程序代理前缀,一般用于nginx代理转发
|
||||
VITE_BASE_API = /api
|
||||
VITE_FILE_API = /api
|
||||
|
||||
# 后端与前端端口不一致时配置,例如 VITE_SERVER_PORT = 30081。
|
||||
# 也可以使用 VITE_WEBSOCKET_URL = http://192.168.200.128:30081 指定后端地址。
|
||||
|
||||
@@ -4,3 +4,5 @@ package-lock.json
|
||||
yarn.lock
|
||||
bun.lockb
|
||||
config.yaml
|
||||
# 渲染产物:Jenkins 从 .docker-compose/nginx/conf.d/my.conf 生成
|
||||
/nginx.k8s.conf
|
||||
|
||||
+5
-24
@@ -1,24 +1,5 @@
|
||||
# 如果需要用 cicd ,请设置环境变量:
|
||||
# variables:
|
||||
# DOCKER_BUILDKIT: 1
|
||||
|
||||
FROM node:20-slim AS base
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
FROM base AS prod-deps
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod
|
||||
|
||||
FROM base AS build
|
||||
COPY --from=prod-deps /app/node_modules /app/node_modules
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install && pnpm run build
|
||||
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=base /app/.docker-compose/nginx/conf.d/my.conf /etc/nginx/conf.d/my.conf
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
RUN ls -al /usr/share/nginx/html
|
||||
FROM docker.m.daocloud.io/nginx:alpine
|
||||
# nginx.k8s.conf is rendered by Jenkins from
|
||||
# .docker-compose/nginx/conf.d/my.conf (envsubst '$KRA_APP').
|
||||
COPY nginx.k8s.conf /etc/nginx/conf.d/default.conf
|
||||
COPY dist /usr/share/nginx/html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
allowBuilds:
|
||||
'@parcel/watcher': set this to true or false
|
||||
'@vue-office/docx': set this to true or false
|
||||
'@vue-office/excel': set this to true or false
|
||||
'@vue-office/pdf': set this to true or false
|
||||
es5-ext: set this to true or false
|
||||
vue-demi: set this to true or false
|
||||
'@parcel/watcher': true
|
||||
'@vue-office/docx': true
|
||||
'@vue-office/excel': true
|
||||
'@vue-office/pdf': true
|
||||
es5-ext: true
|
||||
vue-demi: true
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
<el-button
|
||||
v-if="isWebSocket(selected)"
|
||||
:icon="DocumentCopy"
|
||||
:disabled="isBusy(selected)"
|
||||
:disabled="isBusy(selected) || !canTestConnectionInfo(selected)"
|
||||
@click="openConnectionInfo"
|
||||
>
|
||||
连接信息
|
||||
@@ -326,9 +326,18 @@ const selected = computed(
|
||||
const integrationKey = (item) => `${item.kind}/${item.provider}`
|
||||
const providerMeta = (item) => TARGETS[integrationKey(item)] || TARGETS[TARGET_ORDER[0]]
|
||||
const isWebSocket = (item) => integrationKey(item) === 'websocket/melody'
|
||||
const websocketBackendIsExplicit = () =>
|
||||
Boolean(
|
||||
String(import.meta.env.VITE_WEBSOCKET_URL || '').trim() ||
|
||||
String(import.meta.env.VITE_SERVER_PORT || '').trim()
|
||||
)
|
||||
const websocketOrigin = () => {
|
||||
if (import.meta.env.DEV && import.meta.env.VITE_SERVER_PORT) {
|
||||
const configuredBase = String(import.meta.env.VITE_BASE_PATH || window.location.origin)
|
||||
if (websocketBackendIsExplicit()) {
|
||||
const configuredBase = String(
|
||||
import.meta.env.VITE_WEBSOCKET_URL ||
|
||||
import.meta.env.VITE_BASE_PATH ||
|
||||
window.location.origin
|
||||
)
|
||||
const backend = new URL(configuredBase, window.location.origin)
|
||||
if (
|
||||
['127.0.0.1', 'localhost'].includes(backend.hostname) &&
|
||||
@@ -336,18 +345,27 @@ const websocketOrigin = () => {
|
||||
) {
|
||||
backend.hostname = window.location.hostname
|
||||
}
|
||||
backend.port = String(import.meta.env.VITE_SERVER_PORT)
|
||||
if (import.meta.env.VITE_SERVER_PORT) {
|
||||
backend.port = String(import.meta.env.VITE_SERVER_PORT)
|
||||
}
|
||||
backend.protocol = backend.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
return `${backend.protocol}//${backend.host}`
|
||||
}
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
return `${protocol}//${window.location.host}`
|
||||
}
|
||||
const websocketPathPrefix = () => {
|
||||
if (websocketBackendIsExplicit()) return ''
|
||||
const base = String(import.meta.env.VITE_BASE_API || '').trim()
|
||||
if (!base || /^https?:\/\//i.test(base)) return ''
|
||||
return `/${base.replace(/^\/+|\/+$/g, '')}`
|
||||
}
|
||||
const connectionInfo = computed(() => {
|
||||
const path = String(selected.value?.config?.path || '/ws').trim() || '/ws'
|
||||
const normalizedPath = path.startsWith('/') ? path : `/${path}`
|
||||
const routePath = `${websocketPathPrefix()}${normalizedPath}`
|
||||
const token = String(userStore.token || '').trim()
|
||||
const url = `${websocketOrigin()}${normalizedPath}${token ? `?token=${encodeURIComponent(token)}` : ''}`
|
||||
const url = `${websocketOrigin()}${routePath}${token ? `?token=${encodeURIComponent(token)}` : ''}`
|
||||
return {
|
||||
url,
|
||||
example: `const socket = new WebSocket(${JSON.stringify(url)})\n\nsocket.onopen = () => console.log('connected')\nsocket.onmessage = (event) => console.log(event.data)`
|
||||
@@ -357,7 +375,7 @@ const connectionTestMessage = computed(() => {
|
||||
if (connectionTestStatus.value === 'testing') return '等待服务器握手包...'
|
||||
if (connectionTestStatus.value === 'success') return '握手成功,WebSocket 已连接。'
|
||||
if (connectionTestStatus.value === 'error') return '握手失败,请查看 websocket/websocket.log。'
|
||||
return '点击“测试此地址”验证浏览器到服务器的真实握手。'
|
||||
return '“测试连接”仅校验当前参数;保存并启用后可测试正式地址。'
|
||||
})
|
||||
const connectionTestAlertType = computed(() => {
|
||||
if (connectionTestStatus.value === 'success') return 'success'
|
||||
@@ -469,6 +487,8 @@ const isBusy = (item) => Boolean(pending[operationKey(item)])
|
||||
const isSaving = (item) => pending[operationKey(item)] === 'save'
|
||||
const isToggling = (item) => pending[operationKey(item)] === 'toggle'
|
||||
const isTesting = (item) => pending[operationKey(item)] === 'test'
|
||||
const canTestConnectionInfo = (item) =>
|
||||
Boolean(item?.configured && item.enabled && !isDirty(item))
|
||||
const numberConstraint = (fieldKey) =>
|
||||
NUMBER_CONSTRAINTS[fieldKey] || { min: undefined, max: undefined }
|
||||
|
||||
@@ -601,7 +621,7 @@ const testSelected = async () => {
|
||||
if (res.code !== 0) {
|
||||
return
|
||||
}
|
||||
ElMessage.success(`${item.name || providerMeta(item).name} 连接测试成功`)
|
||||
ElMessage.success(`${item.name || providerMeta(item).name} 配置测试成功`)
|
||||
} catch {
|
||||
// The request layer owns transport and server error presentation.
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user