部署

Docker 构建

本项目使用基于 node:22-alpine 的两阶段 Docker 构建。

阶段 1 --- 构建器:

FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
ARG NEXT_PUBLIC_START_URL
ARG NEXT_PUBLIC_SIGNUP_URL
ARG NEXT_PUBLIC_SITE_URL
RUN npm run build

阶段 2 --- 运行器:

FROM node:22-alpine
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]

构建依赖于 Next.js 的 output: 'standalone' 模式,该模式会在 .next/standalone 目录下生成一个自包含的 server.js。最终镜像不包含 node_modules --- 所有必要的依赖项均由 Next.js 打包到 standalone 输出中。

Next.js 遥测在两个阶段中均已禁用。

NEXT_PUBLIC_* 环境变量通过 Docker ARG 声明在构建时嵌入到客户端 bundle 中。请使用 --build-arg 传递这些变量。

构建镜像:

docker build -t flexgalaxy-www \
  --build-arg NEXT_PUBLIC_SITE_URL=https://flexgalaxy.ai \
  --build-arg NEXT_PUBLIC_START_URL=https://console.flexgalaxy.ai/start/ \
  --build-arg NEXT_PUBLIC_SIGNUP_URL="https://console.flexgalaxy.ai/start/?register=true" \
  .

运行容器:

docker run -p 3000:3000 \
  -e STRAPI_URL=https://cms.flexgalaxy.ai \
  flexgalaxy-www

Next.js 配置

next.config.ts 包含两项重要设置:

  • Sass: 抑制 legacy-js-api 弃用警告,这是兼容 @carbon/styles SCSS 所必需的

  • 图片: 允许 <Image>http://localhost:1337/uploads/**``(本地 Strapi)加载图片。在生产环境中,请将 Strapi 生产主机名添加到 ``remotePatterns

next.config.ts 中没有 i18n 配置 --- 语言路由完全由中间件处理。

环境变量

变量

默认值

说明

STRAPI_URL

http://localhost:1337

Strapi CMS 基础 URL

NEXT_PUBLIC_SITE_URL

http://localhost:3000

网站公开 URL (SEO 元数据)

NEXT_PUBLIC_START_URL

https://console.flexgalaxy.ai/start/

SSR fallback for Login button

NEXT_PUBLIC_SIGNUP_URL

https://console.flexgalaxy.ai/start/?register=true

SSR fallback for Sign Up CTA

NODE_ENV

部署

不使用 Docker 进行生产构建:

NEXT_TELEMETRY_DISABLED

1 (in Docker)

禁用 Next.js 遥测

NEXT_PUBLIC_* 变量由 Next.js 在构建时嵌入。在 Docker 构建中,它们通过 ARG / ENV 对注入。在运行时,只有服务器端变量(STRAPI_URL)可以被覆盖。

备注

Since March 2026, Login, Sign Up, and Admin URLs are derived at runtime from the browser hostname via useConsoleUrls() in src/lib/consoleUrl.ts. The NEXT_PUBLIC_START_URL and NEXT_PUBLIC_SIGNUP_URL variables now serve only as SSR fallbacks displayed during server-side rendering before client-side hydration computes the correct domain-specific URL.

This means a single Docker image works on both .ai (international) and .com (China) deployments without requiring a separate build per partition. See 架构 for details on the derivation logic.

生产构建

不使用 Docker 进行生产构建:

npm run build
npm start

build 命令在 .next/ 目录下生成优化后的输出。start 命令在端口 3000 上提供生产构建服务。

CI/CD

文档通过 deploy-docs.yml GitHub Actions 工作流进行构建和部署。该工作流会将 SiriusVoyager/infra-common 与项目一同检出,以访问共享的 Makefile、构建脚本和 Carbon 主题。

文档构建使用 infra-common/docs/build-i18n.sh,该脚本从 conf.py 中读取项目名称并生成多语言 HTML 输出。

AWS 基础设施

www 应用作为租户部署在 DotID AWS 账户中的 DotID EKS 集群上。Terraform 配置位于 terraform/ 目录中。

Dual-partition deployment:

Partition

Domain

DNS Provider

AWS Region

International

flexgalaxy.ai

GoDaddy

ap-northeast-1

China

flexgalaxy.com

Aliyun (Alibaba Cloud)

cn-north-1

AWS accounts (China partition):

Account

AWS Account ID

Profile

Use

DotID CN

890180556369

fg-dotid-cn-prod

Keycloak, EKS cluster, www, OrbitCast

Infra CN

890176879308

fg-ai-cn-prod-deploy

NovaBell, api-gateway (SSO via cn-northwest-1)

IaC State CN

890078969307

iac-infrastructure

Terraform state (S3 + DynamoDB) only

AWS accounts (International partition):

Deploy with the deploy.sh script:

# International (prod)
./deploy.sh prod --partition intl

# China (prod)
./deploy.sh prod --partition cn

# Dev
./deploy.sh dev

来自 DotID 的共享基础设施(通过 remote state):

  • VPC、EKS 集群(计算资源)

  • ACM wildcard certificate for TLS termination

由 www Terraform 管理:

  • 用于 www Docker 镜像的 ECR 仓库

  • Kubernetes 命名空间(www)、deployment、service 和 configmap

  • 通过共享 ACM 证书提供 TLS 的 NLB(面向互联网)

  • CloudFront CDN distribution (intl partition) for static asset caching

DNS is managed externally, NOT in AWS Route53:

  • flexgalaxy.ai --- GoDaddy (international partition)

  • flexgalaxy.com --- Aliyun / Alibaba Cloud DNS (China partition)

After terraform apply, create CNAME records manually in the respective DNS provider. Terraform outputs www_nlb_hostname and cdn_acm_validation_records to help with DNS setup.

CDN

International partition uses CloudFront (global) with managed cache policies and ACM certificates. Configuration is in cdn.tf, controlled by enable_cdn = true in prod-intl.tfvars.

China partition uses CloudFront China (*.cloudfront.cn), which has significant limitations compared to the global service:

  • aws_cloudfront_cache_policynot supported in China regions

  • aws_cloudfront_origin_request_policynot supported in China regions

  • ACM certificates — not supported for CloudFront China; must use IAM-uploaded server certificates instead

The current cdn.tf only supports the international partition. China partition CDN requires a separate implementation using legacy forwarded_values blocks and IAM certificate references.

Current production (legacy):

The existing www.flexgalaxy.com CDN is a CloudFront China distribution (d341g2nskxpja3.cloudfront.cn) managed in the fg-ai-ops account (148308503730). It was created by the old Terraform codebase and uses:

  • IAM certificate ASCASFB7AFSZC7VW5X6UC

  • Legacy ForwardedValues (forwards all cookies + query strings, no headers)

  • Single default cache behavior (no separate static asset caching)

  • HTTP/1.1 only, IPv6 disabled

  • Origin: NLB in cn-northwest-1, port 8080

CDN AWS account (China):

Account

AWS Account ID

Profile

Use

fg-ai-ops

148308503730

fg-ai-ops-cdn-deploy

CloudFront China distributions

This account is a member of the AWS CN organization (management account 633349536424 / sr-awscn-admin).

TODO: China CDN Migration

Migrate the CN partition CDN from the legacy setup to Terraform-managed configuration. This work should be done separately from the initial www CN deployment.

1. Make cdn.tf partition-aware:

  • Add is_china_partition variable (bool, default false)

  • CN mode: use forwarded_values blocks instead of cache/origin-request policy resources

  • CN mode: use var.cdn_iam_certificate_id instead of ACM

  • CN mode: use http2 (not http2and3)

  • CN mode: enable IPv6

  • Add separate /_next/static/* and /images/* cache behaviors with aggressive TTLs (missing from legacy config)

  • Add Accept-Language header forwarding in default behavior for i18n

2. Consolidate docs.flexgalaxy.com into www.flexgalaxy.com/docs/legacy:

The docs.flexgalaxy.com distribution (EXIZH9G3CAXFK in fg-ai-ops) currently serves:

  • Default: NLB port 8081 (main docs site)

  • /en-us/organization/latest/api/*: S3 origin fws-cn-api-reference-docs.s3.cn-northwest-1.amazonaws.com.cn (path: /fws-global-published/organization/website)

Migration steps:

  • Add S3 origin to the www distribution for /docs/legacy/* path

  • Add a Next.js rewrite rule or CloudFront behavior to route /docs/legacy/* to the S3 bucket

  • Verify content is accessible at new path

  • Disable and delete the docs.flexgalaxy.com distribution

  • Remove docs.flexgalaxy.com CNAME from Aliyun DNS

  • Add redirect from docs.flexgalaxy.comwww.flexgalaxy.com/docs/legacy during transition period

3. Deploy new CN CDN:

  • Set enable_cdn = true and is_china_partition = true in prod-cn.tfvars

  • Set cdn_iam_certificate_id = "ASCASFB7AFSZC7VW5X6UC" (reuse existing IAM cert, or upload a new one)

  • Deploy with ./deploy.sh prod --partition cn

  • Update www.flexgalaxy.com CNAME in Aliyun to point to the new distribution

  • Disable and delete the legacy distribution (E38L5N5NHTWU77)