ops: use host-managed local service list

This commit is contained in:
2026-08-12 11:20:48 +08:00
parent 176119ca29
commit 50371cfb0c
5 changed files with 19 additions and 238 deletions

View File

@@ -35,7 +35,16 @@ nginx -s stop \
## Production 443 Proxy ## Production 443 Proxy
For port 443, install `deploy/nginx.local-kanban.conf` into the system Nginx site directory and use a trusted certificate. The root domain serves the portal page, and individual apps keep their own ports: For port 443, install `deploy/nginx.local-kanban.conf` into the system Nginx site directory and use a trusted certificate. The root domain serves the host-local service list from `/var/www/local-service-list`, and individual apps keep their own ports. The service-list HTML and CSS are maintained directly in that directory rather than copied from this repo.
Before installing, make sure these files exist:
```text
/var/www/local-service-list/index.html
/var/www/local-service-list/portal.css
```
Then install the Nginx configuration:
```bash ```bash
sudo cp deploy/nginx.local-kanban.conf /etc/nginx/sites-available/local-kanban sudo cp deploy/nginx.local-kanban.conf /etc/nginx/sites-available/local-kanban

View File

@@ -3,7 +3,7 @@ limit_req_zone $binary_remote_addr zone=kanban_login:10m rate=5r/m;
server { server {
listen 443 ssl http2; listen 443 ssl http2;
server_name gahow-pc.ipads-lab.se.sjtu.edu.cn; server_name gahow-pc.ipads-lab.se.sjtu.edu.cn;
root /var/www/local-kanban-portal; root /var/www/local-service-list;
index index.html; index index.html;
ssl_certificate /etc/nginx/certs/gahow-pc.fullchain.pem; ssl_certificate /etc/nginx/certs/gahow-pc.fullchain.pem;

View File

@@ -1,64 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>gahow-pc services</title>
<link rel="stylesheet" href="/portal.css">
</head>
<body>
<main class="shell">
<header class="topbar">
<div>
<h1>gahow-pc</h1>
<p>Local services</p>
</div>
</header>
<section class="service-section">
<div class="section-heading">
<h2>Services</h2>
</div>
<div class="service-grid">
<a class="service-card primary" href="https://gahow-pc.ipads-lab.se.sjtu.edu.cn:3443/">
<span class="service-icon">Gi</span>
<span class="service-topline">Repository</span>
<span class="service-name">Gitea</span>
<span class="service-desc">本地 Git 仓库与项目管理</span>
<span class="service-port">https :3443</span>
</a>
<a class="service-card primary" href="https://gahow-pc.ipads-lab.se.sjtu.edu.cn:8443/">
<span class="service-icon">Kb</span>
<span class="service-topline">Ops</span>
<span class="service-name">Kanban</span>
<span class="service-desc">GPU、额度、项目与 agent 任务</span>
<span class="service-port">https :8443</span>
</a>
<a class="service-card primary" href="https://gahow-pc.ipads-lab.se.sjtu.edu.cn:5443/">
<span class="service-icon">St</span>
<span class="service-topline">Finance</span>
<span class="service-name">Stock Agent</span>
<span class="service-desc">个人股票分析与日报</span>
<span class="service-port">https :5443</span>
</a>
</div>
</section>
<details class="api-section">
<summary>后端 API</summary>
<div class="service-grid">
<a class="service-card" href="https://gahow-pc.ipads-lab.se.sjtu.edu.cn:8443/api/health">
<span class="service-name">Kanban API</span>
<span class="service-port">https :8443/api</span>
<span class="service-desc">Kanban 前后端同一个 Node 服务</span>
</a>
<a class="service-card" href="https://gahow-pc.ipads-lab.se.sjtu.edu.cn:8788/api/health">
<span class="service-name">Stock Agent API</span>
<span class="service-port">https :8788/api</span>
<span class="service-desc">Express API位于 /home/gahow/projects/stock-agent</span>
</a>
</div>
</details>
</main>
</body>
</html>

View File

@@ -1,166 +0,0 @@
:root {
color-scheme: light;
--bg: #f4f6f8;
--panel: #ffffff;
--ink: #17202c;
--muted: #697586;
--line: #d7dee8;
--accent: #2563eb;
--soft: #eef4ff;
--shadow: 0 16px 40px rgba(23, 32, 44, 0.08);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background:
radial-gradient(circle at 18% 10%, rgba(37, 99, 235, 0.12), transparent 28%),
radial-gradient(circle at 90% 18%, rgba(18, 128, 92, 0.11), transparent 26%),
var(--bg);
color: var(--ink);
font: 14px/1.45 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.shell {
width: min(1180px, calc(100vw - 32px));
margin: 0 auto;
padding: 42px 0 56px;
}
.topbar {
margin-bottom: 30px;
}
h1,
h2,
p {
margin: 0;
}
h1 {
font-size: 34px;
line-height: 1.08;
letter-spacing: 0;
}
h2 {
font-size: 14px;
margin-bottom: 0;
text-transform: uppercase;
color: var(--muted);
}
.topbar p,
.service-desc {
color: var(--muted);
}
.topbar p {
margin-top: 6px;
}
.service-section {
margin-top: 18px;
}
.section-heading {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
margin-bottom: 10px;
}
.section-heading span {
color: var(--muted);
}
.service-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 16px;
}
.service-card,
.api-section {
background: var(--panel);
border: 1px solid var(--line);
border-radius: 8px;
box-shadow: var(--shadow);
}
.service-card {
position: relative;
display: grid;
grid-template-columns: auto 1fr;
gap: 8px 14px;
min-height: 168px;
padding: 18px;
color: inherit;
text-decoration: none;
overflow: hidden;
}
.service-card:hover {
border-color: var(--accent);
transform: translateY(-1px);
}
.service-card.primary {
border-color: color-mix(in srgb, var(--accent) 32%, var(--line));
}
.service-name {
grid-column: 1 / -1;
font-size: 22px;
font-weight: 700;
}
.service-icon {
display: grid;
place-items: center;
width: 42px;
height: 42px;
border-radius: 8px;
background: var(--soft);
color: var(--accent);
font-weight: 800;
}
.service-topline {
align-self: center;
color: var(--muted);
font-weight: 650;
}
.service-desc {
grid-column: 1 / -1;
}
.service-port {
grid-column: 1 / -1;
justify-self: start;
border-radius: 999px;
background: var(--soft);
color: #1849a9;
padding: 3px 9px;
}
.api-section {
margin-top: 18px;
padding: 14px 16px;
box-shadow: none;
}
.api-section summary {
cursor: pointer;
font-size: 15px;
font-weight: 700;
}
.api-section .service-grid {
margin-top: 14px;
}

View File

@@ -8,18 +8,20 @@ ENABLE_HTTP_REDIRECT="${KANBAN_ENABLE_HTTP_REDIRECT:-0}"
GITEA_PORT="${KANBAN_GITEA_PORT:-3443}" GITEA_PORT="${KANBAN_GITEA_PORT:-3443}"
STOCK_FRONTEND_PORT="${KANBAN_STOCK_FRONTEND_PORT:-5443}" STOCK_FRONTEND_PORT="${KANBAN_STOCK_FRONTEND_PORT:-5443}"
STOCK_API_PORT="${KANBAN_STOCK_API_PORT:-8788}" STOCK_API_PORT="${KANBAN_STOCK_API_PORT:-8788}"
SERVICE_LIST_ROOT="/var/www/local-service-list"
if [[ "${EUID}" -ne 0 ]]; then if [[ "${EUID}" -ne 0 ]]; then
exec sudo -E bash "$0" "$@" exec sudo -E bash "$0" "$@"
fi fi
if [[ ! -f "${SERVICE_LIST_ROOT}/index.html" || ! -f "${SERVICE_LIST_ROOT}/portal.css" ]]; then
echo "Missing local service list assets under ${SERVICE_LIST_ROOT}" >&2
exit 1
fi
mkdir -p /etc/nginx/certs mkdir -p /etc/nginx/certs
mkdir -p /var/www/local-kanban-portal
cp "${ROOT_DIR}/deploy/certs/local-kanban.crt" /etc/nginx/certs/gahow-pc.fullchain.pem cp "${ROOT_DIR}/deploy/certs/local-kanban.crt" /etc/nginx/certs/gahow-pc.fullchain.pem
cp "${ROOT_DIR}/deploy/certs/local-kanban.key" /etc/nginx/certs/gahow-pc.key cp "${ROOT_DIR}/deploy/certs/local-kanban.key" /etc/nginx/certs/gahow-pc.key
cp "${ROOT_DIR}/portal/index.html" /var/www/local-kanban-portal/index.html
cp "${ROOT_DIR}/portal/portal.css" /var/www/local-kanban-portal/portal.css
rm -f /var/www/local-kanban-portal/portal.js
chmod 600 /etc/nginx/certs/gahow-pc.key chmod 600 /etc/nginx/certs/gahow-pc.key
{ {
@@ -43,7 +45,7 @@ cat <<EOF
server { server {
listen 443 ssl http2; listen 443 ssl http2;
server_name ${DOMAIN}; server_name ${DOMAIN};
root /var/www/local-kanban-portal; root ${SERVICE_LIST_ROOT};
index index.html; index index.html;
ssl_certificate /etc/nginx/certs/gahow-pc.fullchain.pem; ssl_certificate /etc/nginx/certs/gahow-pc.fullchain.pem;
@@ -135,7 +137,7 @@ rm -f /etc/nginx/sites-enabled/default
nginx -t nginx -t
systemctl reload nginx || systemctl restart nginx systemctl reload nginx || systemctl restart nginx
echo "Nginx portal is configured for https://${DOMAIN}/" echo "Nginx local service list is configured for https://${DOMAIN}/"
echo "Kanban remains available on its own port, for example https://${DOMAIN}:8443/" echo "Kanban remains available on its own port, for example https://${DOMAIN}:8443/"
echo "Gitea HTTPS is configured for https://${DOMAIN}:${GITEA_PORT}/" echo "Gitea HTTPS is configured for https://${DOMAIN}:${GITEA_PORT}/"
echo "Stock Agent HTTPS is configured for https://${DOMAIN}:${STOCK_FRONTEND_PORT}/" echo "Stock Agent HTTPS is configured for https://${DOMAIN}:${STOCK_FRONTEND_PORT}/"