部署: 支持 .env 文件注入环境变量(OT_ 前缀), nginx-public 公网单端口配置
- config: loadDotEnv() 读取 .env 注入 os env, AutomaticEnv 统一映射 OT_ 前缀 - deploy/nginx-public.conf: 宿主 8088 单端口, 前端静态 + /api /v1 反代 loopback (SSE 关缓冲), host 网络避开 iptables DNAT
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
# openteam 公网部署(IP+端口方式):宿主 8088 单端口入口
|
||||||
|
# nginx 容器使用 host 网络,反代走 loopback 避开 DNAT 干扰
|
||||||
|
server {
|
||||||
|
listen 8088;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# SPA 路由回退
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 管理 API + 代理端点 → 本机 openteam(127.0.0.1 loopback 不经 iptables DNAT)
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
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;
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
}
|
||||||
|
location /v1/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
# SSE 流式透传:关闭缓冲
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 静态资源缓存
|
||||||
|
location /assets/ {
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -50,7 +51,32 @@ type ProxyConfig struct {
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadDotEnv 读取 .env 文件并把 KEY=VALUE 注入环境变量(AutomaticEnv 会自动映射 OT_ 前缀)。
|
||||||
|
func loadDotEnv() {
|
||||||
|
data, err := os.ReadFile(".env")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if line == "" || strings.HasPrefix(line, "#") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
k, v, ok := strings.Cut(line, "=")
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
k = strings.TrimSpace(k)
|
||||||
|
v = strings.Trim(strings.TrimSpace(v), `"'`)
|
||||||
|
if k != "" && os.Getenv(k) == "" {
|
||||||
|
_ = os.Setenv(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Load() (*Config, error) {
|
func Load() (*Config, error) {
|
||||||
|
loadDotEnv()
|
||||||
|
|
||||||
v := viper.New()
|
v := viper.New()
|
||||||
v.SetEnvPrefix("OT")
|
v.SetEnvPrefix("OT")
|
||||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
|
|||||||
Reference in New Issue
Block a user