Files
AIclinicalresearch/docs/05-部署文档/06-前端Nginx-SAE容器部署指南.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

1726 lines
52 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# <20>滨垢 Nginx - SAE 摰孵膥<E5ADB5>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦**: v1.2 (靽格迤嚗鐭ode <20><>𧋦<EFBFBD><F0A78BA6>ite <20><>𧋦<EFBFBD><F0A78BA6>𠯫敹𡑒<E695B9><F0A19192><EFBFBD><E7AE9D>𧒄<EFBFBD>?
**<EFBFBD>𥕦遣<EFBFBD>園𡢿**: 2025-12-13
**<EFBFBD><EFBFBD><EFBFBD>𦒘耨霈?*: 2025-12-13
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>凒**: AIclinicalresearch 撟喳蝱 - <20>滨垢<E6BBA8><EFBFBD><E8B9B1><EFBFBD>皞鞉<E79A9E><E99E89><EFBFBD>frontend-v2嚗?
**<EFBFBD><EFBFBD>霂餉<EFBFBD>?*: 餈鞟輕撌亦<E6928C><EFBFBD><E692A3><EFBFBD><EFBFBD>蝡臬<E89DA1><E887AC>穃極蝔见<E89D94>
**<EFBFBD>函蔡<EFBFBD><EFBFBD>**: <20><EFBFBD>鈭?SAE嚗𠄎erverless 摨𠉛鍂撘閙<E69298>嚗会ginx 摰孵膥<E5ADB5>函蔡
**v1.2 <20>湔鰵<E6B994><EFBFBD>**嚗?- <20>𣞁 靽格迤嚗鐭ode <20><>𧋦隞?18 <20>嫣蛹 22嚗<32><E59A97><EFBFBD><E69298>𤑳㴓憓?v22.18.0 銝<><E98A9D><EFBFBD>
- <20>?蝖株恕嚗间ite <20><>𧋦 7.2嚗īackage.json <20><EFBFBD><E7AC94><EFBFBD>𧋦嚗?- <20>𩤃<EFBFBD> 靽格迤嚗𡁏𠯫敹𡑒<E695B9><F0A19192><EFBFBD> stdout/stderr嚗𠄎AE <20><>雿喳<E99BBF>頝蛛<E9A09D>
- <20>𩤃<EFBFBD> <20><EFBFBD>嚗𡁜捆<F0A1819C>冽𧒄<E586BD>箄挽蝵殷<E89DB5>Asia/Shanghai嚗?- <20>𩤃<EFBFBD> 撘箏<E69298>嚗𡁜<E59A97>蝡臬𧑐<E887AC><F0A79190><EFBFBD><EFBFBD><EFBFBD><E69B89>滨蔭嚗<E894AD><E59A97>蝏坔暒<E59D94><EFBFBD>霈文<E99C88><EFBFBD>
**v1.1 <20>湔鰵<E6B994><EFBFBD>**嚗?- <20><> 靽格迤嚗𡁜抅鈭?**frontend-v2** <20><EFBFBD><EFBFBD><E59A97><EFBFBD>?frontend嚗?- <20>?<3F>湔鰵嚗鑹eact 19 + Vite 6 + Ant Design 6.0
- <20>?<3F><EFBFBD>嚗鋫nt Design X 2.1 霂湔<E99C82>嚗㇁I 撖寡<E69296><EFBFBD>辣嚗?- <20>?<3F><EFBFBD>嚗𡁏芋<F0A1818F><EFBFBD><E5A092><EFBFBD>霂湔<E99C82>嚗Êramework + modules嚗?- <20>?摰<><E691B0>嚗𡁏<E59A97>撱箄楝敺<E6A59D><E695BA><EFBFBD><EFBFBD>蝏𤘪<E89D8F>
---
## <20><> <20><EFBFBD>
1. [銝箔<EFBFBD><EFBFBD><EFBFBD>㗇𥋘 SAE Nginx 摰孵膥<E5ADB5>函蔡](#1-銝箔<E98A9D><EFBFBD><E98A8B>㗇𥋘-sae-nginx-摰孵膥<E5ADB5>函蔡)
2. [<5B>函蔡<E587BD><EFBFBD>憭䚡(#2-<2D>函蔡<E587BD><EFBFBD>憭?
3. [<EFBFBD>滨垢<EFBFBD>滚𦛚<EFBFBD><EFBFBD><EFBFBD>](#3-<2D>滨垢<E6BBA8>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>)
4. [<EFBFBD>𥕦遣 Nginx <20>滨蔭](#4-<2D>𥕦遣-nginx-<2D>滨蔭)
5. [<EFBFBD><EFBFBD>遣 Docker <20>𨅯<EFBFBD>](#5-<2D><>遣-docker-<2D>𨅯<EFBFBD>)
6. [<EFBFBD>砍𧑐瘚贝<EFBFBD>撉諹<EFBFBD>](#6-<2D>砍𧑐瘚贝<E7989A>撉諹<E69289>)
7. [<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ACR](#7-<2D><EFBFBD><E588B8><EFBFBD>-acr)
8. [SAE 摨𠉛鍂<F0A0899B>滨蔭](#8-sae-摨𠉛鍂<F0A0899B>滨蔭)
9. [蝡臬<E89DA1>蝡舀<E89DA1>霂騟(#9-蝡臬<E89DA1>蝡舀<E89DA1>霂?
10. [<5B>烐綉銝𡒊輕<F0A1928A>也(#10-<2D>烐綉銝𡒊輕<F0A1928A>?
11. [<EFBFBD><EFBFBD><EFBFBD><EFBFBD>埝䰻](#11-<2D><><EFBFBD><EFBFBD>埝䰻)
12. [瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹䀉(#12-瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹?
---
## 1. 銝箔<E98A9D><EFBFBD><E98A8B>㗇𥋘 SAE Nginx 摰孵膥<E5ADB5>函蔡
### <20>?<3F><EFBFBD>隡睃飵
| 隡睃飵 | 霂湔<E99C82> | 撖寞<E69296><E5AF9E><EFBFBD><EFBFBD>?|
|------|------|----------|
| **<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>** | Nginx 憭<><E686AD><EFBFBD><EFBFBD><E8B9B1><EFBFBD>隞嗆<E99A9E><E59786><EFBFBD><EFBFBD>擃䀝<E69383> Node.js嚗ìerve <20>?next start嚗?| 擐硋<E69390><E7A18B>㰘蝸敹恬<E695B9><E681AC><EFBFBD>雿㯄<E99BBF>憟?|
| **SPA 頝舐眏<E88890><EFBFBD>** | React Router <20>瑟鰵憿菟𢒰銝滢<E98A9D> 404 | `try_files` <20><EFBFBD><E6AFBA><EFBFBD> |
| **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** | Nginx 撠?`/api` 頧砍<E9A0A7><E7A08D><EFBFBD>蝡荔<E89DA1><E88D94>滨垢<E6BBA8><EFBFBD><E4ADBE>?| <20>?CORS <20>滨蔭嚗𣬚<E59A97><F0A3AC9A><EFBFBD><E7A18B>?|
| **蝻枏<E89DBB><E69E8F><EFBFBD>** | 蝎曄<E89D8E><E69B84><EFBFBD><E689B9><EFBFBD><E8B9B1><EFBFBD>皞鞟<E79A9E>摮条<E691AE><E69DA1>?| <20><EFBFBD>撣血捐瘨<E68D90><E798A8><EFBFBD><E6A2B9>𣳇<EFBFBD><EFBFBD>頧?|
| **蝘<><E89D98><EFBFBD>硋停蝏?* | Docker <20>𨅯<EFBFBD><F0A885AF>舐凒<E88890>乩漱隞条<E99A9E><E69DA1>駁堺 | 皛∟雲<E2889F><EFBFBD><E9A48C>唳旿<E594B3><E697BF><EFBFBD><EFBFBD><E996AC> |
| **蝏煺<E89D8F><E785BA><EFBFBD>** | 銝𤾸<E98A9D>蝡胯<E89DA1><E883AF>ython 敺格<E695BA><E6A0BC><EFBFBD><EFBFBD>雿輻鍂 Docker | 銝<>憟烾<E6869F>蝵脫<E89DB5>蝔页<E89D94><E9A1B5><EFBFBD>餈鞟輕<E99E9F>鞉𧋦 |
### <20>㴓 銝箔<E98A9D><EFBFBD><E98A8B><EFBFBD>?OSS + CDN嚗?
<EFBFBD>寞旿銋见<EFBFBD><EFBFBD><EFBFBD>悄霈綽<EFBFBD><EFBFBD>睲賑<EFBFBD>𡒊<EFBFBD><EFBFBD><EFBFBD><EFBFBD>娪★<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
| 撖寞<E69296>憿?| OSS + CDN | SAE Nginx 摰孵膥 | 霂<><E99C82> |
|-------|-----------|----------------|------|
| **蝘<><E89D98><EFBFBD><EFBFBD>蝵?* | <20>?<3F><EFBFBD><E4ADBE>典龫<E585B8><EFBFBD>蝵煾<E89DB5>蝵?OSS | <20>?Docker <20>𨅯<EFBFBD><F0A885AF>舐凒<E88890>乩漱隞?| **摰孵膥<E5ADB5>?* |
| **<EFBFBD><EFBFBD>蝏煺<EFBFBD><EFBFBD>?* | <20>?<3F>滨垢 OSS嚗<53><E59A97>蝡?SAE嚗<45>𠧧鋆?| <20>?<3F><EFBFBD> SAE 摰孵膥嚗𣬚<E59A97><EFBFBD>蝞∠<E89D9E> | **摰孵膥<E5ADB5>?* |
| **CORS 憭<><E686AD>** | <20>𩤃<EFBFBD> <20>滨垢<E6BBA8><E59EA2><EFBFBD><E996AC><EFBFBD><EFBFBD><EFBFBD>?| <20>?Nginx <20><EFBFBD><EFBFBD><E99A9E><EFBFBD><E59A97>蝡舀<E89DA1><E88880>?| **摰孵膥<E5ADB5>?* |
| **<EFBFBD>鞉𧋦嚗<EFBFBD><EFBFBD><EFBFBD>芋嚗?* | <20>?摮睃<E691AE>韐寧鍂<E5AFA7><E98D82><EFBFBD> | <20>𩤃<EFBFBD> <20><><EFBFBD><E996AC><EFBFBD><E98AB5>靘页<E99D98>~100<30>?<3F><><EFBFBD> | **OSS <20>?* |
| **<EFBFBD><EFBFBD><EFBFBD>𣳇<EFBFBD>?* | <20>?CDN <20><><EFBFBD><EFBFBD><E996AC><EFBFBD><EFBFBD> | <20>?<3F>訫𧑐<E8A8AB><EFBFBD>蝵?| **OSS <20>?* |
| **<EFBFBD><EFBFBD><EFBFBD>箸艶<EFBFBD><EFBFBD><EFBFBD>** | <20>?銝漤<E98A9D><E6BCA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | <20>?摰𣬚<E691B0><F0A3AC9A><EFBFBD><EFBFBD><EFBFBD><E89D98><EFBFBD>?| **摰孵膥<E5ADB5>?* |
**蝏栞捏**嚗𡁜笆鈭𡡞<E988AD><EFBFBD><E996AC><EFBFBD><EFBFBD><E58CA7>函蔡<E587BD><E894A1><EFBFBD><EFBFBD><E39B96>𥪯漣<F0A5AAAF><E6BCA3><EFBFBD>SAE Nginx 摰孵膥<E5ADB5>臬𣈲銝<F0A388B2><E98A9D>㗇𥋘<E39787>?
---
## 2. <20>函蔡<E587BD><EFBFBD>憭?
### <20>?<3F>滨蔭<E6BBA8>∩辣璉<E8BEA3><E79289><EFBFBD><E4BAA4>?
#### <20>砍𧑐撘<F0A79190><E69298>𤑳㴓憓?
- [ ] Docker Desktop 撌脣<E6928C><EFBFBD>僎餈鞱<E9A488><EFBFBD><E59A97><EFBFBD>?20.10+嚗?- [ ] Node.js 撌脣<E6928C><EFBFBD><E98B86><EFBFBD><EFBFBD>𧋦 18+嚗?- [ ] <20>滨垢隞<E59EA2><E99A9E>撌脫<E6928C><E884AB><EFBFBD><E7A18B>砍𧑐
- [ ] <20>滨垢<E6BBA8>冽𧋦<E586BD><EFBFBD><EFBFBD><EFBFBD>臬𢆡嚗Ǒnpm run dev`嚗?- [ ] <20>滨垢<E6BBA8><EFBFBD><E8B3A3><EFBFBD><EFBFBD>撱綽<E692B1>`npm run build`嚗?
撉諹<EFBFBD><EFBFBD>賭誘嚗?
```bash
# 璉<><E79289>?Docker
docker --version
# 颲枏枂蝷箔<E89DB7>嚗鋽ocker version 24.0.6
# 璉<><E79289>?Node.js
node --version
# 颲枏枂蝷箔<E89DB7>嚗鯝18.17.0
# 璉<><E79289>?npm
npm --version
# 颲枏枂蝷箔<E89DB7>嚗?.6.7
# 瘚贝<E7989A><E8B49D><EFBFBD>
cd frontend
npm run build
# 摨磰砲<E7A3B0>𣂼<EFBFBD><F0A382BC><EFBFBD><EFBFBD> dist/ <20><EFBFBD>
```
#### <20><EFBFBD>鈭𤏸<E988AD>皞?
- [ ] **<EFBFBD>𡒊垢<EFBFBD>滚𦛚嚗𠄎AE嚗?* 撌脤<E6928C>蝵脣僎餈鞱<E9A488>
- <20>𡒊垢 VPC <20><><EFBFBD><EFBFBD><EFBFBD>撌脰繮<E884B0><EFBFBD>憒?`http://172.17.x.x:3001`嚗? - <20>𡒊垢<F0A1928A>亙熒璉<E78692><E79289>亙虾霈輸䔮
- [ ] **<EFBFBD><EFBFBD>鈭穃捆<EFBFBD><EFBFBD><EFBFBD>𤩺<EFBFBD><EFBFBD>?ACR** 撌脣<E6928C><E884A3>? - <20><EFBFBD>蝛粹𡢿撌脣<E6928C>撱綽<E692B1>憒?`clinical-research`嚗? - <20><EFBFBD><EFBFBD><E69296>撌脰挽蝵?
- [ ] **SAE 摨𠉛鍂** <20><><EFBFBD><EFBFBD>𥕦遣
- VPC <20>䔶漱<E494B6>㦤撌脤<E6928C>㗇𥋘嚗<F0A58B98><E59A97><EFBFBD>𡒊垢<F0A1928A><EFBFBD><EFBFBD> VPC嚗?
#### <20>滨蔭靽⊥<E99DBD><E28AA5><EFBFBD><EFBFBD>
```bash
# <20>𡒊垢<F0A1928A>滚𦛚<E6BB9A><F0A69B9A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>
BACKEND_SERVICE_URL=http://172.17.x.x:3001
# 憒<><E68692><EFBFBD><EFBFBD><EFBFBD><E996AC>蝵桃㴓憓<E3B493><E68693><EFBFBD>𧶏<EFBFBD><F0A7B68F><EFBFBD><EFBFBD>
# VITE_API_BASE_URL <20><EFBFBD>撱箸𧒄瘜典<E7989C><EFBFBD><E59A97>撠睲蝙<E79DB2><EFBFBD>
```
---
## 3. <20>滨垢<E6BBA8>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>
### <20>𣑐 <20><><EFBFBD><EFBFBD>
| <20><><EFBFBD>?| <20><>𧋦 | <20><EFBFBD>?|
|------|------|------|
| **React** | 19.2+ | UI 獢<>沲嚗<E6B2B2><E59A97><EFBFBD><EFBFBD><E59581>穿<EFBFBD> |
| **Vite** | 7.2+ | <20><>遣撌亙<E6928C><EFBFBD><E59A97>敹恬<E695B9><E681AC><EFBFBD><EFBFBD><EFBFBD><E59581>穿<EFBFBD>|
| **TypeScript** | 5.9+ | 蝐餃<E89D90>摰匧<E691B0> |
| **Ant Design** | 6.0+ | UI 蝏<>辣摨橒<E691A8><E6A992><EFBFBD><EFBFBD><EFBFBD><E59581>穿<EFBFBD> |
| **Ant Design X** | 2.1+ | AI 撖寡<E69296><EFBFBD>辣嚗<E8BEA3>鰵憓痹<E68693> |
| **React Router** | 7.9+ | 頝舐眏蝞∠<E89D9E>嚗𠄎PA嚗?|
| **React Query** | 5.90+ | <20>唳旿<E594B3><EFBFBD><E79195>𣬚<EFBFBD>摮?|
| **Axios** | 1.13+ | HTTP 摰<E691B0>蝡?|
| **AG Grid** | 34.3+ | <20>唳旿銵冽聢嚗㇄C 璅<E79285>嚗?|
| **TailwindCSS** | 3.4+ | CSS 獢<>沲 |
| **Zustand** | 5.0+ | <20><EFBFBD><E59786><EFBFBD>?|
**<EFBFBD>𩤃<EFBFBD> <20><>𧋦霂湔<E99C82>**嚗?- **Node.js**: v22.18.0嚗<EFBFBD><EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD><EFBFBD>摰䂿<EFBFBD><EFBFBD>穿<EFBFBD>
- **Vite**: 7.2.2嚗īackage.json <20><EFBFBD><E7AC94><EFBFBD>𧋦嚗峕<E59A97><E5B395>啁迅摰𡁶<E691B0>嚗?- <20><><EFBFBD><EFBFBD><E58EA9><EFBFBD><E7A08D>亥䌊 `frontend-v2/package.json` <20><EFBFBD><EFBFBD><E99A9E>
### <20><> <20><EFBFBD>霈曇恣嚗<E681A3><EFBFBD><EFBFBD>嚗?
```
frontend-v2/
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> src/
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> framework/ # 獢<>沲撅?<3F>? <20>? <20><EFBFBD><E98EBF><EFBFBD> layout/ # 銝餃<E98A9D><EFBFBD> + 憿園<E686BF>撖潸⏛
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> router/ # 頝舐眏摰<E79C8F>
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> permission/ # <20><><EFBFBD>蝞∠<E89D9E>
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> modules/ # 璅<E79285>瘜典<E7989C>銵?<3F>? <20>?<3F>? <20><EFBFBD><E98EBF><EFBFBD> modules/ # 銝𡁜𦛚璅<E79285>撅?<3F>? <20>? <20><EFBFBD><E98EBF><EFBFBD> aia/ # AI <20><EFBFBD><E7AE84><EFBFBD>
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> pkb/ # 銝芯犖<E88AAF><EFBFBD>摨?<3F>? <20>? <20><EFBFBD><E98EBF><EFBFBD> asl/ # AI <20><EFBFBD><E7AE84><EFBFBD>
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> dc/ # <20>唳旿皜<E697BF><E79A9C><EFBFBD><EFBFBD>
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> ssa/ # <20><EFBFBD>蝏蠘恣<E8A098><E681A3><EFBFBD>
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> st/ # 蝏蠘恣<E8A098><E681A3><EFBFBD>撌亙<E6928C>
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> rvw/ # 蝔蹂辣摰⊥䰻蝟餌<E89D9F>
<EFBFBD>? <20>?<3F>? <20><EFBFBD><E5A999><EFBFBD> shared/ # <20>曹澈<E69BB9><EFBFBD>撅?<3F>? <20><EFBFBD><E98EBF><EFBFBD> components/ # <20>曹澈蝏<E6BE88>辣嚗㇃hat 蝏<>辣蝑㚁<E89D91>
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> api/ # <20>曹澈 API 撌亙<E6928C>
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> hooks/ # <20>曹澈 Hooks
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD> utils/ # 撌亙<E6928C><E4BA99>賣㺭
```
### <20><> API 靚<><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>霈曇恣嚗?
**瘥譍葵璅<E79285><E288AA>厩𡠺蝡讠<E89DA1> API <20><>辣**嚗?
```typescript
// modules/asl/api/index.ts
const API_BASE_URL = '/api/v1/asl';
async function request<T>(url: string, options?: RequestInit): Promise<T> {
const response = await fetch(`${API_BASE_URL}${url}`, {
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
});
return response.json();
}
// modules/dc/api/toolC.ts
const BASE_URL = '/api/v1/dc/tool-c';
// 雿輻鍂 axios
axios.post(`${BASE_URL}/upload`, formData);
```
**<EFBFBD>喲睸霈曇恣**嚗?- <20>?瘥譍葵璅<E79285><E288AA><EFBFBD>蝞∠<E89D9E><E288A0>芸楛<E88AB8>?API嚗<49><EFBFBD><EFBFBD>嚗?- <20>?雿輻鍂<E8BCBB>詨笆頝臬<E9A09D> `/api/v1/...`<EFBFBD><EFBFBD>蝖祉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝡臬𧑐<EFBFBD><EFBFBD>嚗?- <20>?瘛瑕<E7989B>雿輻鍂 fetch <20>?axios嚗<73><EFBFBD>格芋<E6A0BC><EFBFBD><EFBFBD><E79899>
- <20>?<3F>煺漣<E785BA><EFBFBD><E887AC>?Nginx <20><EFBFBD><EFBFBD><E99A9E><EFBFBD><EFBFBD>蝡?- <20>?<3F>𣳇<EFBFBD><EFBFBD><E686AD> CORS嚗<53><E59A97>皞鞱窈瘙<E7AA88><E79899>
**蝷箔<E89DB7>霂瑟<E99C82><EFBFBD><E7989A>**嚗?```
ASL 璅<E79285>嚗鎭ET /api/v1/asl/projects
<20>?Nginx <20><EFBFBD><EFBFBD><E99A9E>
<20>?<3F>𡒊垢<F0A1928A>滚𦛚嚗冴ttp://172.17.x.x:3001/api/v1/asl/projects
```
### <20><> <20><>遣瘚<E981A3><E7989A>
```bash
# <20>𩤃<EFBFBD> 瘜冽<E7989C>嚗帋蝙<E5B88B>?frontend-v2 <20><EFBFBD><EFBFBD><E59A97><EFBFBD>?frontend嚗?cd frontend-v2
# 1. 摰㕑<E691B0>靘肽<E99D98>
npm install
# 2. <20><><EFBFBD>煺漣<E785BA><E6BCA3>𧋦
npm run build
# 摰鮋<E691B0><E9AE8B><EFBFBD>嚗魩sc -b && vite build
# 3. 鈭抒<E988AD><E68A92><EFBFBD>蝏𤘪<E89D8F>
dist/
<20><EFBFBD><E98EBF><EFBFBD> index.html # <20>亙藁 HTML嚗<4C>漲 1KB嚗? <20><EFBFBD><E98EBF><EFBFBD> assets/
<20>? <20><EFBFBD><E98EBF><EFBFBD> index-xxxxx.js # 銝?JS <20><>辣嚗<E8BEA3>漲 800KB嚗<42><EFBFBD>讠憬嚗? <20>? <20><EFBFBD><E98EBF><EFBFBD> index-xxxxx.css # 銝?CSS <20><>辣嚗<E8BEA3>漲 100KB嚗<42>鉄 Ant Design + TailwindCSS嚗? <20>? <20><EFBFBD><E98EBF><EFBFBD> vendor-xxxxx.js # 蝚砌<E89D9A><E7A08C><EFBFBD>嚗㇌eact<63><74>nt Design 蝑㚁<E89D91>
<20>? <20><EFBFBD><E5A999><EFBFBD> *.svg/png/... # <20><EFBFBD><EFBFBD><E99F8F>
<20><EFBFBD><E5A999><EFBFBD> vite.svg # Favicon
# 憸<><E686B8><EFBFBD><EFBFBD><EFBFBD>園𡢿嚗?0-60 蝘𡜐<E89D98><F0A19C90><EFBFBD>鈭擧㦤<E693A7><EFBFBD><EFBFBD>嚗?# 鈭抒<E988AD><E68A92>餃之撠𧶏<E692A0>蝥?2-3MB嚗<42><E59A97>蝻拙<E89DBB>嚗?```
**<2A><>遣鈭抒<E988AD><E68A92><EFBFBD><EFBFBD>**嚗?| <20><>辣蝐餃<E89D90> | 憭批<E686AD><EFBFBD><E59A97>蝻拙<E89DBB>嚗?| 憭批<E686AD><EFBFBD><E59A97>蝻拙<E89DBB>嚗?| 霂湔<E99C82> |
|---------|--------------|--------------|------|
| index.html | 1KB | 1KB | <20>亙藁 HTML |
| index-xxxxx.js | ~2.5MB | ~800KB | 銝𡁜𦛚隞<F0A69B9A><E99A9E> |
| vendor-xxxxx.js | ~3MB | ~1MB | 蝚砌<E89D9A><E7A08C><EFBFBD> |
| index-xxxxx.css | ~300KB | ~100KB | <20><EFBFBD><E79195><EFBFBD>辣 |
| <20><EFBFBD><EFBFBD><E99F8F> | ~500KB | ~200KB | <20><EFBFBD><E69AB9><EFBFBD><EFBFBD>雿梶<E99BBF> |
| **<2A>餉恣** | **~6.3MB** | **~2.1MB** | Gzip <20>讠憬<E8AEA0>?|
### <20><> 敶枏<E695B6> API <20>滨蔭<E6BBA8><E894AD><EFBFBD>
**frontend-v2 <20>?API <20>滨蔭<E6BBA8><EFBFBD>**嚗?
```typescript
// modules/asl/api/index.ts
const API_BASE_URL = '/api/v1/asl'; // <20>?<3F>詨笆頝臬<E9A09D><EFBFBD><EFBFBD><EFBFBD>
// modules/dc/api/toolC.ts
const BASE_URL = '/api/v1/dc/tool-c'; // <20>?<3F>詨笆頝臬<E9A09D><EFBFBD><EFBFBD><EFBFBD>
// modules/dc/api/toolB.ts
const BASE_URL = '/api/v1/dc/tool-b'; // <20>?<3F>詨笆頝臬<E9A09D><EFBFBD><EFBFBD><EFBFBD>
```
**撘<><E69298>𤑳㴓憓<E3B493><EFBFBD><E8AAA8><EFBFBD>蝵?*嚗?
```typescript
// vite.config.ts
export default defineConfig({
server: {
host: '0.0.0.0',
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:3001',
changeOrigin: true,
},
},
},
});
```
**<2A>煺漣<E785BA><EFBFBD><E887AC>滨蔭蝑𣇉裦**嚗?- <20>?**銝漤<E98A9D>閬?*霈曄蔭隞颱<E99A9E><E9A2B1><EFBFBD><E887AC><EFBFBD><EFBFBD><E59A97> `VITE_API_BASE_URL`嚗?- <20>?<3F><><EFBFBD>㗇芋<E39787><EFBFBD>雿輻鍂<E8BCBB>詨笆頝臬<E9A09D> `/api/v1/...`
- <20>?雿輻鍂 Nginx <20><EFBFBD><EFBFBD><E99A9E>蝏煺<E89D8F><EFBFBD><E686AD>
- <20>?撘<><E69298>𤑳㴓憓<E3B493><E68693><EFBFBD> Vite proxy 隞<><E99A9E><EFBFBD><EFBFBD>蝡?- <20>?<3F>煺漣<E785BA><EFBFBD><E887AC><EFBFBD> Nginx 隞<><E99A9E><EFBFBD><EFBFBD>蝡?
**摰𣬚<E691B0>霈曇恣**嚗?- <20>?<3F>𣳇<EFBFBD><F0A3B387><EFBFBD>撱箸𧒄瘜典<E7989C><E585B8><EFBFBD><E887AC><EFBFBD>
- <20>?<3F><EFBFBD>憟𦯀誨<F0A6AF80><E8AAA8><EFBFBD><EFBFBD>鍂鈭𤾸<E988AD><F0A4BEB8><EFBFBD><E7A983>煺漣
- <20>?<3F><EFBFBD><EFBFBD><E89D98><EFBFBD><EFBFBD>蝵莎<E89DB5>銝滢<E98A9D>韏硋<E99F8F><E7A18B><EFBFBD>蝵殷<E89DB5>
---
## 4. <20>𥕦遣 Nginx <20>滨蔭
### <20><> <20>𥕦遣 nginx.conf
**<2A>𩤃<EFBFBD> <20><EFBFBD>嚗𡁜銁 `frontend-v2/` <20><EFBFBD>銝见<E98A9D>撱?`nginx.conf`嚗<><E59A97><EFBFBD>?`frontend/`嚗?*
```nginx
# Nginx <20>滨蔭<E6BBA8><E894AD>辣 - AI銝游<E98A9D><E6B8B8>𠉛弦撟喳蝱<E596B3>滨垢<E6BBA8>滚𦛚
# <20><EFBFBD><EFBFBD><E48891>条恣 React SPA + <20><EFBFBD><EFBFBD><E99A9E><EFBFBD>𡒊垢 API
user nginx;
worker_processes auto; # <20>芸𢆡<E88AB8>寞旿 CPU <20><EFBFBD><E8A9A8><EFBFBD><E59597>?
# <20>𩤃<EFBFBD> <20><EFBFBD>颲枏枂<E69E8F>?stderr嚗𠄎AE 隡朞䌊<E69C9E>冽𤣰<E586BD><F0A4A3B0><EFBFBD>
error_log /dev/stderr warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # 瘥譍葵 worker 餈𤤿<E9A488><F0A4A4BF><EFBFBD><EFBFBD>憭扯<E686AD><E689AF>交㺭
use epoll; # Linux 銝衤蝙<E8A1A4>?epoll嚗<6C><E59A97><EFBFBD><EFBFBD>嚗?}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# <20><EFBFBD><E4BA99><EFBFBD>
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# <20>𩤃<EFBFBD> <20><EFBFBD>颲枏枂<E69E8F>?stdout嚗𠄎AE 隡朞䌊<E69C9E>冽𤣰<E586BD><F0A4A3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E89DA4><EFBFBD>蹱說嚗? access_log /dev/stdout main;
# <20><EFBFBD>隡睃<E99AA1>
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip <20>讠憬嚗<E686AC><E59A97>撠睲<E692A0>颲枏之撠𧶏<E692A0>
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;
gzip_disable "msie6";
# 銝𦠜虜<F0A6A09C>𡒊垢<F0A1928A>滚𦛚嚗㇂ackend Service嚗? upstream backend {
# <20>𩤃<EFBFBD> <20><EFBFBD>嚗朞<E59A97><E69C9E>𣬚<EFBFBD><F0A3AC9A><EFBFBD><E595A3><EFBFBD>蝵脫𧒄<E884AB><F0A79284><EFBFBD>𤜯<EFBFBD><EFBCB6><EFBFBD><E7AC94><EFBFBD><EFBFBD>蝡臬<E89DA1>蝵穃𧑐<E7A983><F0A79190>
# SAE <20>函蔡<E587BD><EFBFBD><E5A19A><EFBFBD><E69C9E><EFBFBD><E887AC><EFBFBD>瘜典<E7989C>嚗諹祕閫?Dockerfile
server ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT} fail_timeout=30s max_fails=3;
# 憒<><E68692><EFBFBD><EFBFBD>銝芸<E98A9D>蝡臬<E89DA1>靘页<E99D98>韐蠘蝸<E8A098><E89DB8>﹛嚗? # server 172.17.x.x:3001 weight=1;
# server 172.16.0.31:3001 weight=1;
keepalive 32; # 靽脲<E99DBD>餈墧𦻖瘙? }
server {
listen 80;
server_name _; # <20><EFBFBD><E4BA99><EFBFBD><EFBFBD><EFBFBD><E58CA7>?
# <20>寧𤌍敶𤏪<E695B6>React <20><>遣鈭抒<E988AD>嚗? root /usr/share/nginx/html;
index index.html;
# 摮㛖泵<E39B96>? charset utf-8;
# ==================== <20><EFBFBD><E8B9B1><EFBFBD>皞𣂼<E79A9E><F0A382BC>?====================
# 銝駁△<E9A781><EFBFBD>index.html嚗? 銝滨<E98A9D>摮? location = / {
try_files /index.html =404;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
# JS/CSS <20><>辣 - 撘箇<E69298>摮矋<E691AE><E79F8B><EFBFBD><EFBFBD>滚蒂 hash嚗? location ~* \.(js|css)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# <20><EFBFBD>/摮𦯀<E691AE><F0A6AF80><EFBFBD>辣 - 撘箇<E69298>摮? location ~* \.(png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# ==================== API <20><EFBFBD><EFBFBD><E99A9E> ====================
# <20>𡒊垢 API 隞<><E99A9E><EFBFBD><E59A97><EFBFBD><EFBFBD>蝵殷<E89DB5>
location /api/ {
# 隞<><E99A9E><EFBFBD><EFBFBD>蝡舀<E89DA1><E88880>? proxy_pass http://backend;
# 靽萘<E99DBD><E89098><EFBFBD>霂瑟<E99C82>靽⊥<E99DBD>
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;
# 頞<>𧒄<EFBFBD>滨蔭嚗㇁I 撖寡<E69296><E5AFA1><EFBFBD><EFBFBD>隞嗅<E99A9E><E59785><EFBFBD><EFBFBD><EFBFBD>埈𧒄颲<F0A79284>鵭嚗? proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# 蝻枏<E89DBB><E69E8F>滨蔭
proxy_buffering off; # <20>喲𡡒蝻枏<E89DBB><EFBFBD><E59A97><EFBFBD><EFBFBD>撘誩<E69298>摨䈑<E691A8>
proxy_request_buffering off; # <20><EFBFBD>憭扳<E686AD>隞嗡<E99A9E>隡?
# WebSocket <20><EFBFBD><EFBFBD><E59A97><EFBFBD>𨅯<EFBFBD>蝏剝<E89D8F><EFBFBD><E996AC>
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# <20>躰秤憭<E7A7A4><E686AD>
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_next_upstream_tries 2;
}
# ==================== SPA 頝舐眏<E88890><EFBFBD> ====================
# React Router 頝舐眏<E88890><EFBFBD><E9AE8B>
# <20><><EFBFBD><EFBFBD><E58EB0><EFBFBD>辣霂瑟<E99C82><E7919F><EFBFBD><E8B3AA>?index.html嚗𠄎PA <20><>瓲敹<E793B2><E695B9>
location / {
try_files $uri $uri/ /index.html;
# 蝳<>鍂蝻枏<E89DBB><EFBFBD><EFBFBD><EFBFBD><E79195>唳𧒄<E594B3>餅糓<E9A485><EFBFBD><E79195><EFBFBD><EFBFBD>圈△<E59C88><EFBFBD>
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# ==================== 摰匧<E691B0><E58CA7>惩𤐄 ====================
# <20><EFBFBD> Nginx <20><>𧋦<EFBFBD>? server_tokens off;
# 蝳<>迫霈輸䔮<E8BCB8><EFBFBD><E99EB1><EFBFBD>
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 蝳<>迫霈輸䔮<E8BCB8><EFBFBD><E5ADB5><EFBFBD>
location ~* \.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)$ {
deny all;
}
# ==================== <20>亙熒璉<E78692><E79289>?====================
# SAE <20>亙熒璉<E78692><E79289>亦垢<E4BAA6>? location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Nginx <20><EFBFBD><E59786>△嚗<E296B3>鍂鈭𡒊<E988AD><F0A1928A><EFBFBD>
location /nginx_status {
stub_status on;
access_log off;
# 隞<><E99A9E>霈詨<E99C88>蝵𤏸挪<F0A48FB8>? allow 10.0.0.0/8;
allow 172.17.0.0/16;
allow 192.168.0.0/16;
deny all;
}
# ==================== <20>躰秤憿菟𢒰 ====================
error_page 404 /index.html; # SPA 頝舐眏<E88890><EFBFBD><E9AE8B>
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
```
### <20><> <20>滨蔭<E6BBA8>喲睸<E596B2>寡圾<E5AFA1>?
#### 1. <20>𡒊垢<F0A1928A><EFBFBD><E595A3><EFBFBD><E586BD><EFBFBD>?
```nginx
upstream backend {
server ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT};
}
```
**<2A><EFBFBD>**嚗鐭ginx <20>滨蔭<E6BBA8><E894AD>辣銝齿𣈲<E9BDBF><F0A388B2>㴓憓<E3B493><E68693><EFBFBD><EFBFBD>?
**閫<><E996AB><EFBFBD><EFBFBD>**嚗𡁜銁 Docker <20>臬𢆡<E887AC>嗡蝙<E597A1>?`envsubst` <20>踵揢<E8B8B5><EFBFBD>蝚佗<E89D9A>霂西<E99C82>蝚?5 <20>?Dockerfile嚗剹<E59A97>?
#### 2. SPA 頝舐眏<E88890><EFBFBD>
```nginx
location / {
try_files $uri $uri/ /index.html;
}
```
**<2A><EFBFBD>**嚗?- <20><EFBFBD>霈輸䔮 `/dashboard` <20>?Nginx <20><EFBFBD><E69B86>?`dashboard` <20><><20>?餈𥪜<E9A488> `index.html`
- React Router <20>亦恣頝舐眏 <20>?皜脫<E79A9C> Dashboard 蝏<>
**憒<><E68692>瘝⊥<E7989D>餈嗘葵<E59798>滨蔭**嚗?- <20><EFBFBD><E586BD>瑟鰵 `/dashboard` <20>?Nginx <20>?404 <20>躰秤 <20>?
#### 3. <20><EFBFBD><EFBFBD><E99A9E><EFBFBD>滨蔭
```nginx
location /api/ {
proxy_pass http://backend;
}
```
**霂瑟<E99C82><EFBFBD><E7989A>**嚗?```
瘚讛<EFBFBD><EFBFBD><EFBFBD>GET /api/v1/projects
<20>?Nginx嚗𡁏𦻖<F0A1818F>嗉窈瘙? <20>?Nginx嚗䮝roxy_pass http://backend
<20>?<3F>𡒊垢<F0A1928A>滚𦛚嚗冴ttp://172.17.x.x:3001/api/v1/projects
<20>?<3F>𡒊垢餈𥪜<E9A488><F0A5AA9C>唳旿
<20>?Nginx 頧砍<E9A0A7>蝏蹱<E89D8F><EFBFBD>
```
**隡睃飵**嚗?- <20>?<3F>滨垢<E6BBA8><E59EA2><EFBFBD>蝡臬<E89DA1>皞琜<E79A9E><E7909C>賣糓 `https://your-domain.com`嚗?- <20>?<3F>𣳇<EFBFBD><EFBFBD><E686AD> CORS
- <20>?<3F>滨垢隞<E59EA2><E99A9E><EFBFBD>𣳇<EFBFBD><F0A3B387>仿<EFBFBD><E4BBBF>𡒊垢<F0A1928A><EFBFBD><E7AC94><EFBFBD>
#### 4. 蝻枏<E89DBB>蝑𣇉裦
| 韏<><E99F8F>蝐餃<E89D90> | 蝻枏<E89DBB>蝑𣇉裦 | <20><EFBFBD> |
|---------|---------|------|
| `index.html` | `no-cache` | 蝖桐<E89D96><E6A190><EFBFBD><E586BD><EFBFBD><E9A489><EFBFBD><E79195><EFBFBD><EFBFBD><EFBFBD><E59581>?|
| `.js` / `.css` | `1y` + `immutable` | <20><><EFBFBD>滚蒂 hash嚗<68><E59A97>摰嫣<E691B0><E5ABA3>?|
| <20><EFBFBD>/摮𦯀<E691AE> | `1y` + `immutable` | <20><EFBFBD><E8B9B1><EFBFBD>皞琜<E79A9E>銝滢<E98A9D><E6BBA2><EFBFBD> |
**銝箔<E98A9D>銋?index.html 銝滨<E98A9D>摮矋<E691AE>**
```
<EFBFBD><EFBFBD>擐𡝗活霈輸䔮嚗? <20>?銝贝蝸 index.html嚗<6C><E59A97><EFBFBD>?index-abc123.js嚗? <20>?<3F>函蔡<E587BD><EFBFBD><E59581>穿<EFBFBD>index.html <20>湔鰵嚗<E9B0B5><E59A97><EFBFBD>?index-xyz789.js嚗? <20>?<3F><EFBFBD><E586BD>齿活霈輸䔮嚗? - 憒<><E68692> index.html 鋡怎<E98BA1>摮?<3F>?隞滚<E99A9E>頧?index-abc123.js嚗<73><EFBFBD><E59482>𧋦嚗?<3F>? - 憒<><E68692> index.html 銝滨<E98A9D>摮?<3F>?<3F>㰘蝸 index-xyz789.js嚗<73><EFBFBD><E9B0B5>𧋦嚗?<3F>?```
---
## 5. <20><>遣 Docker <20>𨅯<EFBFBD>
### <20><> <20>𥕦遣 Dockerfile
**<2A>𩤃<EFBFBD> <20><EFBFBD>嚗𡁜銁 `frontend-v2/` <20><EFBFBD>銝见<E98A9D>撱?`Dockerfile`嚗<><E59A97><EFBFBD>?`frontend/`嚗?*
```dockerfile
# ==================== <20>嗆挾 1: <20><><EFBFBD>嗆挾 ====================
# <20>𩤃<EFBFBD> 雿輻鍂 Node 22嚗<32><E59A97><EFBFBD><E69298>𤑳㴓憓<E3B493><E68693><EFBFBD><EFBFBD><E6B99B><EFBFBD> package-lock.json <20><>𧋦<EFBFBD><EFBFBD>嚗?FROM node:22-alpine AS builder
# 霈曄蔭撌乩<E6928C><E4B9A9><EFBFBD>
WORKDIR /app
# 1. 憭滚<E686AD>靘肽<E99D98><E882BD><EFBFBD>
COPY package*.json ./
# 2. 摰㕑<E691B0>靘肽<E99D98>
# 雿輻鍂<E8BCBB><EFBFBD><E8B3A2>𨅯<EFBFBD><F0A885AF>𣳇<EFBFBD><F0A3B387><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
# RUN npm config set registry https://registry.npmmirror.com
RUN npm ci --only=production=false
# 3. 憭滚<E686AD>皞𣂷誨<F0A382B7>?COPY . .
# 4. <20><><EFBFBD>煺漣<E785BA><E6BCA3>𧋦
# <20>𩤃<EFBFBD> 瘜冽<E7989C>嚗𡁜<E59A97><F0A1819C>𣈯<EFBFBD><EFBFBD><EFBFBD><E98A81><EFBFBD>嗆釣<E59786>亦㴓憓<E3B493><E68693><EFBFBD>𧶏<EFBFBD><F0A7B68F><EFBFBD><E588BB>諹挽蝵?ARG
# ARG VITE_API_BASE_URL
# ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
RUN npm run build
# 撉諹<E69289><E8ABB9><EFBFBD>遣鈭抒<E988AD>
RUN ls -la /app/dist/
# ==================== <20>嗆挾 2: 餈鞱<E9A488><E99EB1>嗆挾 ====================
FROM nginx:1.25-alpine
# 摰㕑<E691B0><EFBFBD><E695B9>撌亙<E6928C><EFBFBD><E59A97><EFBFBD>祆𧒄<E7A586>箸㺭<E7AEB8><EFBFBD>
RUN apk add --no-cache \
bash \
gettext \
curl \
tzdata
# 霈曄蔭摰孵膥<E5ADB5>嗅躹銝箔<E98A9D>瘚瘀<E7989A><E79880><EFBFBD><E8A180><EFBFBD><E4BA99>園𡢿隡𡁏<E99AA1><F0A1818F>𦯀漪<F0A6AF80>園𡢿<E59C92>?8 撠𤩺𧒄嚗?RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
# <20>𥕦遣 Nginx <20>滨蔭<E6BBA8><EFBFBD>
RUN mkdir -p /etc/nginx/templates
# 1. 憭滚<E686AD> Nginx <20>滨蔭璅⊥踎嚗<E8B88E>𣈲<EFBFBD><F0A388B2>㴓憓<E3B493><E68693><EFBFBD>𤩺𤜯<F0A4A9BA><EFBFBD>
COPY nginx.conf /etc/nginx/templates/nginx.conf.template
# 2. 憭滚<E686AD><E6BB9A><EFBFBD>遣鈭抒<E988AD><E68A92>?Nginx 暺䁅恕<E48185><EFBFBD>
COPY --from=builder /app/dist /usr/share/nginx/html
# 3. <20>𥕦遣<F0A595A6>臬𢆡<E887AC>𡁏𧋦嚗<F0A78BA6><E59A97><EFBFBD><EFBFBD>㴓憓<E3B493><E68693><EFBFBD>𤩺𤜯<F0A4A9BA><EFBFBD>
RUN cat > /docker-entrypoint.sh <<'EOF'
#!/bin/bash
set -e
# <20>𩤃<EFBFBD> <20>喲睸嚗帋<E59A97>蝏䠷<E89D8F>霈文<E99C88><EFBFBD>撘箏<E69298><E7AE8F>?SAE <20><EFBFBD><E689B9><EFBFBD>蝵?# 憒<><E68692><EFBFBD><EFBFBD>蝵殷<E89DB5><E6AEB7>仿<EFBFBD><E4BBBF><EFBFBD><EFBFBD><EFBFBD><E7B6BD><EFBFBD>雿輻鍂<E8BCBB>躰秤<E8BAB0><E7A7A4><EFBFBD>蝡臬𧑐<E887AC><F0A79190>嚗?if [ -z "$BACKEND_SERVICE_HOST" ]; then
echo "<22>?ERROR: BACKEND_SERVICE_HOST environment variable is required!"
echo "Please configure it in SAE console with backend internal IP (e.g., 172.16.0.30)"
exit 1
fi
if [ -z "$BACKEND_SERVICE_PORT" ]; then
echo "<22>𩤃<EFBFBD> WARNING: BACKEND_SERVICE_PORT not set, using default: 3001"
export BACKEND_SERVICE_PORT=3001
fi
echo "============================================"
echo "Starting Frontend Nginx Service"
echo "Backend Service: ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT}"
echo "Container Timezone: $(cat /etc/timezone)"
echo "Current Time: $(date)"
echo "============================================"
# 雿輻鍂 envsubst <20>踵揢 Nginx <20>滨蔭銝剔<E98A9D><E58994><EFBFBD><E887AC><EFBFBD>
envsubst '${BACKEND_SERVICE_HOST} ${BACKEND_SERVICE_PORT}' \
< /etc/nginx/templates/nginx.conf.template \
> /etc/nginx/nginx.conf
# 撉諹<E69289> Nginx <20>滨蔭
nginx -t
# <20>臬𢆡 Nginx
exec nginx -g 'daemon off;'
EOF
RUN chmod +x /docker-entrypoint.sh
# <20>亙熒璉<E78692><E79289>?HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD curl -f http://localhost/health || exit 1
# <20>湧蠧蝡臬藁
EXPOSE 80
# <20>臬𢆡<E887AC>賭誘
ENTRYPOINT ["/docker-entrypoint.sh"]
```
### <20><> <20>𥕦遣 .dockerignore
**<2A>𩤃<EFBFBD> <20><EFBFBD>嚗𡁜銁 `frontend-v2/` <20><EFBFBD>銝见<E98A9D>撱?`.dockerignore`嚗<><E59A97><EFBFBD>?`frontend/`嚗?*
```
# Node.js
node_modules
npm-debug.log
yarn-error.log
.npm
.yarn
# 撘<><E69298><EFBFBD>隞?.env
.env.*
*.local
# <20><>遣鈭抒<E988AD>嚗㇄ockerfile 銝凋<E98A9D><E5878B>齿鰵<E9BDBF><E9B0B5><EFBFBD>嚗?dist
# 瘚贝<E7989A><E8B49D><EFBFBD>
test
tests
*.test.ts
*.test.tsx
*.spec.ts
*.spec.tsx
coverage
.nyc_output
# <20><><EFBFBD>䔶葩<E494B6><EFBFBD>隞?docs
*.md
!README.md
.vscode
.idea
.DS_Store
Thumbs.db
# Git
.git
.gitignore
.gitattributes
# CI/CD
.github
.gitlab-ci.yml
.travis.yml
# <20><EFBFBD>
*.log
logs
# 銝湔𧒄<E6B994><F0A79284>
temp
tmp
*.swp
*.swo
*~
# 蝻𤥁<E89DBB><F0A4A581><EFBFBD>蝵?.editorconfig
.prettierrc
.eslintrc*
# TypeScript <20>滨蔭嚗<E894AD><E59A97><EFBFBD>?tsconfig.json嚗<6E><E59A97>隞硋蕭<E7A18B><EFBFBD>
tsconfig.tsbuildinfo
# Vite
.vite
vite.config.*.timestamp-*
```
### <20><> Dockerfile <20>喲睸霈曇恣閫<E681A3><E996AB>
#### 1. 憭𡁻𧫴畾菜<E795BE>撱綽<E692B1><E7B6BD><EFBFBD><E8AAA9>𨅯<EFBFBD>雿梶妖嚗?
```dockerfile
# <20>嗆挾 1嚗𡁏<E59A97>撱綽<E692B1>Node.js <20><EFBFBD>嚗?FROM node:22-alpine AS builder # <20>𩤃<EFBFBD> 雿輻鍂 Node 22嚗<32><E59A97><EFBFBD><E69298>𤑳㴓憓<E3B493><E68693><EFBFBD><EFBFBD>
# 雿梶妖嚗鰺200MB嚗<42><EFBFBD><EFBFBD>
RUN npm run build
# <20>嗆挾 2嚗朞<E59A97>銵䕘<E98AB5>Nginx <20><EFBFBD>嚗?FROM nginx:1.25-alpine
# 雿梶妖嚗鰺25MB嚗<42><E59A97><EFBFBD><E89D8F>
COPY --from=builder /app/dist /usr/share/nginx/html
```
**<2A><><EFBFBD>撖寞<E69296>**嚗?- <20>?<3F>閖𧫴畾菜<E795BE>撱綽<E692B1>~700MB嚗<42><E59A97><EFBFBD>?Node.js + npm + <20><><EFBFBD><EFBFBD>韏吔<E99F8F>
- <20>?憭𡁻𧫴畾菜<E795BE>撱綽<E692B1>~40-60MB嚗<42><E59A97> Nginx + <20><EFBFBD><E8B9B1><EFBFBD>隞塚<E99A9E>
**銝箔<E98A9D><EFBFBD><EFBFBD>?Node 22**嚗?- 撘<><E69298>𤑳㴓憓<E3B493><EFBFBD>?Node 22.18.0+
- `package-lock.json` <20>?Node 22 <20><><EFBFBD>嚗𡿨ockfile version 3嚗?- Node 18 <20><EFBFBD>撖潸稲靘肽<E99D98>摰㕑<E691B0>霅血<E99C85><E8A180>硋仃韐?- 靽肽<E99DBD><E882BD><EFBFBD><EFBFBD><EFBFBD>銝𤾸<E98A9D><F0A4BEB8>𤑳㴓憓<E3B493><E68693><EFBFBD><EFBFBD><E585B6>?
#### 2. <20><EFBFBD><E887AC><EFBFBD><E3979B>踵揢<E8B8B5><EFBFBD>
```bash
# <20>臬𢆡<E887AC>𡁏𧋦
envsubst '${BACKEND_SERVICE_HOST} ${BACKEND_SERVICE_PORT}' \
< /etc/nginx/templates/nginx.conf.template \
> /etc/nginx/nginx.conf
```
**瘚<><E7989A>**嚗?```
nginx.conf.template嚗<65><EFBFBD><EFBFBD>:
server ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT};
<EFBFBD>?envsubst <20>踵揢
nginx.conf嚗<66><E59A97><EFBFBD><E89D8F>蝵殷<E89DB5>:
server 172.17.x.x:3001;
```
#### 3. <20>亙熒璉<E78692><E79289>?
```dockerfile
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD curl -f http://localhost/health || exit 1
```
**SAE 隡帋蝙<E5B88B><EFBFBD>銝芸<E98A9D>摨瑟<E691A8><E7919F>?*嚗?- <20>?摰孵膥<E5ADB5>臬𢆡<E887AC>?30 蝘鍦<E89D98>憪𧢲<E686AA><F0A7A2B2>?- <20>?瘥?30 蝘埝<E89D98><E59F9D><EFBFBD>甈?- <20>?餈䂿賒憭梯揖 3 甈?<3F>?<3F><>扇銝箔<E98A9D><E7AE94>亙熒 <20>?SAE <20>滚鍳摰孵膥
---
## 6. <20>砍𧑐瘚贝<E7989A>撉諹<E69289>
### 甇仿炊 1嚗𡁏<E59A97>撱粹<E692B1><E7B2B9>?
```bash
# <20>𩤃<EFBFBD> <20><EFBFBD>嚗帋蝙<E5B88B>?frontend-v2 <20><EFBFBD><EFBFBD><E59A97><EFBFBD>?frontend嚗?cd frontend-v2
# 蝖株恕敶枏<E695B6><E69E8F><EFBFBD><EFBFBD>
pwd
# 摨磰砲颲枏枂嚗?../AIclinicalresearch/frontend-v2
# 蝖株恕 package.json 摮睃銁
cat package.json | grep '"name"'
# 摨磰砲颲枏枂嚗?name": "frontend-v2"
# <20><><EFBFBD>𨅯<EFBFBD><EFBFBD><E59A97>閬?3-5 <20><><EFBFBD>嚗?docker build -t frontend-service:v1.0.0 .
# <20><EFBFBD><E4BAA6>𨅯<EFBFBD>憭批<E686AD>
docker images frontend-service:v1.0.0
# 憸<><E686B8>憭批<E686AD>嚗鰺40-60MB嚗㇁lpine <20><EFBFBD><E7AE87>𨅯<EFBFBD> + <20><>遣鈭抒<E988AD>嚗?
# <20><EFBFBD><E4BAA6>𨅯<EFBFBD>霂行<E99C82>
docker inspect frontend-service:v1.0.0 | grep -A 5 "Size"
```
**憒<><E68692><EFBFBD><EFBFBD>遣憭梯揖**嚗?
```bash
# 撣貉<E692A3><E8B289><EFBFBD> 1嚗䭰pm install 頞<>𧒄
# 閫<><E996AB>嚗帋蝙<E5B88B>典𤙴<E585B8><F0A499B4><EFBFBD><EFBFBD>𤩺<EFBFBD>
# <20>?Dockerfile <20>?npm ci 銋见<E98A8B>瘛餃<E7989B>嚗?RUN npm config set registry https://registry.npmmirror.com
# 撣貉<E692A3><E8B289><EFBFBD> 2嚗𡁏<E59A97>撱箔漣<E7AE94>拐蛹蝛?# 閫<><E996AB>嚗𡁏<E59A97><F0A1818F>?package.json 銝剔<E98A9D> build <20>𡁏𧋦
cat package.json | grep '"build"'
# 摨磰砲颲枏枂嚗? "build": "tsc -b && vite build",
# 撣貉<E692A3><E8B289><EFBFBD> 3嚗関ypeScript 蝻𤥁<E89DBB><F0A4A581>躰秤
# 閫<><E996AB>嚗𡁏<E59A97><F0A1818F>交糓<E4BAA4><EFBFBD>蝐餃<E89D90><E9A483>躰秤
npm run build # <20>?Docker 憭硋<E686AD>瘚贝<E7989A><E8B49D><EFBFBD>
# 撣貉<E692A3><E8B289><EFBFBD> 4嚗䭰ginx.conf <20><><EFBFBD><EFBFBD><E69B86>?# 閫<><E996AB>嚗𡁶靽?nginx.conf <20>?frontend-v2/ <20><EFBFBD>銝?ls nginx.conf
```
### 甇仿炊 2嚗𡁏𧋦<F0A1818F><EFBFBD>銵峕<E98AB5>霂?
```bash
# 餈鞱<E9A488>摰孵膥嚗<E886A5><E59A97><EFBFBD><E996AC>摰𡁜<E691B0>蝡臬𧑐<E887AC><F0A79190>嚗?docker run -d \
--name frontend-test \
-p 8080:80 \
-e BACKEND_SERVICE_HOST=host.docker.internal \
-e BACKEND_SERVICE_PORT=3001 \
frontend-service:v1.0.0
# <20><EFBFBD><E4BAA6>臬𢆡<E887AC><EFBFBD>
docker logs frontend-test
# 摨磰砲<E7A3B0><EFBFBD>嚗?# ============================================
# Starting Frontend Nginx Service
# Backend Service: host.docker.internal:3001
# ============================================
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
```
**瘜冽<E7989C>**嚗䫤host.docker.internal` <20>?Docker Desktop <20><EFBFBD><E5AF9E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3B5AA><EFBFBD><EFBFBD>摰蹂蜓<E8B982><EFBFBD>?
### 甇仿炊 3嚗𡁏<E59A97>霂閖<E99C82><E99696><EFBFBD><EFBFBD>皞鞱挪<E99EB1>?
```bash
# 瘚贝<E7989A>銝駁△
curl http://localhost:8080/
# 憸<><E686B8>餈𥪜<E9A488>嚗?# <!doctype html>
# <html lang="zh-CN">
# ...
# </html>
# 瘚贝<E7989A><E8B49D>亙熒璉<E78692><E79289>?curl http://localhost:8080/health
# 憸<><E686B8>餈𥪜<E9A488>嚗?# healthy
```
### 甇仿炊 4嚗𡁏<E59A97>霂?SPA 頝舐眏
```bash
# 霈輸䔮銝滚<E98A9D><E6BB9A><EFBFBD>頝舐眏嚗<E79C8F><E59A97>霂亥<E99C82><E4BAA5>?index.html嚗諹<E59A97><EFBFBD><E494B6>?404嚗?curl http://localhost:8080/dashboard
# 憸<><E686B8>餈𥪜<E9A488>嚗?# <!doctype html>
# <html lang="zh-CN">
# ...嚗<><E59A97>銝駁△<E9A781><EFBFBD>嚗?# </html>
# <20><EFBFBD><E494B6><EFBFBD>
# <html>
# <head><title>404 Not Found</title></head>
# ...嚗𠃊ginx 暺䁅恕 404 憿菟𢒰嚗?```
### 甇仿炊 5嚗𡁏<E59A97>霂訫<E99C82><E8A8AB>睲誨<E79DB2><E8AAA8><EFBFBD><EFBFBD>喲睸瘚贝<E7989A>嚗?
**<2A>齿<EFBFBD>**嚗𡁶靽脲𧋦<E884B2><EFBFBD>蝡舀<E89DA1><E88880>`http://localhost:3001` 餈鞱<E9A488><E99EB1>?
```bash
# <20><EFBFBD><E69C9E>滨垢 Nginx 霈輸䔮<E8BCB8>𡒊垢 API
curl http://localhost:8080/api/v1/health
# 憸<><E686B8>餈𥪜<E9A488><EFBFBD><E59A97>蝡舐<E89DA1><E88890><EFBFBD>嚗㚁<E59A97>
{
"status": "healthy",
"timestamp": "2025-12-13T10:30:00.000Z",
"database": {
"status": "connected"
}
}
# <20><EFBFBD> Nginx <20><EFBFBD>嚗𣬚霈支誨<E694AF><E8AAA8><EFBFBD><EFBFBD>?docker logs frontend-test 2>&1 | grep "/api/v1/health"
# 摨磰砲<E7A3B0><EFBFBD>嚗?# 172.17.0.1 - - [13/Dec/2025:10:30:00 +0000] "GET /api/v1/health HTTP/1.1" 200 123
```
### 甇仿炊 6嚗𡁏<E59A97><EFBFBD>膥瘚贝<E7989A>
<EFBFBD><EFBFBD>瘚讛<EFBFBD><EFBFBD><EFBFBD>霈輸䔮 `http://localhost:8080`
**瘚贝<E7989A><EFBFBD><E79A9C>**嚗?- [ ] 憿菟𢒰<E88F9F>賣迤撣詨<E692A3>頧踝<E9A0A7>銝齿糓蝛箇蒾憿蛛<E686BF>
- [ ] <20><EFBFBD><EFBFBD><EFBFBD>曄內嚗㇃SS <20>㰘蝸<E3B098>𣂼<EFBFBD>嚗?- [ ] JavaScript <20><EFBFBD><EFBFBD>虜嚗<E8999C>漱鈭埝迤撣賂<E692A3>
- [ ] <20>瑟鰵憿菟𢒰銝滢<E98A9D> 404嚗𠄎PA 頝舐眏甇<E79C8F>虜嚗?- [ ] 瘚讛<E7989A><E8AE9B><EFBFBD><E585B8>𤏸<EFBFBD><F0A48FB8><EFBFBD>?Network <20><>倌嚗? - [ ] API 霂瑟<E99C82>頝臬<E9A09D><E887AC>?`/api/v1/...`<EFBFBD>㮾撖寡楝敺<EFBFBD><EFBFBD>
- [ ] API 霂瑟<E99C82><E7919F><EFBFBD><E59786>糓 200嚗<30><EFBFBD><E8AAA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- [ ] 瘝⊥<E7989D> CORS <20>躰秤
### 甇仿炊 7嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD>霂訫捆<E8A8AB>?
```bash
# <20>𨀣迫撟嗅<E6929F><E59785><EFBFBD>霂訫捆<E8A8AB>?docker stop frontend-test
docker rm frontend-test
```
---
## 7. <20><EFBFBD><E588B8><EFBFBD> ACR
### 甇仿炊 1嚗𡁶蒈敶?ACR
```bash
# <20><EFBFBD><EFBFBD><EFBFBD>?ACR 撖<><E69296>嚗䔶<E59A97><E494B6>舫燵<E888AB><EFBFBD>韐血噡撖<E599A1><E69296>嚗?docker login --username=your-aliyun-account registry.cn-beijing.aliyuncs.com
# 颲枏<E9A2B2><EFBFBD><E69296><EFBFBD>𡒊<EFBFBD><F0A1928A><EFBFBD>
# Login Succeeded
```
### 甇仿炊 2嚗𡁏<E59A97>霈圈<E99C88><E59C88>?
```bash
# <20><EFBFBD>嚗鬏egistry<72><EFBFBD>/<2F><EFBFBD>蝛粹𡢿/隞枏<E99A9E><E69E8F>?<3F><>𧋦<EFBFBD>?docker tag frontend-service:v1.0.0 \
registry.cn-beijing.aliyuncs.com/clinical-research/frontend-service:v1.0.0
# <20>峕𧒄<E5B395><EFBFBD>銝?latest <20><>
docker tag frontend-service:v1.0.0 \
registry.cn-beijing.aliyuncs.com/clinical-research/frontend-service:latest
```
### 甇仿炊 3嚗𡁏綫<F0A1818F><E7B6AB><EFBFBD><EFBFBD>?
```bash
# <20><EFBFBD><E588B8><EFBFBD>摰𡁶<E691B0><F0A181B6>?docker push registry.cn-beijing.aliyuncs.com/clinical-research/frontend-service:v1.0.0
# <20><EFBFBD>?latest
docker push registry.cn-beijing.aliyuncs.com/clinical-research/frontend-service:latest
# <20><EFBFBD><E588B8><EFBFBD>蝔钅<E89D94>閬?1-3 <20><><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>撠𧶏<E692A0>
```
### 甇仿炊 4嚗𡁻<E59A97><EFBFBD><EFBFBD><E7B6AB><EFBFBD><EFBFBD>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鈭烐綉<EFBFBD>嗅蝱 <20>?摰孵膥<E5ADB5>𨅯<EFBFBD><F0A885AF>滚𦛚 <20>?<3F>𨅯<EFBFBD>隞枏<E99A9E> <20>?`frontend-service`
- 摨磰砲<E7A3B0><EFBFBD><E8A781><EFBFBD>𧋦嚗䫤v1.0.0` <20>?`latest`
- <20>𨅯<EFBFBD>憭批<E686AD>嚗鰺30-50MB
- <20><EFBFBD><E588B8>𧒄<EFBFBD><EFBFBD><E6B99B>𡁏<EFBFBD><F0A1818F><EFBFBD>𧒄<EFBFBD>?
---
## 8. SAE 摨𠉛鍂<F0A0899B>滨蔭
### 甇仿炊 1嚗𡁜<E59A97>撱箏<E692B1><E7AE8F>?
**<2A><EFBFBD>鈭烐綉<E78390>嗅蝱** <20>?**SAE** <20>?**摨𠉛鍂<F0A0899B>𡑒”** <20>?**<2A>𥕦遣摨𠉛鍂**
| <20>滨蔭憿?| <20>?| 霂湔<E99C82> |
|-------|-----|------|
| **摨𠉛鍂<F0A0899B>滨妍** | `frontend-service` | <20>滨垢<E6BBA8>滚𦛚 |
| **<EFBFBD><EFBFBD>蝛粹𡢿** | <20>㗇𥋘撌脣<E6928C>撱箇<E692B1><E7AE87><EFBFBD>蝛粹𡢿 | 銝𤾸<E98A9D>蝡舀<E89DA1><E88880><EFBFBD><EFBFBD><E98A9D><EFBFBD>蝛粹𡢿 |
| **VPC** | <20>㗇𥋘<E39787>𡒊垢<F0A1928A><E59EA2><EFBFBD>?VPC | 敹<>◆銝𤾸<E98A9D>蝡臬銁<E887AC><EFBFBD> VPC |
| **鈭斗揢<E69697>?* | <20>㗇𥋘<E39787>舐鍂<E88890>?| 撱箄悅憭𡁜虾<F0A1819C>典躹 |
| **摨𠉛鍂摰硺<E691B0><EFBFBD>** | 0.5<EFBFBD>?G | <20>滨垢Nginx<6E>删鍂韏<E98D82><E99F8F><EFBFBD><E695BA> |
| **摰硺<E691B0><E7A1BA><EFBFBD>** | 2 | <20><>撠?2 銝芸<E98A9D>靘页<E99D98>擃睃虾<E79D83><EFBFBD> |
**銝箔<E98A9D><EFBFBD><EFBFBD><E898A8>閬?0.5<EFBFBD>?G嚗?*
| <20>滚𦛚蝐餃<E89D90> | <20><EFBFBD><EFBFBD>聢 | <20><EFBFBD> |
|---------|---------|------|
| Node.js <20>𡒊垢 | 2<>?G | <20><><EFBFBD><E996AC><EFBFBD>?AI 撖寡<E69296><E5AFA1><EFBFBD><EFBFBD><EFBFBD><E6A180>亥砭 |
| Python 敺格<E695BA><E6A0BC>?| 2<>?G | PDF <20>𣂼<EFBFBD><F0A382BC>?CPU 撖<><E69296><EFBFBD>?|
| **Nginx <20>滨垢** | **0.5<EFBFBD>?G** | **隞<><E99A9E>靘偦<E99D98><E581A6><EFBFBD><EFBFBD>隞塚<E99A9E><EFBFBD><E798A8><EFBFBD>撠?* |
### 甇仿炊 2嚗𡁻<E59A97>蝵桅<E89DB5><E6A185>?
| <20>滨蔭憿?| <20>?|
|-------|-----|
| **<EFBFBD>𨅯<EFBFBD>蝐餃<EFBFBD>** | 摰孵膥<E5ADB5>𨅯<EFBFBD><F0A885AF>滚𦛚隡<F0A69B9A><E99AA1><EFBFBD><EFBFBD><EFBFBD>靘?|
| **<EFBFBD>𨅯<EFBFBD>隞枏<EFBFBD>** | `registry.cn-beijing.aliyuncs.com/clinical-research/frontend-service` |
| **<EFBFBD>𨅯<EFBFBD><EFBFBD><EFBFBD>𧋦** | `v1.0.0` |
| **<EFBFBD>𨅯<EFBFBD><EFBFBD><EFBFBD>蝑𣇉裦** | <20>餅糓<E9A485><EFBFBD><E58CA7>𨅯<EFBFBD> |
### 甇仿炊 3嚗𡁻<E59A97>蝵桃垢<E6A183>?
| <20>滨蔭憿?| <20>?|
|-------|-----|
| **摰孵膥蝡臬藁** | `80` |
| **<EFBFBD>讛悅** | TCP |
### 甇仿炊 4嚗𡁻<E59A97>蝵桃㴓憓<E3B493><E68693><EFBFBD>𧶏<EFBFBD><F0A7B68F>喲睸甇仿炊嚗?
**<2A>𩤃<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>嚗𡁜<E59A97>憿駁<E686BF>蝵桀<E89DB5>蝡舀<E89DA1><E88880><EFBFBD><E288A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>坔捆<E59D94>典鍳<E585B8>典仃韐?*
#### <20><EFBFBD><E79195>𡒊垢<F0A1928A><E59EA2><EFBFBD><EFBFBD><EFBFBD>
1. **<EFBFBD><EFBFBD> SAE <20><EFBFBD><E689B9>?* <20>?**摨𠉛鍂<F0A0899B>𡑒”** <20>?**backend-service** <20>?**摨𠉛鍂霂行<E99C82>**
2. **<EFBFBD><EFBFBD>"摨𠉛鍂霈輸䔮<E8BCB8>滨蔭"** <20>?**VPC <20><><EFBFBD>霈輸䔮<E8BCB8><EFBFBD>**
憭滚<E686AD><E6BB9A><EFBFBD>嚗峕聢撘誯<E69298>𡁜虜<F0A1819C><EFBFBD>
```
172.16.0.30:3001
```
#### <20>滨蔭<E6BBA8><EFBFBD><E887AC><EFBFBD>
```bash
# <20>𩤃<EFBFBD><><EFBFBD>滨蔭嚗<E894AD><EFBFBD>坔捆<E59D94>典鍳<E585B8>典仃韐伐<E99F90>
BACKEND_SERVICE_HOST=172.17.x.x
# <20><EFBFBD><EFBFBD>蝵殷<E89DB5>暺䁅恕 3001嚗?BACKEND_SERVICE_PORT=3001
```
**<2A>𩤃<EFBFBD> <20><EFBFBD>霂湔<E99C82>**嚗?- `BACKEND_SERVICE_HOST` **敹<><EFBFBD>滨蔭**嚗<><EFBFBD>坔捆<E59D94>典鍳<E585B8>冽𧒄隡𡁏𥁒<F0A1818F><EFBFBD><E4A0B7><EFBFBD>?- 銝滩<E98A9D>雿輻鍂銝餅㦤<E9A485><EFBFBD>憒?`backend-service`嚗㚁<E59A97>SAE <20><EFBFBD><E888AA><EFBFBD><EFBFBD><E996AB>
- 敹<>◆雿輻鍂<E8BCBB>𡒊垢<F0A1928A>滚𦛚<E6BB9A>?*<2A><><EFBFBD> IP <20><EFBFBD>**嚗<><E59A97> SAE <20><EFBFBD><E689B9>啗繮<E59597><EFBFBD>
**銝箔<E98A9D><EFBFBD><E98A8B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?Host <20>?Port嚗?*
```nginx
# nginx.conf 銝剔<E98A9D><E58994>滨蔭嚗?upstream backend {
server ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT};
}
# 憒<><E68692>銝齿<E98A9D><E9BDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?server ${BACKEND_SERVICE_URL}; # <20>?<3F><EFBFBD><EFBFBD><E996AB> http://172.16.0.30:3001
# <20><><EFBFBD><EFBFBD>𠬍<EFBFBD>
server 172.17.x.x:3001; # <20>?甇<>
```
### 甇仿炊 5嚗𡁻<E59A97>蝵桀<E89DB5>摨瑟<E691A8><E7919F>?
**SAE <20><EFBFBD><E689B9>?* <20>?**摨𠉛鍂<F0A0899B>滨蔭** <20>?**<2A>亙熒璉<E78692><E79289>?*
| <20>滨蔭憿?| <20>?| 霂湔<E99C82> |
|-------|-----|------|
| **璉<><E79289>交䲮撘?* | HTTP 霂瑟<E99C82> | |
| **璉<><E79289>亥楝敺?* | `/health` | Nginx <20>亙熒璉<E78692><E79289>亦垢<E4BAA6>?|
| **璉<><E79289>亦垢<E4BAA6>?* | 80 | 銝𤾸捆<F0A4BEB8>函垢<E587BD><E59EA2><EFBFBD><EFBFBD>?|
| **璉<><E79289><EFBFBD>霈?* | HTTP | |
| **<2A><EFBFBD>撱嗉<E692B1>** | 30 蝘?| Nginx <20>臬𢆡敺<F0A286A1>翰 |
| **璉<><E79289>仿𡢿<E4BBBF>?* | 10 蝘?| |
| **頞<>𧒄<EFBFBD>園𡢿** | 3 蝘?| |
| **銝滚<E98A9D>摨琿<E691A8><E790BF>?* | 3 甈?| 餈䂿賒憭梯揖 3 甈⊥<E79488>霈唬蛹銝滚<E98A9D>摨?|
| **<2A>亙熒<E4BA99><E78692><EFBFBD>?* | 2 甈?| 餈䂿賒<E482BF>𣂼<EFBFBD> 2 甈⊥<E79488>霈唬蛹<E594AC>亙熒 |
### 甇仿炊 6嚗𡁻<E59A97>蝵桀撕<E6A180>找撓蝻?
**SAE <20><EFBFBD><E689B9>?* <20>?**摨𠉛鍂<F0A0899B>滨蔭** <20>?**撘寞<E69298>找撓蝻?*
| <20>滨蔭憿?| <20>?| 霂湔<E99C82> |
|-------|-----|------|
| **<2A><>撠誩<E692A0>靘𧢲㺭** | 2 | 擃睃虾<E79D83><EFBFBD>霂?|
| **<2A><>憭批<E686AD>靘𧢲㺭** | 5 | <20>滨垢瘚<E59EA2><E7989A>𢆡<EFBCB7>𡁜虜銝滚之 |
| **<2A>拙捆<E68B99>∩辣** | CPU > 60% <20><>賒 3 <20><><EFBFBD> | Nginx 敺<><E695BA>颲曉<E9A2B2>餈嗘葵<E59798><E891B5><EFBFBD>?|
| **蝻拙捆<E68B99>∩辣** | CPU < 20% <20><>賒 5 <20><><EFBFBD> | |
**瘜冽<E7989C>**嚗𡁜<E59A97>蝡?Nginx 敺<><E695BA><EFBFBD><EFBFBD><EFBFBD><E996AC>摰對<E691B0><E5B08D>牐蛹<E78990><EFBFBD><E8B9B1><EFBFBD>隞嗆<E99A9E><E59786><EFBFBD><E28AA5><EFBFBD><E59C92><EFBFBD><EFBFBD>?
### 甇仿炊 7嚗𡁻<E59A97>蝵桀<E89DB5>蝵𤏸挪<F0A48FB8><EFBFBD><E6AEB7><EFBFBD><EFBFBD>
**SAE <20><EFBFBD><E689B9>?* <20>?**摨𠉛鍂<F0A0899B>滨蔭** <20>?**摨𠉛鍂霈輸䔮<E8BCB8>滨蔭**
#### <20>厰★ A嚗帋蝙<E5B88B>?SAE <20>𣂷<EFBFBD><F0A382B7><EFBFBD><EFBFBD>蝵穃𧑐<E7A983><F0A79190><EFBFBD><EFBFBD><EFBFBD>霂𤏪<E99C82>
- **隡睃飵**嚗𡁜<E59A97>韐對<E99F90>蝡见朖<E8A781>舐鍂
- **<2A><>飵**嚗𡁜<E59A97><F0A1819C>漤𠗕霈堆<E99C88>HTTPS 霂<><EFBFBD>?SAE <20>?
#### <20>厰★ B嚗𡁶<E59A97>摰朞䌊摰帋<E691B0><E5B88B><EFBFBD><EFBFBD><E59A97>鈭扳綫<E689B3><EFBFBD>
1. **瘛餃<E7989B><E9A483><EFBFBD><EFBFBD><E996AB>**嚗? ```
your-domain.com <20>? CNAME <20>? frontend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com
```
2. **<2A>滨蔭 HTTPS 霂<>髡**嚗? - 銝𠹺<E98A9D> SSL 霂<>髡嚗<E9ABA1><E59A97>雿輻鍂<E8BCBB>滩晶霂<E699B6>髡嚗?
3. **撘箏<E69298> HTTPS**嚗? ```nginx
# <20>?nginx.conf 銝剜溶<E5899C>𣳇<EFBFBD>摰𡁜<E691B0>
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
```
### 甇仿炊 8嚗𡁻<E59A97>蝵脣<E89DB5><E884A3>?
<EFBFBD>孵稬"<22>函蔡"<22>厰僼嚗玺AE 撠<><E692A0>
1. 隞?ACR <20><EFBFBD><E58CA7>𨅯<EFBFBD>嚗ǚ30 蝘𡜐<E89D98>
2. <20>臬𢆡摰孵膥摰硺<E691B0>嚗ǚ30 蝘𡜐<E89D98>
3. <20><EFBFBD><E689AF>亙熒璉<E78692><E79289><EFBFBD>~30 蝘𡜐<E89D98>
4. 瘚<><E7989A><EFBFBD><EFBFBD>揢嚗ǚ10 蝘𡜐<E89D98>
**<2A><EFBFBD>埈𧒄**嚗𡁶漲 2 <20><><EFBFBD>
---
## 9. 蝡臬<E89DA1>蝡舀<E89DA1>霂?
### 甇仿炊 1嚗朞繮<E69C9E><EFBFBD><E7A18B>刻挪<E588BB>桀𧑐<E6A180><F0A79190>
**SAE <20><EFBFBD><E689B9>?* <20>?**摨𠉛鍂霂行<E99C82>** <20>?**摨𠉛鍂霈輸䔮<E8BCB8>滨蔭**
憭滚<EFBFBD><EFBFBD><EFBFBD>霈輸䔮<EFBFBD><EFBFBD>嚗?```
https://frontend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com
```
### 甇仿炊 2嚗𡁏<E59A97>霂蓥蜓憿萄<E686BF>頧?
```bash
# 雿輻鍂 curl 瘚贝<E7989A>
curl -I https://frontend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/
# 憸<><E686B8>餈𥪜<E9A488>嚗?# HTTP/2 200
# content-type: text/html
# cache-control: no-cache, no-store, must-revalidate
# ...
# 摰峕㟲<E5B395><EFBFBD>
curl https://frontend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/ | head -n 10
# 摨磰砲<E7A3B0><EFBFBD> HTML <20><>
```
### 甇仿炊 3嚗𡁏<E59A97><EFBFBD>膥摰峕㟲瘚贝<E7989A>
<EFBFBD><EFBFBD>瘚讛<EFBFBD><EFBFBD><EFBFBD>霈輸䔮<EFBFBD>滨垢<EFBFBD><EFBFBD>嚗?
#### 瘚贝<E7989A><EFBFBD><E79A9C> A嚗𡁻△<F0A181BB>抅蝖<E68A85><E89D96><EFBFBD>
- [ ] **銝駁△<E9A781>賣迤撣詨<E692A3>頧?*
- <20><EFBFBD><E8A781><EFBFBD>憿菟𢒰<E88F9F><EFBFBD>憿? - <20><EFBFBD><EFBFBD><EFBFBD>曄內嚗<E585A7><E59A97><EFBFBD>舐滲<E88890><E6BBB2>𧋦嚗? - <20><EFBFBD><E69B84><EFBFBD><EFBFBD><E3A69B>迤撣豢遬蝷?
- [ ] **頝舐眏頝唾蓮甇<E893AE>虜**
- <20>孵稬撖潸⏛<E6BDB8>𨅯<EFBFBD>嚗𪄇RL <20><EFBFBD>
- 憿菟𢒰<E88F9F><F0A292B0><EFBFBD>湔鰵
- 瘚讛<E7989A><E8AE9B><EFBFBD><E585B8><EFBFBD>/<2F><EFBFBD><E6BBA9>厰僼甇<E583BC>虜撌乩<E6928C>
- [ ] **<2A>瑟鰵憿菟𢒰銝齿𥁒<E9BDBF>?*
- 霈輸䔮 `/dashboard`
- <20>?F5 <20>瑟鰵
- 憿菟𢒰甇<F0A292B0><EFBFBD>曄內嚗<E585A7><E59A97><EFBFBD>?404嚗?
#### 瘚贝<E7989A><EFBFBD><E79A9C> B嚗鋫PI 靚<>鍂瘚贝<E7989A>
- [ ] **<2A><EFBFBD><E9A483><EFBFBD>**
- 颲枏<E9A2B2><E69E8F><EFBFBD><E586BD><EFBFBD><EFBFBD><E69296>
- <20>孵稬<E5ADB5><EFBFBD>
- <20><EFBFBD>瘚讛<E7989A><E8AE9B><EFBFBD><E585B8>𤏸<EFBFBD><F0A48FB8><EFBFBD>?<3F>?Network <20><>
- 摨磰砲<E7A3B0><EFBFBD>嚗䫤POST /api/v1/auth/login` <20>?<3F><EFBFBD>?200
- [ ] **<EFBFBD>唳旿<EFBFBD>㰘蝸**
- 霈輸䔮憿寧𤌍<E5AFA7>𡑒”憿? - <20><EFBFBD> Network <20><>
- 摨磰砲<E7A3B0><EFBFBD>嚗䫤GET /api/v1/projects` <20>?<3F><EFBFBD>?200
- <20>𡑒”<F0A19192>唳旿甇<E697BF><EFBFBD>曄內
- [ ] **<EFBFBD><EFBFBD>辣銝𠹺<EFBFBD>**
- 撠肽<E692A0>銝𠹺<E98A9D><EFBFBD>銝?PDF <20><>
- <20><EFBFBD> Network <20><>
- 摨磰砲<E7A3B0><EFBFBD>嚗䫤POST /api/v1/knowledge-bases/.../documents` <20>?<3F><EFBFBD>?200
- 銝𠹺<E98A9D>餈𥕦漲甇<E6BCB2><EFBFBD>曄內
#### 瘚贝<E7989A><EFBFBD><E79A9C> C嚗𡁏<E59A97><EFBFBD>瘚贝<E7989A>
- [ ] **擐硋<E69390><E7A18B>㰘蝸<E3B098>園𡢿**
-<>膄瘚讛<E7989A><E8AE9B><EFBFBD>摮? - <20>瑟鰵憿菟𢒰
- <20><EFBFBD> Network <20><><20>?摨閖<E691A8>蝏蠘恣
- <20>餅𧒄<E9A485><EFBFBD> < 3 蝘𡜐<E89D98><F0A19C90><EFBFBD>霈輸䔮嚗?
- [ ] **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>皞鞟<EFBFBD>摮?*
- 蝚砌<E89D9A>甈∟挪<E2889F><EFBFBD><E6AEB7><EFBFBD><EFBFBD><EFBFBD>皞𣂷<E79A9E><F0A382B7>滚𦛚<E6BB9A><EFBFBD>頧? - 蝚砌<E89D9A>甈∟挪<E2889F><EFBFBD>JS/CSS <20><><EFBFBD>曄內"(from disk cache)"
- index.html <20>曄內<E69B84><EFBFBD>?200嚗<30><E59A97>甈⊿<E79488><E28ABF>齿鰵<E9BDBF><EFBFBD>嚗?
- [ ] **Gzip <20>讠憬**
- <20><EFBFBD> Response Headers
- 摨磰砲<E7A3B0><EFBFBD>嚗䫤Content-Encoding: gzip`
- JS <20><>辣憭批<E686AD><E689B9><EFBFBD> 60-70%
### 甇仿炊 4嚗𡁏<E59A97>霂訫<E99C82><E8A8AB>睲誨<E79DB2><E8AAA8><EFBFBD>撉諹<E69289> CORS 閫<><E996AB>嚗?
```bash
# <20><EFBFBD>瘚讛<E7989A><E8AE9B><EFBFBD><E585B8>𤏸<EFBFBD><F0A48FB8><EFBFBD>?<3F>?Console
# <20><EFBFBD>隞乩<E99A9E><EFBFBD><E99A9E>嚗?
fetch('/api/v1/health')
.then(res => res.json())
.then(data => console.log(data));
# 憸<><E686B8>颲枏枂嚗?# {status: "healthy", timestamp: "...", ...}
# 憒<><E68692><EFBFBD><EFBFBD> CORS <20>躰秤嚗?# <20>?Access to fetch at '/api/v1/health' from origin 'https://...' has been blocked by CORS policy
# <20>?霂湔<E99C82> Nginx <20><EFBFBD><EFBFBD><E99A9E><EFBFBD>滨蔭<E6BBA8>厰䔮憸?
# 甇<><EFBFBD><EFBC86><EFBFBD><EFBFBD><EFBFBD>
# <20>?霂瑟<E99C82><E7919F>𣂼<EFBFBD>嚗峕<E59A97>隞颱<E99A9E> CORS <20>躰秤
```
### 甇仿炊 5嚗𡁶宏<F0A181B6>函垢瘚贝<E7989A><EFBFBD><EFBFBD><EFBFBD>
雿輻鍂<EFBFBD>𧢲㦤瘚讛<EFBFBD><EFBFBD>刻挪<EFBFBD><EFBFBD>蝡臬𧑐<EFBFBD><EFBFBD>嚗?
- [ ] 憿菟𢒰<E88F9F>質䌊<E8B3AA><E48C8A><EFBFBD>蝘餃𢆡蝡臬<E89DA1>撟?- [ ] 閫行𨰫鈭支<E988AD><EFBFBD>
- [ ] 憿菟𢒰<E88F9F>㰘蝸<E3B098>笔漲<E7AC94>舀𦻖<E88880>?
---
## 10. <20>烐綉銝𡒊輕<F0A1928A>?
### <20><> SAE <20>芸蒂<E88AB8>烐綉
#### 1. 摰墧𧒄<E5A2A7>烐綉
**SAE <20><EFBFBD><E689B9>?* <20>?**摨𠉛鍂霂行<E99C82>** <20>?**<2A>烐綉**
**<EFBFBD>喲睸<EFBFBD><EFBFBD><EFBFBD>**嚗?
| <20><><EFBFBD> | <20>亙熒<E4BA99><E78692><EFBFBD>?| <20>𡃏郎<F0A1838F><E9838E><EFBFBD>?| 霂湔<E99C82> |
|------|---------|---------|------|
| **CPU 雿輻鍂<E8BCBB>?* | < 30% | > 60% | Nginx <20><><EFBFBD><EFBFBD><E9A09E> 30% |
| **<EFBFBD><EFBFBD><EFBFBD>雿輻鍂<EFBFBD>?* | < 50% | > 80% | Nginx <20><><EFBFBD><EFBFBD>删鍂敺<E98D82><E695BA> |
| **霂瑟<E99C82> QPS** | - | - | 鈭<>圾霈輸䔮<E8BCB8>?|
| **撟喳<E6929F><E596B3><EFBFBD><E6BB9A>園𡢿** | < 50ms | > 200ms | <20><EFBFBD><E8B9B1><EFBFBD>隞嗅<E99A9E>摨娍<E691A8>敹?|
| **<EFBFBD>躰秤<EFBFBD>?* | < 0.1% | > 1% | <20>烐綉 404/50x <20>躰秤 |
| **摰硺<E691B0><E7A1BA><EFBFBD>** | 2+ | - | 蝖桐<E89D96>擃睃虾<E79D83>?|
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**嚗?```
<EFBFBD><EFBFBD>?HTML嚗𡁜<E59A97>摨娍𧒄<E5A88D>?10-20ms
JS/CSS <20><>辣嚗𡁜<E59A97>摨娍𧒄<E5A88D>?10-30ms
API 隞<><E99A9E>嚗𡁜<E59A97>摨娍𧒄<E5A88D>?50-500ms嚗<73><E59A97><EFBFBD><EFBFBD><E59683>𡒊垢嚗?擐硋<E69390><E7A18B>㰘蝸嚗<E89DB8><E59A97><EFBFBD><EFBFBD>皞琜<E79A9E>嚗?-3蝘?```
#### 2. <20><EFBFBD><E4BA99><EFBFBD>
**SAE <20><EFBFBD><E689B9>?* <20>?**摨𠉛鍂霂行<E99C82>** <20>?**<2A><EFBFBD>** <20>?**摰墧𧒄<E5A2A7><EFBFBD>**
**<2A>喲睸<E596B2><EFBFBD>蝷箔<E89DB7>**嚗?
```bash
# <20>?甇<><EFBFBD>臬𢆡
============================================
Starting Frontend Nginx Service
Backend Service: 172.17.x.x:3001
============================================
nginx: configuration file /etc/nginx/nginx.conf test is successful
# <20>?甇<>虜霂瑟<E99C82><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD>皞琜<E79A9E>
172.31.0.10 - - [13/Dec/2025:10:30:00 +0000] "GET / HTTP/1.1" 200 1234
172.31.0.10 - - [13/Dec/2025:10:30:01 +0000] "GET /assets/index-xxxxx.js HTTP/1.1" 200 567890
# <20>?甇<>虜霂瑟<E99C82>嚗㇁PI 隞<><E99A9E>嚗?172.31.0.10 - - [13/Dec/2025:10:30:02 +0000] "GET /api/v1/projects HTTP/1.1" 200 8765
# <20>𩤃<EFBFBD> 霅血<E99C85><E8A180><EFBFBD>嚗?04 Not Found嚗?172.31.0.10 - - [13/Dec/2025:10:30:03 +0000] "GET /favicon.ico HTTP/1.1" 404 153
# <20>?<3F>躰秤<E8BAB0><EFBFBD><EFBFBD><E59A97>蝡航<E89DA1><E888AA>亙仃韐伐<E99F90>
2025/12/13 10:30:04 [error] 7#7: *1 connect() failed (111: Connection refused) while connecting to upstream
client: 172.31.0.10, server: _, request: "GET /api/v1/projects HTTP/1.1"
upstream: "http://172.17.x.x:3001/api/v1/projects"
```
#### 3. Nginx <20><EFBFBD><E59786><EFBFBD><EFBFBD>?
```bash
# <20>?SAE Webshell 銝剜<E98A9D>銵䕘<E98AB5><E49598><EFBFBD><EFBFBD><E69C9E><EFBFBD><EFBFBD>霈輸䔮嚗?curl http://localhost/nginx_status
# 颲枏枂蝷箔<E89DB7>嚗?# Active connections: 15
# server accepts handled requests
# 123456 123456 567890
# Reading: 2 Writing: 5 Waiting: 8
```
**<2A><><EFBFBD><EFBFBD><EFBFBD>**嚗?- `Active connections`: 敶枏<E695B6>瘣餉<E798A3>餈墧𦻖<E5A2A7>?- `accepts`: 撌脫𦻖<E884AB><EFBFBD>餈墧𦻖<E5A2A7>餅㺭
- `handled`: 撌脣<E6928C><E884A3><EFBFBD><EFBFBD>餈墧𦻖<E5A2A7>餅㺭
- `requests`: 撌脣<E6928C><E884A3><EFBFBD><EFBFBD>霂瑟<E99C82><E7919F>餅㺭
- `Reading`: 甇<>銁霂餃<E99C82>霂瑟<E99C82>憭渡<E686AD>餈墧𦻖<E5A2A7>?- `Writing`: 甇<><EFBFBD><EFBFBD><E59D94><EFBFBD><E6BB9A><EFBFBD><EFBFBD><EFBFBD>交㺭
- `Waiting`: 蝛粹𤦭<E7B2B9>?Keep-Alive 餈墧𦻖<E5A2A7>?
### <20><20>亙虜蝏湔擪隞餃𦛚
#### 瘥𤩺𠯫璉<F0A0AFAB><E79289>?
```bash
# 1. 璉<><E79289><EFBFBD><E4BA99><EFBFBD>摨瑞𠶖<E7919E>?# SAE <20><EFBFBD><E689B9>?<3F>?摨𠉛鍂<F0A0899B>𡑒” <20>?<3F><EFBFBD>餈鞱<E9A488><E99EB1><EFBFBD><E59786><EFBFBD>蝏輯𠧧銝箸迤撣賂<E692A3>
# 2. <20><EFBFBD><E4BAA6>躰秤<E8BAB0><EFBFBD>
# SAE <20><EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F><EFBFBD> <20>?蝑偦<E89D91>?error 蝥批<E89DA5>
# 3. 璉<><E79289>亥挪<E4BAA5><EFBFBD>
# SAE <20><EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>烐綉 <20>?<3F><EFBFBD> QPS
```
#### 瘥誩𪂹隞餃𦛚
```bash
# 1. <20><EFBFBD><E4BAA6><EFBFBD><E689AF><EFBFBD><EFBFBD>頞见飵
# SAE <20><EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>烐綉 <20>?<3F>㗇𥋘"<22><>餈?7 憭?
# <20>單釣嚗?# - <20><EFBFBD><E6BB9A>園𡢿<E59C92>臬炏<E887AC><EFBFBD>
# - <20>躰秤<E8BAB0><E7A7A4><EFBFBD><EFBFBD><E8A180>?# - 瘚<><E7989A><EFBFBD>臬炏<E887AC><EFBFBD>撣豢郭<E8B1A2>?
# 2. <20><EFBFBD> 404 <20>躰秤
# <20>冽𠯫敹𦯀葉<F0A6AF80>𦦵揣 "404"嚗<><E59A97><EFBFBD>𣂼<EFBFBD><F0A382BC>𩤃<EFBFBD>
# - 韏<><E99F8F>蝖桀<E89D96>銝滚<E98A9D><E6BB9A><EFBFBD>
# - SPA 頝舐眏<E88890>滨蔭<E6BBA8><EFBFBD>嚗?# - 憭㚚<E686AD><E39A9A>祈臤霈輸䔮銝滚<E98A9D><E6BB9A><EFBFBD>頝臬<E9A09D>嚗?```
#### 瘥𤩺<E798A5>隞餃𦛚
```bash
# 1. <20>湔鰵<E6B994>滨垢隞<E59EA2><E99A9E><EFBFBD><E59A97><EFBFBD>㗇鰵<E39787><E9B0B5>𧋦嚗?# <20>冽𧋦<E586BD><EFBFBD><E59C88><EFBFBD>撱粹<E692B1><E7B2B9>𧶏<EFBFBD>
cd frontend
npm run build
docker build -t frontend-service:v1.0.1 .
docker push registry.cn-beijing.aliyuncs.com/clinical-research/frontend-service:v1.0.1
# 2. <20>?SAE 銝剜凒<E5899C><EFBFBD><E59C88>?# SAE <20><EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>函蔡
# <20>㗇𥋘<E39787><EFBFBD><E59C88><EFBFBD><E8AE90>穿<EFBFBD>v1.0.1
# <20>啣漲<E595A3><EFBFBD>嚗𡁜<E59A97><F0A1819C>湔鰵 1 銝芸<E98A9D>靘页<E99D98><EFBFBD><E996AB> 5 <20><><EFBFBD><EFBFBD>𤾸<EFBFBD><F0A4BEB8><EFBFBD>撣?
# 3. 皜<><E79A9C><EFBFBD><EFBFBD><E68A98>𧶏<EFBFBD><F0A7B68F><EFBFBD><EFBFBD> ACR 摮睃<E691AE>蝛粹𡢿嚗?# ACR <20><EFBFBD><E689B9>?<3F>?<3F>𨅯<EFBFBD>隞枏<E99A9E> <20>?frontend-service
# <20>𣳇膄 30 憭拙<E686AD><E68B99><EFBFBD><EFBFBD><E59482>𧋦嚗<F0A78BA6><E59A97><EFBFBD><EFBFBD>餈?3 銝芰<E98A9D><E88AB0>穿<EFBFBD>
# 4. 璉<><E79289>?SSL 霂<><EFBFBD><EFBFBD><E39787><EFBFBD><EFBFBD><EFBFBD><E68692>雿輻鍂<E8BCBB><EFBFBD>銋匧<E98A8B><E58CA7><EFBFBD>
# SAE <20><EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?摨𠉛鍂霈輸䔮<E8BCB8>滨蔭 <20>?HTTPS 霈曄蔭
# 霂<><EFBFBD><EFBFBD><E594B3>?30 憭拇凒<E68B87>?```
### <20><20>𡃏郎<F0A1838F>滨蔭
**鈭𤑳<E988AD><F0A491B3>?* <20>?**摨𠉛鍂<F0A0899B>烐綉** <20>?**<2A>𥕦遣<F0A595A6>𡃏郎閫<E9838E><E996AB>**
**<2A><EFBFBD><E588BB>𡃏郎閫<E9838E><E996AB>**嚗?
| <20>𡃏郎憿?| <20><><EFBFBD>?| <20>𡁶䰻<F0A181B6><EFBFBD> |
|-------|------|---------|
| CPU 雿輻鍂<E8BCBB>?> 60% <20><>賒 5 <20><><EFBFBD> | <20>𡃏郎 | <20><EFBFBD>/<2F>桐辣 |
| <20><><EFBFBD>雿輻鍂<E8BCBB>?> 80% <20><>賒 5 <20><><EFBFBD> | <20>𡃏郎 | <20><EFBFBD>/<2F>桐辣 |
| <20>躰秤<E8BAB0>?> 1% <20><>賒 3 <20><><EFBFBD> | 蝝扳<E89D9D>?| <20>凋縑+<2B><EFBFBD> |
| 摰硺<E691B0><E7A1BA>亙熒璉<E78692><E79289>亙仃韐?> 3 甈?| 蝝扳<E89D9D>?| <20>凋縑+<2B><EFBFBD> |
| 撟喳<E6929F><E596B3><EFBFBD><E6BB9A>園𡢿 > 500ms <20><>賒 5 <20><><EFBFBD> | <20>𡃏郎 | <20><EFBFBD>/<2F>桐辣 |
---
## 11. <20><><EFBFBD><EFBFBD>埝䰻
### <20><EFBFBD> 1嚗𡁻△<F0A181BB><EFBFBD>頧賜征<E8B39C><EFBFBD><E8B89D><EFBFBD>撣貉<E692A3>嚗?
**<2A><>𠶖**嚗?
瘚讛<EFBFBD><EFBFBD>刻挪<EFBFBD><EFBFBD>蝡臬𧑐<EFBFBD><EFBFBD>嚗𣬚<EFBFBD><EFBFBD>啁征<EFBFBD>賡△<EFBFBD><EFBFBD>?
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. 璉<><E79289>?HTML <20>臬炏甇<E7828F>餈𥪜<E9A488>
curl -I https://frontend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/
# 憒<><E68692>餈𥪜<E9A488> 404 <20>?50x嚗諹秩<E8ABB9>?Nginx <20>滨蔭<E6BBA8>厰䔮憸?
# 2. 璉<><E79289><EFBFBD>撱箔漣<E7AE94>拇糓<E68B87><EFBFBD><E8A180>?# <20><EFBFBD> SAE Webshell嚗?ls -la /usr/share/nginx/html/
# 摨磰砲<E7A3B0><EFBFBD>嚗?# index.html
# assets/index-xxxxx.js
# assets/index-xxxxx.css
# 憒<><E68692> dist/ <20><EFBFBD>銝箇征嚗諹秩<E8ABB9><EFBFBD>撱粹𧫴畾萄仃韐?
# 3. <20><EFBFBD>瘚讛<E7989A><E8AE9B><EFBFBD><E585B8>𤏸<EFBFBD><F0A48FB8><EFBFBD>?Console
# 憒<><E68692><EFBFBD><EFBFBD>嚗?# Uncaught SyntaxError: Unexpected token '<'
# 霂湔<E99C82> JS <20><>辣頝臬<E9A09D><E887AC>躰秤嚗諹<E59A97><E8ABB9><EFBFBD> HTML <20><EFBFBD><E494B6>?JS
# 4. 璉<><E79289>?Vite <20><><EFBFBD>滨蔭
# vite.config.ts 銝剔<E98A9D> base 頝臬<E9A09D>
# 摨磰砲<E7A3B0><EFBFBD>base: '/'嚗<><E59A97>霈歹<E99C88>
# 銝滩<E98A9D><E6BBA9><EFBFBD>嚗颹ase: '/app/'嚗<><E59A97>撖潸稲頝臬<E9A09D><E887AC>躰秤嚗?```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?
```bash
# <20><EFBFBD> 1嚗𡁻<E59A97><F0A181BB><EFBFBD>撱粹<E692B1><E7B2B9>𧶏<EFBFBD><F0A7B68F>砍𧑐撉諹<E69289>嚗?cd frontend
npm run build
ls -la dist/ # 蝖株恕<E6A0AA><E68195>遣鈭抒<E988AD>摮睃銁
docker build -t frontend-service:v1.0.1 .
# <20><EFBFBD> 2嚗𡁏<E59A97><F0A1818F>?Dockerfile <20>臬炏甇<E7828F>憭滚<E686AD>鈭?dist/
# 蝖桐<E89D96><E6A190><EFBFBD><EFBFBD>銵䕘<E98AB5>
COPY --from=builder /app/dist /usr/share/nginx/html
```
### <20><EFBFBD> 2嚗𡁜<E59A97><F0A1819C>圈△<E59C88>𥁒 404嚗𠄎PA 頝舐眏<E88890><EFBFBD>嚗?
**<2A><>𠶖**嚗?
- 霈輸䔮 `/` 甇<>
- <20>孵稬<E5ADB5>暹𦻖頝唾蓮<E594BE>?`/dashboard` 甇<>
- <20>瑟鰵憿菟𢒰嚗㇅5嚗争<E59A97> 404 Not Found
**<2A><EFBFBD>**嚗?
Nginx <20><EFBFBD><E69B86>?`/dashboard` <20><>辣嚗<E8BEA3><E59A97>霂亥<E99C82><E4BAA5>?`index.html` 霈?React Router <20>亦恣<E4BAA6>?
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. 璉<><E79289>?Nginx <20>滨蔭銝剔<E98A9D> try_files
# <20><EFBFBD> SAE Webshell嚗?cat /etc/nginx/nginx.conf | grep "try_files"
# 摨磰砲<E7A3B0><EFBFBD>嚗?# try_files $uri $uri/ /index.html;
# 憒<><E68692>瘝⊥<E7989D>餈嗘<E9A488>銵䕘<E98AB5>霂湔<E99C82> SPA 頝舐眏<E88890>滨蔭蝻箏仃
```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?
```nginx
# <20>?nginx.conf <20>?location / <20>𦯀葉瘛餃<E7989B>嚗?location / {
try_files $uri $uri/ /index.html;
}
# <20>齿鰵<E9BDBF><E9B0B5><EFBFBD>𨅯<EFBFBD>撟園<E6929F>蝵?```
### <20><EFBFBD> 3嚗鋫PI 霂瑟<E99C82><E7919F>仿<EFBFBD><EFBFBD><E59A97><EFBFBD>睲誨<E79DB2><E8AAA8>䔮憸矋<E686B8>
**<2A><>𠶖**嚗?
- <20>滨垢憿菟𢒰甇<F0A292B0><EFBFBD>曄內
- 靚<>鍂 API <20>嗆𥁒<E59786><EFBFBD>
- `Network Error`
- `504 Gateway Timeout`
- `502 Bad Gateway`
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. 璉<><E79289><EFBFBD>蝡舀<E89DA1><E88880>⊥糓<E28AA5>西<EFBFBD>銵?# SAE <20><EFBFBD><E689B9>?<3F>?摨𠉛鍂<F0A0899B>𡑒” <20>?backend-service <20>?<3F><EFBFBD><E4BAA6><EFBFBD>?
# 2. 瘚贝<E7989A><E8B49D>𡒊垢<F0A1928A><E59EA2><EFBFBD><EFBFBD><EFBFBD><E595A3>臬炏<E887AC>航噢
# <20><EFBFBD><E9A483>滨垢摨𠉛鍂<F0A0899B>?Webshell嚗?curl http://172.17.x.x:3001/api/v1/health
# 憒<><E68692>餈𥪜<E9A488><F0A5AA9C>躰秤嚗諹秩<E8ABB9>𠬍<EFBFBD>
# - <20>𡒊垢<F0A1928A>滚𦛚<E6BB9A>芸鍳<E88AB8>?# - <20><><EFBFBD><EFBFBD><EFBFBD><E595A3>滨蔭<E6BBA8>躰秤
# - VPC 蝵𤑳<E89DB5>銝漤<E98A9D>?
# 3. 璉<><E79289>?Nginx <20>滨蔭銝剔<E98A9D> upstream
cat /etc/nginx/nginx.conf | grep -A 5 "upstream backend"
# 摨磰砲<E7A3B0><EFBFBD><EFBFBD><EFBFBD><EFBC86><EFBFBD>蝡臬𧑐<E887AC><F0A79190>嚗?# server 172.17.x.x:3001 fail_timeout=30s max_fails=3;
# 4. <20><EFBFBD> Nginx <20>躰秤<E8BAB0><EFBFBD>
tail -f /var/log/nginx/error.log | grep "upstream"
```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?
```bash
# <20><EFBFBD> 1嚗𡁏凒<F0A1818F>啁㴓憓<E3B493><E68693><EFBFBD>?# SAE <20><EFBFBD><E689B9>?<3F>?frontend-service <20>?摨𠉛鍂<F0A0899B>滨蔭 <20>?<3F><EFBFBD><E887AC><EFBFBD>
# 蝖株恕嚗?BACKEND_SERVICE_HOST=172.17.x.x # 甇<><EFBFBD><EFBC86><EFBFBD>蝵?IP
BACKEND_SERVICE_PORT=3001
# <20>滚鍳摨𠉛鍂雿輻㴓憓<E3B493><E68693><EFBFBD><EFBFBD><E8AE90>?
# <20><EFBFBD> 2嚗𡁏<E59A97>霂訫<E99C82>蝵𤏸<E89DB5><F0A48FB8>𡁏<EFBFBD>?# <20><EFBFBD>蝡?Webshell 銝哨<E98A9D>
telnet 172.17.x.x 3001
# 憒<><E68692>餈墧𦻖憭梯揖嚗峕<E59A97><E5B395><EFBFBD>
# - <20>𡒊垢<F0A1928A><E59EA2><EFBFBD>蝡舀糓<E88880>血銁<E8A180><EFBFBD> VPC
# - 摰匧<E691B0><EFBFBD><E89D8F><EFBFBD>蹱糓<E8B9B1><EFBFBD>霈貉挪<E8B289>?```
### <20><EFBFBD> 4嚗鋴ORS <20>躰秤嚗<E7A7A4><E59A97><EFBFBD>睲誨<E79DB2><E8AAA8>𧊋<EFBFBD><F0A78A8B><EFBFBD>嚗?
**<2A><>𠶖**嚗?
瘚讛<EFBFBD><EFBFBD>?Console <20>曄內嚗?```
Access to fetch at 'http://backend-service:3001/api/v1/projects' from origin 'https://frontend-service.com' has been blocked by CORS policy
```
**<2A><EFBFBD>**嚗?
<EFBFBD>滨垢隞<EFBFBD><EFBFBD>銝剔蝻𣇉<EFBFBD><EFBFBD><EFBFBD>蝡臬𧑐<EFBFBD><EFBFBD>嚗諹<EFBFBD><EFBFBD><EFBFBD>臭蝙<EFBFBD>函㮾撖寡楝敺<EFBFBD><EFBFBD>?
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. 璉<><E79289><EFBFBD>蝡臭誨<E887AD><E8AAA8><EFBFBD>?API 靚<>
# src/api/request.ts
cat src/api/request.ts | grep "baseURL"
# <20>?<3F>躰秤蝷箔<E89DB7>嚗?# baseURL: 'http://backend-service:3001/api/v1'
# <20>?甇<>蝷箔<E89DB7>嚗?# baseURL: '/api/v1'
# 2. 璉<><E79289><EFBFBD><EFBFBD>膥 Network <20><>
# 甇<><EFBFBD><EFBC86>窈瘙<E7AA88>楝敺<E6A59D><E695BA>霂交糓嚗?# https://frontend-service.com/api/v1/projects
# <20><EFBFBD><E494B6><EFBFBD>
# http://backend-service:3001/api/v1/projects
```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?
```typescript
// src/api/request.ts
const request = axios.create({
baseURL: '/api/v1', // <20>?雿輻鍂<E8BCBB>詨笆頝臬<E9A09D>
timeout: 30000,
});
// <20>齿鰵<E9BDBF><E9B0B5>遣撟園<E6929F>蝵?```
### <20><EFBFBD> 5嚗𡁻<E59A97><F0A181BB><EFBFBD><EFBFBD>皞?404嚗<34>楝敺<E6A59D>䔮憸矋<E686B8>
**<2A><>𠶖**嚗?
- HTML <20><EFBFBD>頧?- JS/CSS <20><>辣 404 Not Found
- 瘚讛<E7989A><E8AE9B>?Console <20>曄內嚗? ```
GET https://frontend-service.com/assets/index-xxxxx.js 404 (Not Found)
```
**<2A><EFBFBD>**嚗?
Vite <20><><EFBFBD>滨蔭銝剔<E98A9D> `base` 頝臬<E9A09D>銝齿迤蝖柴<E89D96>?
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. <20><EFBFBD> index.html 銝剔<E98A9D><EFBFBD><E99F8F>頝臬<E9A09D>
curl https://frontend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/ | grep "assets"
# 摨磰砲<E7A3B0><EFBFBD>嚗?# <script type="module" src="/assets/index-xxxxx.js"></script>
# 憒<><E68692><EFBFBD><EFBFBD>嚗?# <script type="module" src="./assets/index-xxxxx.js"></script> # <20>𩤃<EFBFBD> <20>詨笆頝臬<E9A09D>
# <20>?# <script type="module" src="/app/assets/index-xxxxx.js"></script> # <20>?<3F>躰秤<E8BAB0>?base
# 2. 璉<><E79289>?vite.config.ts
cat vite.config.ts | grep "base"
```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?
```typescript
// vite.config.ts
export default defineConfig({
base: '/', // <20>?暺䁅恕<E48185><EFBFBD>蝏嘥笆頝臬<E9A09D>
// base: '/app/', // <20>?銝滩<E98A9D>霈曄蔭摮鞱楝敺<E6A59D><E695BA><EFBFBD><EFBFBD>蝖桀<E89D96><E6A180><EFBFBD><EFBFBD><E996AC>
plugins: [react()],
});
// <20>齿鰵<E9BDBF><E9B0B5>遣撟園<E6929F>蝵?```
### <20><EFBFBD> 6嚗𡁻△<F0A181BB>甅撘誯<E69298>銋梧<E98A8B>CSS <20><EFBFBD>頧踝<E9A0A7>
**<2A><>𠶖**嚗?
憿菟𢒰<EFBFBD><EFBFBD><EFBFBD>曄內嚗䔶<EFBFBD><EFBFBD><EFBFBD>瘛瑚僚嚗<EFBFBD><EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD>嚗剹<EFBFBD>?
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. 璉<><E79289><EFBFBD><EFBFBD>膥 Network <20><>
# <20><EFBFBD> CSS <20><><EFBFBD>臬炏<E887AC>𣂼<EFBFBD><F0A382BC>㰘蝸
# 憒<><E68692><EFBFBD>曄內 404嚗<34><E59A97><EFBFBD><EFBFBD>䔮憸?5
# 2. 璉<><E79289>?CSS <20><><EFBFBD>?MIME 蝐餃<E89D90>
curl -I https://frontend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/assets/index-xxxxx.css
# 摨磰砲<E7A3B0><EFBFBD>嚗?# Content-Type: text/css
# 憒<><E68692><EFBFBD><EFBFBD>嚗?# Content-Type: application/octet-stream # <20>?<3F>躰秤<E8BAB0>?MIME 蝐餃<E89D90>
# 3. 璉<><E79289>?Nginx <20>滨蔭
cat /etc/nginx/nginx.conf | grep "include.*mime.types"
```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?
```nginx
# 蝖桐<E89D96> nginx.conf 銝剖<E98A9D><E58996><EFBFBD>
http {
include /etc/nginx/mime.types; # <20>?敹<><E695B9>
default_type application/octet-stream;
...
}
```
### <20><EFBFBD> 7嚗𡁶㴓憓<E3B493><E68693><EFBFBD>𤩺𧊋<F0A4A9BA>踵揢
**<2A><>𠶖**嚗?
Nginx <20>臬𢆡憭梯揖嚗屸<E59A97>霂舀𠯫敹埈遬蝷綽<E89DB7>
```
nginx: [emerg] host not found in upstream "${BACKEND_SERVICE_HOST}" in /etc/nginx/nginx.conf:45
```
**<2A><EFBFBD>**嚗?
`envsubst` <20>芣迤蝖格𤜯<E6A0BC>㴓憓<E3B493><E68693><EFBFBD><EFBFBD>?
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. 璉<><E79289>亙鍳<E4BA99><EFBFBD><E588BB>?cat /docker-entrypoint.sh | grep "envsubst"
# 2. 璉<><E79289><EFBFBD><EFBFBD><E89D8F><EFBFBD><EFBFBD> nginx.conf
cat /etc/nginx/nginx.conf | grep "server.*backend"
# 摨磰砲<E7A3B0><EFBFBD>嚗?# server 172.17.x.x:3001;
# 憒<><E68692><EFBFBD><EFBFBD>嚗?# server ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT}; # <20>?<3F>芣𤜯<E88AA3>?```
**閫<><E996AB><EFBFBD><EFBFBD>**嚗?
```dockerfile
# 蝖桐<E89D96> Dockerfile 銝剔<E98A9D><E58994>臬𢆡<E887AC>𡁏𧋦甇<F0A78BA6>嚗?envsubst '${BACKEND_SERVICE_HOST} ${BACKEND_SERVICE_PORT}' \
< /etc/nginx/templates/nginx.conf.template \
> /etc/nginx/nginx.conf
# 瘜冽<E7989C>嚗?# - <20><EFBFBD><E8A8AB><EFBFBD>鋆孵<E98B86><E5ADB5><EFBFBD>
# - 雿輻鍂 .template <20><>辣雿靝蛹皞?# - 颲枏枂<E69E8F>?/etc/nginx/nginx.conf
```
---
## 12. 瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹?
### <20>?<3F><>雿喳<E99BBF>頝?
#### 1. **API 靚<>鍂雿輻鍂<E8BCBB>詨笆頝臬<E9A09D>**
```typescript
// <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁶㮾撖寡楝敺?const request = axios.create({
baseURL: '/api/v1',
});
// <20>滨垢嚗冴ttps://your-domain.com
// API嚗冴ttps://your-domain.com/api/v1/...
// <20><EFBFBD>霂瑟<E99C82>嚗峕<E59A97> CORS <20><EFBFBD>
// <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗𡁶蝻𣇉<E89DBB><F0A38789>𡒊垢<F0A1928A><EFBFBD>
const request = axios.create({
baseURL: 'http://backend-service:3001/api/v1',
});
// 頝典<E9A09D>霂瑟<E99C82>嚗䔶<E59A97><E494B6>?CORS <20><EFBFBD>
```
#### 2. **Vite base 頝臬<E9A09D><E887AC>滨蔭**
```typescript
// <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁻<E59A97>霈斗覔頝臬<E9A09D>
export default defineConfig({
base: '/', // 蝏嘥笆頝臬<E9A09D>嚗屸<E59A97><E5B1B8><EFBFBD>憭批<E686AD><E689B9>啣㦤<E595A3>?});
// <20>𩤃<EFBFBD><>銁隞乩<E99A9E><E4B9A9><EFBFBD><EFBFBD>雿輻鍂摮鞱楝敺<E6A59D><E695BA>
// - <20>函蔡<E587BD>?CDN <20><><EFBFBD><EFBFBD><EFBFBD>
// - 憭帋葵<E5B88B>滨垢<E6BBA8>曹澈銝<E6BE88>銝芸<E98A9D><E88AB8>?export default defineConfig({
base: '/app/', // 韏<><E99F8F>頝臬<E9A09D>嚗?app/assets/index.js
});
```
#### 3. **<2A><EFBFBD><E887AC><EFBFBD><E3979B><EFBFBD><EFBFBD><E996AB>**
```bash
# <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁏<E59A97><F0A1818F>?Host <20>?Port
BACKEND_SERVICE_HOST=172.17.x.x
BACKEND_SERVICE_PORT=3001
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗𡁜<E59A97><F0A1819C>?URL
BACKEND_SERVICE_URL=http://172.17.x.x:3001
# Nginx <20><EFBFBD><EFBFBD><E996AB><EFBFBD>讛悅<E8AE9B><EFBFBD>
```
#### 4. **蝻枏<E89DBB>蝑𣇉裦**
```nginx
# <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁜榆撘<E6A686><E69298>蝻枏<E89DBB>
location = /index.html {
add_header Cache-Control "no-cache"; # 瘥𤩺活<F0A4A9BA>質繮<E8B3AA>𡝗<EFBFBD><F0A19D97>?}
location ~* \.(js|css)$ {
expires 1y; # <20><><EFBFBD>滚蒂 hash嚗<68>虾隞仿鵭<E4BBBF><EFBFBD>摮?}
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗𡁜<E59A97><F0A1819C><EFBFBD>摮䀹<E691AE><E480B9><EFBFBD>銝滨<E98A9D>摮?add_header Cache-Control "public, max-age=31536000"; # index.html 銋毺<E98A8B>摮?1 撟?add_header Cache-Control "no-cache"; # <20><><EFBFBD><EFBFBD>隞園<E99A9E>銝滨<E98A9D>摮矋<E691AE>瘚芾晶撣血捐嚗?```
#### 5. **<2A>亙熒璉<E78692><E79289>亦垢<E4BAA6>?*
```nginx
# <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁶𡠺蝡讠<E89DA1><E8AEA0>亙熒璉<E78692><E79289>亦垢<E4BAA6>?location /health {
access_log off;
return 200 "healthy\n";
}
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗帋蝙<E5B88B>其蜓憿萎<E686BF>銝箏<E98A9D>摨瑟<E691A8><E7919F>?# 憒<><E68692><EFBFBD>滨垢隞<E59EA2><E99A9E><EFBFBD>?Bug嚗<67><E59A97>摨瑟<E691A8><E7919F><EFBFBD>隡𡁜仃韐?```
### <20>?蝏嘥笆蝳<E7AC86>
#### 1. **蝳<><EFBFBD><EFBFBD>蝡臭誨<E887AD><E8AAA8>葉蝖祉<E89D96><E7A589><EFBFBD><EFBFBD>蝡臬𧑐<E887AC><F0A79190>**
```typescript
// <20>?<3F>躰秤蝷箔<E89DB7>
const API_URL = 'http://172.16.0.30:3001/api/v1';
// <20><EFBFBD>嚗?// - <20>砍𧑐撘<F0A79190><E69298>烐𧒄<E78390><F0A79284><EFBFBD><EFBFBD>嫣誨<E5ABA3>?// - <20>函蔡<E587BD><EFBFBD>鈭抒㴓憓<E3B493>𧒄<EFBFBD><F0A79284><EFBFBD><E996AC>甈∩耨<E288A9>?// - 頝典<E9A09D><E585B8><EFBFBD>
// - <20><EFBFBD>雿輻鍂 Nginx <20><EFBFBD><EFBFBD><E99A9E>
// <20>?甇<><EFBFBD>𡁏<EFBFBD>
const API_URL = '/api/v1'; // <20>詨笆頝臬<E9A09D>嚗𣬚眏 Nginx 隞<><E99A9E>
```
#### 2. **蝳<>迫敹賜裦 SPA 頝舐眏<E88890>滨蔭**
```nginx
# <20>?<3F>躰秤<E8BAB0>滨蔭嚗<E894AD>撩撠?try_files嚗?location / {
root /usr/share/nginx/html;
}
# <20><EFBFBD>嚗𡁜<E59A97><F0A1819C>圈△<E59C88>𥁒 404
# <20>?甇<><EFBFBD>滨蔭
location / {
try_files $uri $uri/ /index.html;
}
```
#### 3. **蝳<>迫撠?index.html 霈曄蔭銝粹鵭<E7B2B9><EFBFBD>摮?*
```nginx
# <20>?<3F>躰秤蝷箔<E89DB7>
location / {
expires 1y;
add_header Cache-Control "public, immutable";
}
# <20><EFBFBD>嚗𡁻<E59A97>蝵脫鰵<E884AB><E9B0B5>𧋦<EFBFBD>𠬍<EFBFBD><F0A0AC8D><EFBFBD>隞滨<E99A9E><E6BBA8>唳唂<E594B3><E59482>𧋦
# <20>?甇<><EFBFBD>𡁏<EFBFBD>
location = /index.html {
add_header Cache-Control "no-cache";
}
```
#### 4. **蝳<><EFBFBD>?Nginx <20>滨蔭銝凋蝙<E5878B>冽𧊋蝏讐㴓憓<E3B493><E68693><EFBFBD>𤩺𤜯<F0A4A9BA><EFBFBD><EFBCB9><EFBFBD>蝚?*
```nginx
# <20>?<3F>躰秤蝷箔<E89DB7><EFBFBD><EFBFBD><EFBFBD><E4BA99><EFBFBD>蝚佗<E89D9A>
upstream backend {
server ${BACKEND_SERVICE_HOST}:${BACKEND_SERVICE_PORT};
}
# 憒<><E68692>瘝⊥<E7989D> envsubst <20>踵揢嚗𨨲ginx 隡𡁜鍳<F0A1819C>典仃韐?
# <20>?甇<><EFBFBD>𡁏<EFBFBD><EFBFBD><EFBFBD>?envsubst嚗?envsubst '${BACKEND_SERVICE_HOST} ${BACKEND_SERVICE_PORT}' \
< nginx.conf.template > /etc/nginx/nginx.conf
```
#### 5. **蝳<>迫敹賜裦 Gzip <20>讠憬**
```nginx
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD><EFBFBD><E59A97><EFBFBD>讠憬嚗?# 隡㰘<E99AA1>憭批<E686AD>嚗?00KB JS <20><><20>?500KB
# <20>?甇<><EFBFBD>𡁏<EFBFBD><EFBFBD><EFBFBD>?Gzip嚗?gzip on;
gzip_types text/plain text/css application/javascript;
# 隡㰘<E99AA1>憭批<E686AD>嚗?00KB JS <20><><20>?150KB嚗<42><E59A97><EFBFBD>?70%嚗?```
#### 6. **蝳<><EFBFBD><EFBFBD>鈭抒㴓憓<E3B493>𠂔<EFBFBD><EFBFBD><E884AB>煺縑<E785BA>?*
```nginx
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>
server_tokens on; # <20>湧蠧 Nginx <20><>𧋦<EFBFBD>?autoindex on; # <20><><EFBFBD><EFBFBD>瘚讛<E7989A>
# <20>?甇<><EFBFBD>𡁏<EFBFBD>
server_tokens off;
autoindex off;
```
#### 7. **蝳<>迫雿輻鍂餈<E98D82><EFBFBD><E9B5AD><EFBFBD><EFBFBD>嗆𧒄<E59786>?*
```nginx
# <20>?<3F>躰秤蝷箔<E89DB7>嚗?0 <20><><EFBFBD><EFBFBD>𧒄嚗?proxy_read_timeout 1800s;
# <20><EFBFBD>嚗𡁜<E59A97><F0A1819C><EFBFBD><E588BB><EFBFBD>皞琜<E79A9E>敶勗<E695B6>撟嗅<E6929F><E59785><EFBFBD>
# <20>?甇<><EFBFBD>𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6A180><EFBFBD><EFBFBD><EFBFBD><E79899>
proxy_read_timeout 300s; # 5 <20><><EFBFBD>嚗㇁I 撖寡<E69296>頞喳<E9A09E>嚗?```
#### 8. **蝳<>迫敹賜裦<E8B39C>躰秤憭<E7A7A4><E686AD>**
```nginx
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD><EFBFBD><E59A97>蝡舀<E89DA1><EFBFBD><E988AD>Nginx <20>湔𦻖餈𥪜<E9A488> 502嚗?proxy_pass http://backend;
# <20>?甇<><EFBFBD>𡁏<EFBFBD><EFBFBD><E59A97>霂訫<E99C82>隞硋<E99A9E>靘页<E99D98>
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 2;
```
#### 9. **蝳<><EFBFBD>?Dockerfile 銝凋蝙<E5878B>?root <20><EFBFBD>餈鞱<E9A488> Nginx**
```dockerfile
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>
USER root # 摰匧<E691B0>憌𡡞埯
# <20>?甇<><EFBFBD>𡁏<EFBFBD>
USER nginx # Nginx 摰䀹䲮<E480B9>𨅯<EFBFBD>暺䁅恕撌脣<E6928C>撱?nginx <20><EFBFBD>
# <20>𤥁<EFBFBD><F0A4A581><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗淾lpine <20>𨅯<EFBFBD>暺䁅恕雿輻鍂 nginx <20><EFBFBD>
```
#### 10. **蝳<>迫雿輻鍂<E8BCBB>躰秤<E8BAB0>?Node <20><>𧋦**
```dockerfile
# <20>?<3F>躰秤蝷箔<E89DB7>嚗帋蝙<E5B88B>?Node 18嚗<38><E59A97><EFBFBD><E69298>𤑳㴓憓<E3B493><E68693><EFBFBD><E98A9D><EFBFBD>
FROM node:18-alpine AS builder
# 憌𡡞埯嚗䮝ackage-lock.json <20><>𧋦<EFBFBD><EFBFBD>
# <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗帋蝙<E5B88B>?Node 22嚗<32><E59A97><EFBFBD><E69298>𤑳㴓憓<E3B493><E68693><EFBFBD><EFBFBD>
FROM node:22-alpine AS builder
# 靽肽<E99DBD>靘肽<E99D98>摰㕑<E691B0><E39591><EFBFBD>撱箇㴓憓<E3B493><E68693><EFBFBD>?```
#### 11. **蝳<>迫撠<E8BFAB>𠯫敹堒<E695B9><E5A092><EFBFBD>隞?*
```nginx
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD><EFBFBD>𠯫敹堒<E695B9><E5A092><EFBFBD>隞塚<E99A9E>
access_log /var/log/nginx/access.log main;
# 憌𡡞埯嚗𡁜虾<F0A1819C><EFBFBD><E288AA><EFBFBD><E587BD>?
# <20>?甇<><EFBFBD>𡁏<EFBFBD><EFBFBD>𠯫敹𡑒<E695B9><F0A19192><EFBFBD><E7AE8F><EFBFBD><EFBFBD><EFBFBD><E7989A>
access_log /dev/stdout main;
error_log /dev/stderr warn;
# SAE 隡朞䌊<E69C9E>冽𤣰<E586BD><F0A4A3B0><EFBFBD><EFBFBD><EFBFBD>銝剖<E98A9D>
```
#### 12. **蝳<>迫敹賜裦摰孵膥<E5ADB5>嗅躹霈曄蔭**
```dockerfile
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD><EFBFBD><E59A97>霈曄蔭<E69B84>嗅躹嚗屸<E59A97>霈?UTC嚗?# <20><EFBFBD>嚗𡁏𠯫敹埈𧒄<E59F88><EFBFBD><E6B994>𦯀漪<F0A6AF80>園𡢿<E59C92>?8 撠𤩺𧒄
# <20>?甇<><EFBFBD>𡁏<EFBFBD><EFBFBD>挽蝵桐蛹 Asia/Shanghai嚗?RUN apk add --no-cache tzdata && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
```
#### 13. **蝳<>迫蝏坔<E89D8F>蝡臬𧑐<E887AC><F0A79190><EFBFBD>梢埯<E6A2A2><E59FAF><EFBFBD>霈文<E99C88>?*
```bash
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD><EFBFBD><E59A97>暺䁅恕<E48185><EFBFBD>
export BACKEND_SERVICE_HOST=${BACKEND_SERVICE_HOST:-backend-service}
# 憌𡡞埯嚗𡁜虾<F0A1819C><EFBFBD><E8B3AA><EFBFBD><E4BA99>躰秤<E8BAB0><E7A7A4><EFBFBD>蝡?
# <20>?甇<><EFBFBD>𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E79899>蝵殷<E89DB5>
if [ -z "$BACKEND_SERVICE_HOST" ]; then
echo "ERROR: BACKEND_SERVICE_HOST is required!"
exit 1
fi
```
#### 14. **蝳<>迫敹賜裦 Docker <20>𨅯<EFBFBD>隡睃<E99AA1>**
```dockerfile
# <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁜<E59A97><F0A1819C>嗆挾<E59786><E68CBE>
FROM node:22
RUN npm install
RUN npm run build
CMD ["nginx"]
# <20>𨅯<EFBFBD>憭批<E686AD>嚗鰺600MB
# <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁜<E59A97><F0A1819C>嗆挾<E59786><E68CBE>
FROM node:22-alpine AS builder
RUN npm run build
FROM nginx:1.25-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
# <20>𨅯<EFBFBD>憭批<E686AD>嚗鰺40-60MB嚗<42><E59A97><EFBFBD>?90%嚗?```
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
- [05-Node.js<6A>𡒊垢-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md](./05-Node.js<6A>𡒊垢-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md)
- [04-Python敺格<E695BA><E6A0BC>?SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md](./04-Python敺格<E695BA><E6A0BC>?SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md)
- [03-Dify-ECS<43>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>.md](./03-Dify-ECS<43>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>.md)
---
## <20><> <20><EFBFBD>撣桀𨭌
**<2A><><EFBFBD><EFBFBD><EFBFBD>嚗?*
1. <20><EFBFBD><E4BAA6><EFBFBD><EFBFBD><E78DA2>"<22><><EFBFBD><EFBFBD>埝䰻"蝡㰘<E89DA1>
2. <20><EFBFBD> SAE <20><EFBFBD><E689B9><EFBFBD>摰墧𧒄<E5A2A7><EFBFBD>
3. <20><EFBFBD> Nginx <20>躰秤<E8BAB0><EFBFBD>嚗䫤/var/log/nginx/error.log`
4. 雿輻鍂瘚讛<E7989A><E8AE9B><EFBFBD><E585B8>𤏸<EFBFBD><F0A48FB8><EFBFBD>?Network <20><><EFBFBD><E5808C><EFBFBD>霂瑟<E99C82>
5. <20>𠉛頂<F0A0899B><EFBFBD><EFBD81><EFBFBD><EFBFBD>舀𣈲<E88880>?
---
**<EFBFBD>函蔡<EFBFBD>匧翰嚗<EFBFBD><EFBFBD><EFBFBD>**