部署: 支持 .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:
Sakurasan
2026-08-15 13:17:29 +08:00
parent 360c6b33a6
commit 5b67b66611
2 changed files with 71 additions and 0 deletions
+45
View File
@@ -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;
}
+26
View File
@@ -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(".", "_"))