build(docker): Private mode deployment test successful
Test steps: bash docker/scripts/generate-config.sh --mode private [--local-ip 192.168.0.113] bash ./deploy.sh --mode private Front-end directly inlines NEXT_PUBLIC_API_URL, directly connecting to the backend. CORS (production) supports comma-separated multiple origins, with localhost and local network IPs included by default.
This commit is contained in:
+3
-3
@@ -5,9 +5,9 @@ ARG HTTP_PROXY
|
|||||||
ARG HTTPS_PROXY
|
ARG HTTPS_PROXY
|
||||||
ARG NO_PROXY
|
ARG NO_PROXY
|
||||||
|
|
||||||
ENV http_proxy=${HTTP_PROXY} \
|
ENV http_proxy ${HTTP_PROXY} \
|
||||||
https_proxy=${HTTPS_PROXY} \
|
https_proxy ${HTTPS_PROXY} \
|
||||||
no_proxy=${NO_PROXY}
|
no_proxy ${NO_PROXY}
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
|
|||||||
@@ -9,11 +9,24 @@ const DEV_ORIGINS = [
|
|||||||
/^http:\/\/192\.168\.\d+\.\d+:3002$/, // LAN addresses with new port
|
/^http:\/\/192\.168\.\d+\.\d+:3002$/, // LAN addresses with new port
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 解析生产环境下的多来源配置(逗号分隔)
|
||||||
|
const parseProdOrigins = (): string | RegExp | (string | RegExp)[] => {
|
||||||
|
const v = CONFIG.CORS_ORIGIN?.trim();
|
||||||
|
if (!v) return DEV_ORIGINS; // 回退到开发白名单
|
||||||
|
if (v.includes(",")) {
|
||||||
|
return v
|
||||||
|
.split(",")
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
};
|
||||||
|
|
||||||
// Configure CORS
|
// Configure CORS
|
||||||
export const corsOptions: CorsOptions =
|
export const corsOptions: CorsOptions =
|
||||||
CONFIG.NODE_ENV === "production"
|
CONFIG.NODE_ENV === "production"
|
||||||
? {
|
? {
|
||||||
origin: CONFIG.CORS_ORIGIN,
|
origin: parseProdOrigins(),
|
||||||
methods: ["GET", "POST", "OPTIONS"],
|
methods: ["GET", "POST", "OPTIONS"],
|
||||||
credentials: true,
|
credentials: true,
|
||||||
allowedHeaders: ["Content-Type", "Authorization"],
|
allowedHeaders: ["Content-Type", "Authorization"],
|
||||||
@@ -28,7 +41,7 @@ export const corsOptions: CorsOptions =
|
|||||||
export const corsWSOptions =
|
export const corsWSOptions =
|
||||||
CONFIG.NODE_ENV === "production"
|
CONFIG.NODE_ENV === "production"
|
||||||
? {
|
? {
|
||||||
origin: CONFIG.CORS_ORIGIN, // Allowed origin, replace with your Next.js application's URL
|
origin: parseProdOrigins(),
|
||||||
methods: ["GET", "POST"],
|
methods: ["GET", "POST"],
|
||||||
credentials: true,
|
credentials: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ deploy_services() {
|
|||||||
|
|
||||||
# 构建镜像
|
# 构建镜像
|
||||||
log_info "构建Docker镜像..."
|
log_info "构建Docker镜像..."
|
||||||
docker-compose build --no-cache --parallel
|
docker-compose build --parallel
|
||||||
|
|
||||||
# 启动服务
|
# 启动服务
|
||||||
log_info "启动服务..."
|
log_info "启动服务..."
|
||||||
|
|||||||
+7
-3
@@ -45,7 +45,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./logs:/app/logs
|
- ./logs:/app/logs
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
|
test: ["CMD", "node", "health-check.js"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
@@ -60,6 +60,10 @@ services:
|
|||||||
- HTTP_PROXY=${HTTP_PROXY}
|
- HTTP_PROXY=${HTTP_PROXY}
|
||||||
- HTTPS_PROXY=${HTTPS_PROXY}
|
- HTTPS_PROXY=${HTTPS_PROXY}
|
||||||
- NO_PROXY=${NO_PROXY}
|
- NO_PROXY=${NO_PROXY}
|
||||||
|
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
||||||
|
- NEXT_PUBLIC_TURN_HOST=${NEXT_PUBLIC_TURN_HOST}
|
||||||
|
- NEXT_PUBLIC_TURN_USERNAME=${NEXT_PUBLIC_TURN_USERNAME}
|
||||||
|
- NEXT_PUBLIC_TURN_PASSWORD=${NEXT_PUBLIC_TURN_PASSWORD}
|
||||||
container_name: privydrop-frontend
|
container_name: privydrop-frontend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
@@ -75,11 +79,11 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- privydrop-network
|
- privydrop-network
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3002/api/health"]
|
test: ["CMD", "node", "health-check.js"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 60s
|
start_period: 120s
|
||||||
|
|
||||||
# Nginx反向代理
|
# Nginx反向代理
|
||||||
nginx:
|
nginx:
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ generate_env_file() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 计算不同部署模式下的访问入口
|
# 计算不同部署模式下的访问入口
|
||||||
local cors_origin="http://${LOCAL_IP}:3002"
|
# 同时支持 localhost 与 本机IP,两者都可用于浏览器访问,便于Docker直连或本机调试
|
||||||
|
local cors_origin="http://${LOCAL_IP}:3002,http://localhost:3002"
|
||||||
local api_url="http://${LOCAL_IP}:3001"
|
local api_url="http://${LOCAL_IP}:3001"
|
||||||
local ssl_mode="self-signed"
|
local ssl_mode="self-signed"
|
||||||
local turn_enabled="false"
|
local turn_enabled="false"
|
||||||
@@ -66,7 +67,7 @@ generate_env_file() {
|
|||||||
local next_public_turn_password=""
|
local next_public_turn_password=""
|
||||||
|
|
||||||
if [[ "$DEPLOYMENT_MODE" == "public" ]]; then
|
if [[ "$DEPLOYMENT_MODE" == "public" ]]; then
|
||||||
cors_origin="http://${DOMAIN_NAME:-$LOCAL_IP}"
|
cors_origin="http://${DOMAIN_NAME:-$LOCAL_IP},http://localhost"
|
||||||
api_url="$cors_origin"
|
api_url="$cors_origin"
|
||||||
turn_enabled="true"
|
turn_enabled="true"
|
||||||
elif [[ "$DEPLOYMENT_MODE" == "full" ]]; then
|
elif [[ "$DEPLOYMENT_MODE" == "full" ]]; then
|
||||||
|
|||||||
+18
-3
@@ -4,10 +4,20 @@ FROM node:18-alpine AS builder
|
|||||||
ARG HTTP_PROXY
|
ARG HTTP_PROXY
|
||||||
ARG HTTPS_PROXY
|
ARG HTTPS_PROXY
|
||||||
ARG NO_PROXY
|
ARG NO_PROXY
|
||||||
|
ARG NEXT_PUBLIC_API_URL
|
||||||
|
ARG NEXT_PUBLIC_TURN_HOST
|
||||||
|
ARG NEXT_PUBLIC_TURN_USERNAME
|
||||||
|
ARG NEXT_PUBLIC_TURN_PASSWORD
|
||||||
|
|
||||||
ENV http_proxy=${HTTP_PROXY} \
|
ENV http_proxy ${HTTP_PROXY} \
|
||||||
https_proxy=${HTTPS_PROXY} \
|
https_proxy ${HTTPS_PROXY} \
|
||||||
no_proxy=${NO_PROXY}
|
no_proxy ${NO_PROXY}
|
||||||
|
|
||||||
|
# 前端构建期注入可公开环境变量(用于客户端直连后端与 TURN)
|
||||||
|
ENV NEXT_PUBLIC_API_URL ${NEXT_PUBLIC_API_URL}
|
||||||
|
ENV NEXT_PUBLIC_TURN_HOST ${NEXT_PUBLIC_TURN_HOST}
|
||||||
|
ENV NEXT_PUBLIC_TURN_USERNAME ${NEXT_PUBLIC_TURN_USERNAME}
|
||||||
|
ENV NEXT_PUBLIC_TURN_PASSWORD ${NEXT_PUBLIC_TURN_PASSWORD}
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
# 复制package文件
|
# 复制package文件
|
||||||
@@ -62,3 +72,8 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|||||||
|
|
||||||
# 启动应用
|
# 启动应用
|
||||||
CMD ["node", "server.js"]
|
CMD ["node", "server.js"]
|
||||||
|
# 运行期保留公开变量(非必需,但便于服务端渲染读取)
|
||||||
|
ENV NEXT_PUBLIC_API_URL ${NEXT_PUBLIC_API_URL}
|
||||||
|
ENV NEXT_PUBLIC_TURN_HOST ${NEXT_PUBLIC_TURN_HOST}
|
||||||
|
ENV NEXT_PUBLIC_TURN_USERNAME ${NEXT_PUBLIC_TURN_USERNAME}
|
||||||
|
ENV NEXT_PUBLIC_TURN_PASSWORD ${NEXT_PUBLIC_TURN_PASSWORD}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
"@types/hast": "^3.0.4",
|
"@types/hast": "^3.0.4",
|
||||||
"@types/mdast": "^4.0.4",
|
"@types/mdast": "^4.0.4",
|
||||||
"@types/negotiator": "^0.6.3",
|
"@types/negotiator": "^0.6.3",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20.14.13",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@types/unist": "^3.0.3",
|
"@types/unist": "^3.0.3",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -39,8 +39,8 @@
|
|||||||
"next-mdx-remote": "^5.0.0",
|
"next-mdx-remote": "^5.0.0",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"qrcode.react": "^4.0.1",
|
"qrcode.react": "^4.0.1",
|
||||||
"react": "^18",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18.3.1",
|
||||||
"react-intersection-observer": "^9.16.0",
|
"react-intersection-observer": "^9.16.0",
|
||||||
"remark-gfm": "^4.0.0",
|
"remark-gfm": "^4.0.0",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
@@ -52,11 +52,11 @@
|
|||||||
"zustand": "^5.0.7"
|
"zustand": "^5.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.3.18",
|
"@types/react": "^18.3.22",
|
||||||
"eslint": "^8",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-next": "14.2.5",
|
"eslint-config-next": "14.2.5",
|
||||||
"postcss": "^8",
|
"postcss": "^8.4.40",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.7",
|
||||||
"typescript": "^5"
|
"typescript": "^5.5.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+2218
-4501
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user