diff --git a/docker/nocobase/docker-entrypoint.sh b/docker/nocobase/docker-entrypoint.sh index 63b9dcdb524..8f5650c0d48 100755 --- a/docker/nocobase/docker-entrypoint.sh +++ b/docker/nocobase/docker-entrypoint.sh @@ -43,6 +43,7 @@ fi NOCOBASE_PROXY_PROVIDER="${NOCOBASE_PROXY_PROVIDER:-nginx}" NOCOBASE_PROXY_STORAGE_PATH="${NOCOBASE_PROXY_STORAGE_PATH:-/app/nocobase/storage}" NOCOBASE_PROXY_UPSTREAM_HOST="${NOCOBASE_PROXY_UPSTREAM_HOST:-${NGINX_UPSTREAM_HOST:-127.0.0.1}}" +NOCOBASE_PROXY_UPSTREAM_PORT="${NOCOBASE_PROXY_UPSTREAM_PORT:-${APP_PORT:-13000}}" NGINX_CONF_PATH="/app/nocobase/storage/nocobase.conf" cd /app/nocobase && yarn nocobase db:auth @@ -76,23 +77,23 @@ case "${NOCOBASE_EXTRACT_CLIENT_ASSETS:-false}" in cd /app/nocobase && nb proxy nginx generate \ --manual \ --name default \ - --app-port "${APP_PORT:-13000}" \ --storage-path "${NOCOBASE_PROXY_STORAGE_PATH}" \ --dist-root-path /app/nocobase/storage/dist-client \ --runtime-version "${ACTIVE_VERSION}" \ --app-public-path "${APP_PUBLIC_PATH_VALUE}" \ --upstream-host "${NOCOBASE_PROXY_UPSTREAM_HOST}" \ + --upstream-port "${NOCOBASE_PROXY_UPSTREAM_PORT}" \ --cdn-base-url "${PROXY_CDN_BASE_URL}" else cd /app/nocobase && nb proxy nginx generate \ --manual \ --name default \ - --app-port "${APP_PORT:-13000}" \ --storage-path "${NOCOBASE_PROXY_STORAGE_PATH}" \ --dist-root-path /app/nocobase/storage/dist-client \ --runtime-version "${ACTIVE_VERSION}" \ --app-public-path "${APP_PUBLIC_PATH_VALUE}" \ - --upstream-host "${NOCOBASE_PROXY_UPSTREAM_HOST}" + --upstream-host "${NOCOBASE_PROXY_UPSTREAM_HOST}" \ + --upstream-port "${NOCOBASE_PROXY_UPSTREAM_PORT}" fi NGINX_CONF_PATH="${NB_CLI_ROOT}/.nocobase/proxy/nginx/nocobase.conf" ;; @@ -102,23 +103,23 @@ case "${NOCOBASE_EXTRACT_CLIENT_ASSETS:-false}" in cd /app/nocobase && nb proxy caddy generate \ --manual \ --name default \ - --app-port "${APP_PORT:-13000}" \ --storage-path "${NOCOBASE_PROXY_STORAGE_PATH}" \ --dist-root-path /app/nocobase/storage/dist-client \ --runtime-version "${ACTIVE_VERSION}" \ --app-public-path "${APP_PUBLIC_PATH_VALUE}" \ --upstream-host "${NOCOBASE_PROXY_UPSTREAM_HOST}" \ + --upstream-port "${NOCOBASE_PROXY_UPSTREAM_PORT}" \ --cdn-base-url "${PROXY_CDN_BASE_URL}" else cd /app/nocobase && nb proxy caddy generate \ --manual \ --name default \ - --app-port "${APP_PORT:-13000}" \ --storage-path "${NOCOBASE_PROXY_STORAGE_PATH}" \ --dist-root-path /app/nocobase/storage/dist-client \ --runtime-version "${ACTIVE_VERSION}" \ --app-public-path "${APP_PUBLIC_PATH_VALUE}" \ - --upstream-host "${NOCOBASE_PROXY_UPSTREAM_HOST}" + --upstream-host "${NOCOBASE_PROXY_UPSTREAM_HOST}" \ + --upstream-port "${NOCOBASE_PROXY_UPSTREAM_PORT}" fi ;; *) diff --git a/docs/docs/cn/api/cli/config/delete.md b/docs/docs/cn/api/cli/config/delete.md index 77c10fc6ae9..752742fa705 100644 --- a/docs/docs/cn/api/cli/config/delete.md +++ b/docs/docs/cn/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "nb config delete 命令参考:删除某个显式设置的 CLI 配置项。" -keywords: "nb config delete,NocoBase CLI,删除配置" +title: 'nb config delete' +description: 'nb config delete 命令参考:删除某个显式设置的 CLI 配置项。' +keywords: 'nb config delete,NocoBase CLI,删除配置' --- # nb config delete @@ -16,8 +16,8 @@ nb config delete ## 参数 -| 参数 | 类型 | 说明 | -| --- | --- | --- | +| 参数 | 类型 | 说明 | +| ------- | ------ | ------------------------------------------------ | | `` | string | 配置项名称;支持的值见 [`nb config`](./index.md) | ## 示例 @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/cn/api/cli/config/get.md b/docs/docs/cn/api/cli/config/get.md index 02cd949a2f4..008087e1655 100644 --- a/docs/docs/cn/api/cli/config/get.md +++ b/docs/docs/cn/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "nb config get 命令参考:读取某个 CLI 配置项的生效值。" -keywords: "nb config get,NocoBase CLI,读取配置" +title: 'nb config get' +description: 'nb config get 命令参考:读取某个 CLI 配置项的生效值。' +keywords: 'nb config get,NocoBase CLI,读取配置' --- # nb config get @@ -16,8 +16,8 @@ nb config get ## 参数 -| 参数 | 类型 | 说明 | -| --- | --- | --- | +| 参数 | 类型 | 说明 | +| ------- | ------ | ------------------------------------------------ | | `` | string | 配置项名称;支持的值见 [`nb config`](./index.md) | ## 示例 @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/cn/api/cli/config/index.md b/docs/docs/cn/api/cli/config/index.md index b2cd741709a..35e89d23b66 100644 --- a/docs/docs/cn/api/cli/config/index.md +++ b/docs/docs/cn/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "nb config 命令参考:管理 NocoBase CLI 的默认配置项。" -keywords: "nb config,NocoBase CLI,配置,默认配置" +title: 'nb config' +description: 'nb config 命令参考:管理 NocoBase CLI 的默认配置项。' +keywords: 'nb config,NocoBase CLI,配置,默认配置' --- # nb config @@ -10,28 +10,41 @@ keywords: "nb config,NocoBase CLI,配置,默认配置" - CLI 自身:`locale`、`update.policy`、`license.pkg-url` - Docker 运行:`docker.network`、`docker.container-prefix` +- NocoBase 官方镜像:`nb-image-registry`、`nb-image-variant` - 外部可执行文件:`bin.docker`、`bin.caddy`、`bin.git`、`bin.nginx`、`bin.pnpm`、`bin.yarn` - 代理生成:`proxy.nb-cli-root`、`proxy.upstream-host`、`proxy.nginx-driver`、`proxy.caddy-driver` +多数项目只需要配置少数几个键,常见的是: + +- `update.policy` +- `docker.network` +- `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` +- `bin.nginx` 或 `bin.caddy` +- `proxy.nginx-driver` 或 `proxy.caddy-driver` + ## 常用配置项 -| 配置项 | 默认值 | 说明 | -| --- | --- | --- | -| `locale` | 按 CLI 当前规则解析 | 覆盖 CLI 使用的语言 | -| `update.policy` | `prompt` | 启动时更新策略:`prompt`、`auto` 或 `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | 覆盖商业扩展包下载地址 | -| `docker.network` | `nocobase` | CLI 管理的 Docker 应用默认网络 | -| `docker.container-prefix` | `nb` | CLI 管理的 Docker 容器默认前缀 | -| `bin.docker` | `docker` | 覆盖 Docker 可执行文件路径 | -| `bin.caddy` | `caddy` | 覆盖 Caddy 可执行文件路径 | -| `bin.git` | `git` | 覆盖 Git 可执行文件路径 | -| `bin.nginx` | `nginx` | 覆盖 Nginx 可执行文件路径 | -| `bin.pnpm` | `pnpm` | 覆盖 pnpm 可执行文件路径 | -| `bin.yarn` | `yarn` | 覆盖 Yarn 可执行文件路径 | -| `proxy.nb-cli-root` | CLI root(通常是当前用户 Home 目录) | 把 `.nocobase` 路径映射到代理进程实际看到的根目录 | -| `proxy.upstream-host` | `127.0.0.1` | 代理回源到 NocoBase 应用时使用的主机地址 | -| `proxy.nginx-driver` | `local` | `nb proxy nginx` 默认使用的运行方式 | -| `proxy.caddy-driver` | `local` | `nb proxy caddy` 默认使用的运行方式 | +| 配置项 | 默认值 | 说明 | +| ------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- | +| `locale` | 按 CLI 当前规则解析 | 覆盖 CLI 使用的语言 | +| `update.policy` | `prompt` | 启动时更新策略:`prompt`、`auto` 或 `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | 覆盖商业扩展包下载地址 | +| `docker.network` | `nocobase` | CLI 管理的 Docker 应用默认网络 | +| `docker.container-prefix` | `nb` | CLI 管理的 Docker 容器默认前缀 | +| `nb-image-registry` | `dockerhub` | 官方 NocoBase 镜像默认使用的仓库体系:`dockerhub` 或 `aliyun` | +| `nb-image-variant` | `full` | 官方 NocoBase 应用镜像默认使用的标签变体:`standard`、`no-nginx`、`full` 或 `full-no-nginx` | +| `bin.docker` | `docker` | 覆盖 Docker 可执行文件路径 | +| `bin.caddy` | `caddy` | 覆盖 Caddy 可执行文件路径 | +| `bin.git` | `git` | 覆盖 Git 可执行文件路径 | +| `bin.nginx` | `nginx` | 覆盖 Nginx 可执行文件路径 | +| `bin.pnpm` | `pnpm` | 覆盖 pnpm 可执行文件路径 | +| `bin.yarn` | `yarn` | 覆盖 Yarn 可执行文件路径 | +| `proxy.nb-cli-root` | CLI root(通常是当前用户 Home 目录) | 把 `.nocobase` 路径映射到代理进程实际看到的根目录 | +| `proxy.upstream-host` | `127.0.0.1` | 代理回源到 NocoBase 应用时使用的主机地址 | +| `proxy.nginx-driver` | `local` | `nb proxy nginx` 默认使用的运行方式 | +| `proxy.caddy-driver` | `local` | `nb proxy caddy` 默认使用的运行方式 | ## 用法 @@ -41,12 +54,12 @@ nb config ## 子命令 -| 命令 | 说明 | -| --- | --- | -| [`nb config get`](./get.md) | 读取某个配置项的生效值 | -| [`nb config set`](./set.md) | 设置某个配置项 | -| [`nb config delete`](./delete.md) | 删除某个显式配置项 | -| [`nb config list`](./list.md) | 列出当前显式设置过的配置项 | +| 命令 | 说明 | +| --------------------------------- | -------------------------- | +| [`nb config get`](./get.md) | 读取某个配置项的生效值 | +| [`nb config set`](./set.md) | 设置某个配置项 | +| [`nb config delete`](./delete.md) | 删除某个显式配置项 | +| [`nb config list`](./list.md) | 列出当前显式设置过的配置项 | ## 示例 @@ -61,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -69,7 +85,10 @@ nb config delete docker.container-prefix ## 说明 -`bin.pnpm` 会在命令需要直接运行 pnpm 时使用,比如 `nb self update` 更新由 pnpm 管理的全局 CLI 安装。 +- `bin.pnpm` 会在命令需要直接运行 pnpm 时使用,比如 `nb self update` 更新由 pnpm 管理的全局 CLI 安装 +- `nb-image-registry` 只影响 CLI 为官方 NocoBase 镜像推导出来的默认值。`dockerhub` 对应应用镜像仓库 `nocobase/nocobase`,`aliyun` 对应 `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` 只影响官方 NocoBase 应用镜像的 tag。以版本 `1.7.14` 为例,`standard` 对应 `1.7.14`,`no-nginx` 对应 `1.7.14-no-nginx`,`full` 对应 `1.7.14-full`,`full-no-nginx` 对应 `1.7.14-full-no-nginx` +- 当 `nb-image-registry=aliyun` 时,CLI 也会把内置 PostgreSQL、MySQL、MariaDB 和 Kingbase 的默认数据库镜像切到阿里云官方镜像地址 ## 相关命令 diff --git a/docs/docs/cn/api/cli/config/set.md b/docs/docs/cn/api/cli/config/set.md index e229b473403..077dfc51aed 100644 --- a/docs/docs/cn/api/cli/config/set.md +++ b/docs/docs/cn/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "nb config set 命令参考:设置某个 CLI 配置项。" -keywords: "nb config set,NocoBase CLI,设置配置" +title: 'nb config set' +description: 'nb config set 命令参考:设置某个 CLI 配置项。' +keywords: 'nb config set,NocoBase CLI,设置配置' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## 参数 -| 参数 | 类型 | 说明 | -| --- | --- | --- | -| `` | string | 配置项名称;支持的值见 [`nb config`](./index.md) | -| `` | string | 配置值,不能为空 | +| 参数 | 类型 | 说明 | +| --------- | ------ | ------------------------------------------------ | +| `` | string | 配置项名称;支持的值见 [`nb config`](./index.md) | +| `` | string | 配置值,不能为空 | ## 示例 @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## 说明 -`update.policy` 支持 `prompt`、`auto` 和 `off`,默认值为 `prompt`。 +- `update.policy` 支持 `prompt`、`auto` 和 `off`,默认值为 `prompt` +- `nb-image-registry` 支持 `dockerhub` 和 `aliyun`,默认值为 `dockerhub` +- `nb-image-variant` 支持 `standard`、`no-nginx`、`full` 和 `full-no-nginx`,默认值为 `full` ## 相关命令 diff --git a/docs/docs/cn/get-started/_meta.json b/docs/docs/cn/get-started/_meta.json index 679f889edfd..50542f6f01c 100644 --- a/docs/docs/cn/get-started/_meta.json +++ b/docs/docs/cn/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Docker 安装", + "label": "Docker 安装(内置 Nginx)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Docker 安装(外部 Nginx)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Docker 安装(外部 Caddy)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "create-nocobase-app 安装", diff --git a/docs/docs/cn/get-started/installation/docker-caddy.mdx b/docs/docs/cn/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..8eb1f11b57a --- /dev/null +++ b/docs/docs/cn/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Docker 安装(外部 Caddy)" +description: "使用 Docker 安装 NocoBase,并通过外部 Caddy 容器作为独立入口。" +keywords: "Docker,NocoBase,Caddy,安装,反向代理" +--- + +# Docker 安装(外部 Caddy) + +这种方式里,NocoBase 应用容器和 Caddy 容器分别运行。你可以先按 [Docker 安装(内置 Nginx)](./docker.mdx) 完成基础安装,再把入口切换为外部 Caddy 容器。 + +## 什么时候用这种方式 + +- 希望把 NocoBase 和 Web 服务器分开部署 +- 希望用 Caddy 简化反向代理和 HTTPS 配置 +- 希望只对外暴露代理容器,应用容器只在内部网络通信 + +## docker-compose.yml 示例 + +下面的示例使用镜像:`nocobase/nocobase:latest-full-no-nginx`。 + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-full-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Asia/Shanghai + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## 关键点 + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` 用于提取前端静态资源,并生成代理配置 +- `NOCOBASE_PROXY_PROVIDER=caddy` 表示生成 Caddy 配置 +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` 表示让 Caddy 容器通过 Compose 网络访问 `app` 服务 +- `./storage` 需要同时挂载到 `app` 和 `caddy` 容器,方便共享代理配置、静态资源和上传文件 +- `caddy` 容器启动前需要等待 `nocobase.caddy` 生成,再通过 `ln -sf` 链接到 `/etc/caddy/Caddyfile` +- 只需要对外暴露 Caddy 容器端口,`app` 服务不需要对宿主机暴露端口 + +## 如果使用宿主机本地 Caddy + +如果你的 Caddy 不是运行在 Docker 容器里,而是直接安装在宿主机上,建议单独使用一份 `docker-compose.yml`。这种情况下,`app` 需要直接对宿主机暴露端口,同时代理相关环境变量也要改成宿主机视角。 + +可以参考下面的 `docker-compose.yml`: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-full-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Asia/Shanghai + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +其中: + +- `NOCOBASE_PROXY_STORAGE_PATH` 需要写成宿主机上的 `storage` 绝对路径 +- `NOCOBASE_PROXY_UPSTREAM_HOST` 需要改成 `127.0.0.1` +- `app` 服务需要保留 `ports`,这样宿主机本地 Caddy 才能通过 `127.0.0.1:13000` 访问到应用 + +启动 `app` 容器后,再在宿主机上等待配置文件生成,并把它链接到本地 Caddy 配置路径: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +如果你的宿主机 Caddy 没有使用 `/etc/caddy/Caddyfile`,需要把链接路径改成你自己的配置路径。通常来说,保持 `nocobase.caddy` 作为主入口文件会更稳妥,不建议手动拆开后再复制内容。 + +## 相关链接 + +- [Docker 安装(内置 Nginx)](./docker.mdx) — 从单容器安装开始 +- [Caddy 静态资源代理](../deployment/static-resource-proxy/caddy.md) — 了解生成的 Caddy 配置 diff --git a/docs/docs/cn/get-started/installation/docker-nginx.mdx b/docs/docs/cn/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..0071eca13b8 --- /dev/null +++ b/docs/docs/cn/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Docker 安装(外部 Nginx)" +description: "使用 Docker 安装 NocoBase,并通过外部 Nginx 容器作为独立入口。" +keywords: "Docker,NocoBase,Nginx,安装,反向代理" +--- + +# Docker 安装(外部 Nginx) + +这种方式里,NocoBase 应用容器和 Nginx 容器分别运行。你可以先按 [Docker 安装(内置 Nginx)](./docker.mdx) 完成基础安装,再把入口切换为外部 Nginx 容器。 + +## 什么时候用这种方式 + +- 希望把 NocoBase 和 Web 服务器分开部署 +- 希望自己维护 Nginx 配置和端口暴露 +- 希望只对外暴露代理容器,应用容器只在内部网络通信 + +## docker-compose.yml 示例 + +下面的示例使用镜像:`nocobase/nocobase:latest-full-no-nginx`。 + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-full-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Asia/Shanghai + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## 关键点 + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` 用于提取前端静态资源,并生成代理配置 +- `NOCOBASE_PROXY_PROVIDER=nginx` 表示生成 Nginx 配置 +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` 表示让 Nginx 容器通过 Compose 网络访问 `app` 服务 +- `./storage` 需要同时挂载到 `app` 和 `nginx` 容器,方便共享代理配置、静态资源和上传文件 +- `nginx` 容器启动前需要等待 `nocobase.conf` 生成,再通过 `ln -sf` 链接到 `/etc/nginx/conf.d/default.conf` +- 如果使用内置 Nginx,`app` 容器本身通过 `ports: "13000:80"` 对外暴露端口 +- 如果使用外部 Nginx,只需要由 `nginx` 容器处理这个端口映射,`app` 服务不需要对宿主机暴露端口 + +## 如果使用宿主机本地 Nginx + +如果你的 Nginx 不是运行在 Docker 容器里,而是直接安装在宿主机上,建议单独使用一份 `docker-compose.yml`。这种情况下,`app` 需要直接对宿主机暴露端口,同时代理相关环境变量也要改成宿主机视角。 + +可以参考下面的 `docker-compose.yml`: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-full-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Asia/Shanghai + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +其中: + +- `NOCOBASE_PROXY_STORAGE_PATH` 需要写成宿主机上的 `storage` 绝对路径 +- `NOCOBASE_PROXY_UPSTREAM_HOST` 需要改成 `127.0.0.1` +- `app` 服务需要保留 `ports`,这样宿主机本地 Nginx 才能通过 `127.0.0.1:13000` 访问到应用 + +启动 `app` 容器后,再在宿主机上等待配置文件生成,并把它链接到本地 Nginx 配置目录: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +如果你的宿主机 Nginx 没有使用 `conf.d` 目录,需要把链接路径改成你自己的配置目录。通常来说,保持 `nocobase.conf` 作为 `http {}` 里的 include 文件会更稳妥,不建议手动拆开后再复制内容。 + +## 相关链接 + +- [Docker 安装(内置 Nginx)](./docker.mdx) — 从单容器安装开始 +- [Nginx 静态资源代理](../deployment/static-resource-proxy/nginx.md) — 了解生成的 Nginx 配置 diff --git a/docs/docs/de/api/cli/config/delete.md b/docs/docs/de/api/cli/config/delete.md index 044e8def8da..b7771aa62ff 100644 --- a/docs/docs/de/api/cli/config/delete.md +++ b/docs/docs/de/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "Referenz zum Befehl nb config delete: einen explizit gesetzten CLI-Konfigurationseintrag löschen." -keywords: "nb config delete,NocoBase CLI,Konfiguration löschen" +title: 'nb config delete' +description: 'Referenz zum Befehl nb config delete: einen explizit gesetzten CLI-Konfigurationseintrag löschen.' +keywords: 'nb config delete,NocoBase CLI,Konfiguration löschen' --- # nb config delete @@ -16,9 +16,9 @@ nb config delete ## Parameter -| Parameter | Typ | Beschreibung | -| --- | --- | --- | -| `` | string | Name des Konfigurationseintrags. Unterstützte Werte findest du unter [`nb config`](./index.md) | +| Parameter | Typ | Beschreibung | +| --------- | ------ | ---------------------------------------------------------------------------------------------- | +| `` | string | Name des Konfigurationseintrags. Unterstützte Werte findest du unter [`nb config`](./index.md) | ## Beispiele @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/de/api/cli/config/get.md b/docs/docs/de/api/cli/config/get.md index c2a75ecb0cc..c18ebdc85e2 100644 --- a/docs/docs/de/api/cli/config/get.md +++ b/docs/docs/de/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "Referenz zum Befehl nb config get: den wirksamen Wert eines CLI-Konfigurationseintrags lesen." -keywords: "nb config get,NocoBase CLI,Konfiguration lesen" +title: 'nb config get' +description: 'Referenz zum Befehl nb config get: den wirksamen Wert eines CLI-Konfigurationseintrags lesen.' +keywords: 'nb config get,NocoBase CLI,Konfiguration lesen' --- # nb config get @@ -16,9 +16,9 @@ nb config get ## Parameter -| Parameter | Typ | Beschreibung | -| --- | --- | --- | -| `` | string | Name des Konfigurationseintrags. Unterstützte Werte findest du unter [`nb config`](./index.md) | +| Parameter | Typ | Beschreibung | +| --------- | ------ | ---------------------------------------------------------------------------------------------- | +| `` | string | Name des Konfigurationseintrags. Unterstützte Werte findest du unter [`nb config`](./index.md) | ## Beispiele @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/de/api/cli/config/index.md b/docs/docs/de/api/cli/config/index.md index 1da48292ba3..c26edaa8fda 100644 --- a/docs/docs/de/api/cli/config/index.md +++ b/docs/docs/de/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "Referenz zu nb config: Standard-Konfigurationswerte der NocoBase CLI verwalten." -keywords: "nb config,NocoBase CLI,Konfiguration,Standardkonfiguration" +title: 'nb config' +description: 'Referenz zu nb config: Standard-Konfigurationswerte der NocoBase CLI verwalten.' +keywords: 'nb config,NocoBase CLI,Konfiguration,Standardkonfiguration' --- # nb config @@ -10,6 +10,7 @@ Verwaltet die Standard-Konfigurationswerte der CLI. Die aktuell unterstützten S - CLI selbst: `locale`, `update.policy`, `license.pkg-url` - Docker-Runtime: `docker.network`, `docker.container-prefix` +- Offizielle NocoBase-Images: `nb-image-registry`, `nb-image-variant` - Externe ausführbare Dateien: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - Proxy-Erzeugung: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ Die meisten Projekte brauchen nur wenige dieser Schlüssel. In der Praxis werden - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` oder `bin.caddy` - `proxy.nginx-driver` oder `proxy.caddy-driver` ## Häufige Konfigurationsschlüssel -| Schlüssel | Standardwert | Beschreibung | -| --- | --- | --- | -| `locale` | wird nach den aktuellen CLI-Regeln aufgelöst | Überschreibt die von der CLI verwendete Sprache | -| `update.policy` | `prompt` | Update-Richtlinie beim Start: `prompt`, `auto` oder `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | Überschreibt die Download-URL für kommerzielle Erweiterungspakete | -| `docker.network` | `nocobase` | Standardnetzwerk für CLI-verwaltete Docker-Anwendungen | -| `docker.container-prefix` | `nb` | Standardpräfix für CLI-verwaltete Docker-Container | -| `bin.docker` | `docker` | Überschreibt den Pfad zur Docker-Binärdatei | -| `bin.caddy` | `caddy` | Überschreibt den Pfad zur Caddy-Binärdatei | -| `bin.git` | `git` | Überschreibt den Pfad zur Git-Binärdatei | -| `bin.nginx` | `nginx` | Überschreibt den Pfad zur Nginx-Binärdatei | -| `bin.pnpm` | `pnpm` | Überschreibt den Pfad zur pnpm-Binärdatei | -| `bin.yarn` | `yarn` | Überschreibt den Pfad zur Yarn-Binärdatei | -| `proxy.nb-cli-root` | CLI-Root, normalerweise das Home-Verzeichnis des aktuellen Benutzers | Ordnet den `.nocobase`-Pfad auf den Root-Pfad ab, den der Proxy-Prozess tatsächlich sieht | -| `proxy.upstream-host` | `127.0.0.1` | Überschreibt die Host-Adresse, die der Proxy für die Rückleitung zur NocoBase-Anwendung verwendet | -| `proxy.nginx-driver` | `local` | Standard-Driver für `nb proxy nginx` | -| `proxy.caddy-driver` | `local` | Standard-Driver für `nb proxy caddy` | +| Schlüssel | Standardwert | Beschreibung | +| ------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | +| `locale` | wird nach den aktuellen CLI-Regeln aufgelöst | Überschreibt die von der CLI verwendete Sprache | +| `update.policy` | `prompt` | Update-Richtlinie beim Start: `prompt`, `auto` oder `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | Überschreibt die Download-URL für kommerzielle Erweiterungspakete | +| `docker.network` | `nocobase` | Standardnetzwerk für CLI-verwaltete Docker-Anwendungen | +| `docker.container-prefix` | `nb` | Standardpräfix für CLI-verwaltete Docker-Container | +| `nb-image-registry` | `dockerhub` | Standard-Registry-Familie für offizielle NocoBase-Images: `dockerhub` oder `aliyun` | +| `nb-image-variant` | `full` | Standard-Tag-Variante für offizielle NocoBase-App-Images: `standard`, `no-nginx`, `full` oder `full-no-nginx` | +| `bin.docker` | `docker` | Überschreibt den Pfad zur Docker-Binärdatei | +| `bin.caddy` | `caddy` | Überschreibt den Pfad zur Caddy-Binärdatei | +| `bin.git` | `git` | Überschreibt den Pfad zur Git-Binärdatei | +| `bin.nginx` | `nginx` | Überschreibt den Pfad zur Nginx-Binärdatei | +| `bin.pnpm` | `pnpm` | Überschreibt den Pfad zur pnpm-Binärdatei | +| `bin.yarn` | `yarn` | Überschreibt den Pfad zur Yarn-Binärdatei | +| `proxy.nb-cli-root` | CLI-Root, normalerweise das Home-Verzeichnis des aktuellen Benutzers | Ordnet den `.nocobase`-Pfad auf den Root-Pfad ab, den der Proxy-Prozess tatsächlich sieht | +| `proxy.upstream-host` | `127.0.0.1` | Überschreibt die Host-Adresse, die der Proxy für die Rückleitung zur NocoBase-Anwendung verwendet | +| `proxy.nginx-driver` | `local` | Standard-Driver für `nb proxy nginx` | +| `proxy.caddy-driver` | `local` | Standard-Driver für `nb proxy caddy` | ## Verwendung @@ -49,12 +54,12 @@ nb config ## Unterbefehle -| Befehl | Beschreibung | -| --- | --- | -| [`nb config get`](./get.md) | Effektiven Wert eines Konfigurationsschlüssels lesen | -| [`nb config set`](./set.md) | Einen Konfigurationsschlüssel setzen | -| [`nb config delete`](./delete.md) | Einen explizit gesetzten Konfigurationsschlüssel löschen | -| [`nb config list`](./list.md) | Derzeit explizit gesetzte Konfigurationsschlüssel auflisten | +| Befehl | Beschreibung | +| --------------------------------- | ----------------------------------------------------------- | +| [`nb config get`](./get.md) | Effektiven Wert eines Konfigurationsschlüssels lesen | +| [`nb config set`](./set.md) | Einen Konfigurationsschlüssel setzen | +| [`nb config delete`](./delete.md) | Einen explizit gesetzten Konfigurationsschlüssel löschen | +| [`nb config list`](./list.md) | Derzeit explizit gesetzte Konfigurationsschlüssel auflisten | ## Beispiele @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` und `bin.caddy` wirken sich nur auf den `local`-Driver von `nb proxy nginx` und `nb proxy caddy` aus - `bin.pnpm` wird verwendet, wenn Befehle pnpm direkt ausführen müssen, etwa beim Aktualisieren einer von pnpm verwalteten globalen CLI-Installation mit `nb self update` +- `nb-image-registry` betrifft nur die von der CLI verwendeten Standardwerte für offizielle NocoBase-Images. `dockerhub` verwendet das App-Image `nocobase/nocobase`, während `aliyun` `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` verwendet +- `nb-image-variant` betrifft nur die Tags offizieller NocoBase-App-Images. Bei Version `1.7.14` löst die CLI `standard` zu `1.7.14`, `no-nginx` zu `1.7.14-no-nginx`, `full` zu `1.7.14-full` und `full-no-nginx` zu `1.7.14-full-no-nginx` auf +- Wenn `nb-image-registry=aliyun` gesetzt ist, stellt die CLI auch die Standard-Images für eingebaute Datenbanken auf die offiziellen Aliyun-Mirrors für PostgreSQL, MySQL, MariaDB und Kingbase um - `proxy.nginx-driver` und `proxy.caddy-driver` speichern den Standard-Driver des jeweiligen Providers - `proxy.nb-cli-root` und `proxy.upstream-host` sind erweiterte Proxy-Overrides. Für die meisten CLI-verwalteten `local`- oder `docker`-Envs reichen die Standardwerte aus - Wenn du nur den aktiven Proxy-Driver umschalten möchtest, ist `nb proxy nginx use` oder `nb proxy caddy use` in der Regel klarer als das manuelle Setzen des Konfigurationsschlüssels diff --git a/docs/docs/de/api/cli/config/set.md b/docs/docs/de/api/cli/config/set.md index 6c739cfa8b1..2e8bead72ab 100644 --- a/docs/docs/de/api/cli/config/set.md +++ b/docs/docs/de/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "Referenz zum Befehl nb config set: einen CLI-Konfigurationseintrag setzen." -keywords: "nb config set,NocoBase CLI,Konfiguration setzen" +title: 'nb config set' +description: 'Referenz zum Befehl nb config set: einen CLI-Konfigurationseintrag setzen.' +keywords: 'nb config set,NocoBase CLI,Konfiguration setzen' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## Parameter -| Parameter | Typ | Beschreibung | -| --- | --- | --- | -| `` | string | Name des Konfigurationseintrags. Unterstützte Werte findest du unter [`nb config`](./index.md) | -| `` | string | Konfigurationswert, darf nicht leer sein | +| Parameter | Typ | Beschreibung | +| --------- | ------ | ---------------------------------------------------------------------------------------------- | +| `` | string | Name des Konfigurationseintrags. Unterstützte Werte findest du unter [`nb config`](./index.md) | +| `` | string | Konfigurationswert, darf nicht leer sein | ## Beispiele @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## Hinweise -`update.policy` unterstützt `prompt`, `auto` und `off`. Der Standardwert ist `prompt`. +- `update.policy` unterstützt `prompt`, `auto` und `off`. Der Standardwert ist `prompt` +- `nb-image-registry` unterstützt `dockerhub` und `aliyun`. Der Standardwert ist `dockerhub` +- `nb-image-variant` unterstützt `standard`, `no-nginx`, `full` und `full-no-nginx`. Der Standardwert ist `full` ## Verwandte Befehle diff --git a/docs/docs/de/get-started/_meta.json b/docs/docs/de/get-started/_meta.json index ef8fbf1677b..0cfc5cd03e3 100644 --- a/docs/docs/de/get-started/_meta.json +++ b/docs/docs/de/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Docker-Installation", + "label": "Docker-Installation (integriertes Nginx)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Docker-Installation (externes Nginx)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Docker-Installation (externes Caddy)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "Installation mit create-nocobase-app", diff --git a/docs/docs/de/get-started/installation/docker-caddy.mdx b/docs/docs/de/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..33c0df235e3 --- /dev/null +++ b/docs/docs/de/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Docker-Installation (externes Caddy)" +description: "Installiere NocoBase mit Docker und nutze einen externen Caddy-Container als Einstiegspunkt." +keywords: "Docker,NocoBase,Caddy,Installation,Reverse Proxy" +--- + +# Docker-Installation (externes Caddy) + +In diesem Setup laufen der NocoBase-App-Container und der Caddy-Container getrennt. Du kannst mit [Docker-Installation (integriertes Nginx)](./docker.mdx) starten und den Einstieg danach auf einen externen Caddy-Container umstellen. + +## Wann dieses Setup sinnvoll ist + +- Du möchtest NocoBase und den Webserver getrennt betreiben +- Du möchtest Reverse Proxy und HTTPS mit Caddy einfacher verwalten +- Du möchtest nur den Proxy-Container öffentlich erreichbar machen + +## Beispiel für docker-compose.yml + +Wenn du das `full`-Image brauchst, ersetze `latest-no-nginx` durch `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Wichtige Punkte + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrahiert die Client-Assets und erzeugt die Proxy-Konfiguration +- `NOCOBASE_PROXY_PROVIDER=caddy` legt fest, dass eine Caddy-Konfiguration erzeugt wird +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` ermöglicht dem Caddy-Container den Zugriff auf den Dienst `app` über das Compose-Netzwerk +- `./storage` muss sowohl in `app` als auch in `caddy` gemountet werden, damit Proxy-Konfiguration, statische Dateien und Uploads gemeinsam genutzt werden können +- Der `caddy`-Container sollte warten, bis `nocobase.caddy` erzeugt wurde, und die Datei dann mit `ln -sf` nach `/etc/caddy/Caddyfile` verlinken +- Nach außen sollte nur der Port des Caddy-Containers freigegeben werden. Der Dienst `app` muss keinen Port zum Host veröffentlichen + +## Wenn du ein lokales Caddy auf dem Host verwendest + +Wenn dein Caddy direkt auf dem Host installiert ist und nicht in einem Docker-Container läuft, solltest du besser ein separates `docker-compose.yml` verwenden. Dabei muss der Dienst `app` einen Port zum Host veröffentlichen, und die Proxy-Variablen müssen aus Host-Sicht gesetzt werden. + +Du kannst ein `docker-compose.yml` wie dieses verwenden: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +In dieser Variante: + +- `NOCOBASE_PROXY_STORAGE_PATH` sollte der absolute Host-Pfad des `storage`-Verzeichnisses sein +- `NOCOBASE_PROXY_UPSTREAM_HOST` sollte `127.0.0.1` sein +- Der Dienst `app` muss `ports` behalten, damit das lokale Caddy die Anwendung über `127.0.0.1:13000` erreichen kann + +Nachdem der `app`-Container gestartet wurde, warte auf die Generierung der Konfigurationsdatei und verlinke sie dann in den lokalen Caddy-Konfigurationspfad: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +Wenn dein Host-Caddy nicht `/etc/caddy/Caddyfile` verwendet, ersetze das Link-Ziel durch deinen eigenen Konfigurationspfad. In der Regel ist es sicherer, `nocobase.caddy` als Haupteinstiegsdatei zu behalten, statt ihren Inhalt manuell zu kopieren. + +## Verwandte Links + +- [Docker-Installation (integriertes Nginx)](./docker.mdx) — Starte mit dem Single-Container-Setup +- [Statischer Ressourcen-Proxy mit Caddy](../deployment/static-resource-proxy/caddy.md) — Mehr zur generierten Caddy-Konfiguration diff --git a/docs/docs/de/get-started/installation/docker-nginx.mdx b/docs/docs/de/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..c2e2aadc41d --- /dev/null +++ b/docs/docs/de/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Docker-Installation (externes Nginx)" +description: "Installiere NocoBase mit Docker und nutze einen externen Nginx-Container als Einstiegspunkt." +keywords: "Docker,NocoBase,Nginx,Installation,Reverse Proxy" +--- + +# Docker-Installation (externes Nginx) + +In diesem Setup laufen der NocoBase-App-Container und der Nginx-Container getrennt. Du kannst mit [Docker-Installation (integriertes Nginx)](./docker.mdx) starten und den Einstieg danach auf einen externen Nginx-Container umstellen. + +## Wann dieses Setup sinnvoll ist + +- Du möchtest NocoBase und den Webserver getrennt betreiben +- Du möchtest die Nginx-Konfiguration und die freigegebenen Ports selbst verwalten +- Du möchtest nur den Proxy-Container öffentlich erreichbar machen + +## Beispiel für docker-compose.yml + +Wenn du das `full`-Image brauchst, ersetze `latest-no-nginx` durch `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Wichtige Punkte + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrahiert die Client-Assets und erzeugt die Proxy-Konfiguration +- `NOCOBASE_PROXY_PROVIDER=nginx` legt fest, dass eine Nginx-Konfiguration erzeugt wird +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` ermöglicht dem Nginx-Container den Zugriff auf den Dienst `app` über das Compose-Netzwerk +- `./storage` muss sowohl in `app` als auch in `nginx` gemountet werden, damit Proxy-Konfiguration, statische Dateien und Uploads gemeinsam genutzt werden können +- Der `nginx`-Container sollte warten, bis `nocobase.conf` erzeugt wurde, und die Datei dann mit `ln -sf` nach `/etc/nginx/conf.d/default.conf` verlinken +- Wenn du das Image mit integriertem Nginx verwendest, gibt der `app`-Container den Port selbst mit `ports: "13000:80"` nach außen frei +- Wenn du einen externen Nginx-Container verwendest, sollte der `nginx`-Container die Portzuordnung zum Host übernehmen, und der Dienst `app` muss keinen Port zum Host veröffentlichen + +## Wenn du ein lokales Nginx auf dem Host verwendest + +Wenn dein Nginx direkt auf dem Host installiert ist und nicht in einem Docker-Container läuft, solltest du besser ein separates `docker-compose.yml` verwenden. Dabei muss der Dienst `app` einen Port zum Host veröffentlichen, und die Proxy-Variablen müssen aus Host-Sicht gesetzt werden. + +Du kannst ein `docker-compose.yml` wie dieses verwenden: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +In dieser Variante: + +- `NOCOBASE_PROXY_STORAGE_PATH` sollte der absolute Host-Pfad des `storage`-Verzeichnisses sein +- `NOCOBASE_PROXY_UPSTREAM_HOST` sollte `127.0.0.1` sein +- Der Dienst `app` muss `ports` behalten, damit das lokale Nginx die Anwendung über `127.0.0.1:13000` erreichen kann + +Nachdem der `app`-Container gestartet wurde, warte auf die Generierung der Konfigurationsdatei und verlinke sie dann in das lokale Nginx-Konfigurationsverzeichnis: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +Wenn dein Host-Nginx kein `conf.d`-Verzeichnis verwendet, ersetze das Link-Ziel durch deinen eigenen Konfigurationspfad. In der Regel ist es sicherer, `nocobase.conf` als Datei zu behalten, die aus dem `http {}`-Kontext eingebunden wird, statt ihren Inhalt manuell zu kopieren. + +## Verwandte Links + +- [Docker-Installation (integriertes Nginx)](./docker.mdx) — Starte mit dem Single-Container-Setup +- [Statischer Ressourcen-Proxy mit Nginx](../deployment/static-resource-proxy/nginx.md) — Mehr zur generierten Nginx-Konfiguration diff --git a/docs/docs/en/api/cli/config/delete.md b/docs/docs/en/api/cli/config/delete.md index a4c6f6fc302..d6d67d9cff3 100644 --- a/docs/docs/en/api/cli/config/delete.md +++ b/docs/docs/en/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "nb config delete command reference: delete an explicitly set CLI configuration item." -keywords: "nb config delete,NocoBase CLI,delete configuration" +title: 'nb config delete' +description: 'nb config delete command reference: delete an explicitly set CLI configuration item.' +keywords: 'nb config delete,NocoBase CLI,delete configuration' --- # nb config delete @@ -16,9 +16,9 @@ nb config delete ## Parameters -| Parameter | Type | Description | -| --- | --- | --- | -| `` | string | Configuration item name. See [`nb config`](./index.md) for supported values | +| Parameter | Type | Description | +| --------- | ------ | --------------------------------------------------------------------------- | +| `` | string | Configuration item name. See [`nb config`](./index.md) for supported values | ## Examples @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete proxy.nginx-driver diff --git a/docs/docs/en/api/cli/config/get.md b/docs/docs/en/api/cli/config/get.md index 729631d3cec..3f01cbd0bc3 100644 --- a/docs/docs/en/api/cli/config/get.md +++ b/docs/docs/en/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "nb config get command reference: read the effective value of a CLI configuration item." -keywords: "nb config get,NocoBase CLI,read configuration" +title: 'nb config get' +description: 'nb config get command reference: read the effective value of a CLI configuration item.' +keywords: 'nb config get,NocoBase CLI,read configuration' --- # nb config get @@ -16,9 +16,9 @@ nb config get ## Parameters -| Parameter | Type | Description | -| --- | --- | --- | -| `` | string | Configuration item name. See [`nb config`](./index.md) for supported values | +| Parameter | Type | Description | +| --------- | ------ | --------------------------------------------------------------------------- | +| `` | string | Configuration item name. See [`nb config`](./index.md) for supported values | ## Examples @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get proxy.nginx-driver diff --git a/docs/docs/en/api/cli/config/index.md b/docs/docs/en/api/cli/config/index.md index a2f86efb0bf..1845c66106b 100644 --- a/docs/docs/en/api/cli/config/index.md +++ b/docs/docs/en/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "nb config command reference: manage default configuration items for the NocoBase CLI." -keywords: "nb config,NocoBase CLI,configuration,default configuration" +title: 'nb config' +description: 'nb config command reference: manage default configuration items for the NocoBase CLI.' +keywords: 'nb config,NocoBase CLI,configuration,default configuration' --- # nb config @@ -10,6 +10,7 @@ Manage default CLI configuration values. The currently supported keys are mainly - CLI itself: `locale`, `update.policy`, `license.pkg-url` - Docker runtime: `docker.network`, `docker.container-prefix` +- Official NocoBase images: `nb-image-registry`, `nb-image-variant` - External executables: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - Proxy generation: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ Most projects only need a few of these keys. In practice, the most common ones a - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` or `bin.caddy` - `proxy.nginx-driver` or `proxy.caddy-driver` ## Common configuration keys -| Key | Default | Description | -| --- | --- | --- | -| `locale` | resolved by the current CLI rules | Override the language used by the CLI | -| `update.policy` | `prompt` | Startup update policy: `prompt`, `auto`, or `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | Override the download URL for commercial extension packages | -| `docker.network` | `nocobase` | Default network for CLI-managed Docker apps | -| `docker.container-prefix` | `nb` | Default prefix for CLI-managed Docker containers | -| `bin.docker` | `docker` | Override the Docker executable path | -| `bin.caddy` | `caddy` | Override the Caddy executable path | -| `bin.git` | `git` | Override the Git executable path | -| `bin.nginx` | `nginx` | Override the Nginx executable path | -| `bin.pnpm` | `pnpm` | Override the pnpm executable path | -| `bin.yarn` | `yarn` | Override the Yarn executable path | -| `proxy.nb-cli-root` | CLI root, usually the current user's home directory | Override the root path visible to the generated proxy config when the proxy process and CLI do not see the same filesystem root | -| `proxy.upstream-host` | `127.0.0.1` | Override the host used when the proxy forwards traffic back to the NocoBase app | -| `proxy.nginx-driver` | `local` | Default runtime driver used by `nb proxy nginx` | -| `proxy.caddy-driver` | `local` | Default runtime driver used by `nb proxy caddy` | +| Key | Default | Description | +| ------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `locale` | resolved by the current CLI rules | Override the language used by the CLI | +| `update.policy` | `prompt` | Startup update policy: `prompt`, `auto`, or `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | Override the download URL for commercial extension packages | +| `docker.network` | `nocobase` | Default network for CLI-managed Docker apps | +| `docker.container-prefix` | `nb` | Default prefix for CLI-managed Docker containers | +| `nb-image-registry` | `dockerhub` | Default registry family for official NocoBase images: `dockerhub` or `aliyun` | +| `nb-image-variant` | `full` | Default tag variant for official NocoBase app images: `standard`, `no-nginx`, `full`, or `full-no-nginx` | +| `bin.docker` | `docker` | Override the Docker executable path | +| `bin.caddy` | `caddy` | Override the Caddy executable path | +| `bin.git` | `git` | Override the Git executable path | +| `bin.nginx` | `nginx` | Override the Nginx executable path | +| `bin.pnpm` | `pnpm` | Override the pnpm executable path | +| `bin.yarn` | `yarn` | Override the Yarn executable path | +| `proxy.nb-cli-root` | CLI root, usually the current user's home directory | Override the root path visible to the generated proxy config when the proxy process and CLI do not see the same filesystem root | +| `proxy.upstream-host` | `127.0.0.1` | Override the host used when the proxy forwards traffic back to the NocoBase app | +| `proxy.nginx-driver` | `local` | Default runtime driver used by `nb proxy nginx` | +| `proxy.caddy-driver` | `local` | Default runtime driver used by `nb proxy caddy` | ## Usage @@ -49,12 +54,12 @@ nb config ## Subcommands -| Command | Description | -| --- | --- | -| [`nb config get`](./get.md) | Read the effective value of a configuration key | -| [`nb config set`](./set.md) | Set a configuration key | -| [`nb config delete`](./delete.md) | Delete an explicitly set configuration key | -| [`nb config list`](./list.md) | List the configuration keys that are currently set explicitly | +| Command | Description | +| --------------------------------- | ------------------------------------------------------------- | +| [`nb config get`](./get.md) | Read the effective value of a configuration key | +| [`nb config set`](./set.md) | Set a configuration key | +| [`nb config delete`](./delete.md) | Delete an explicitly set configuration key | +| [`nb config list`](./list.md) | List the configuration keys that are currently set explicitly | ## Examples @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` and `bin.caddy` only affect the `local` driver for `nb proxy nginx` and `nb proxy caddy` - `bin.pnpm` is used when commands need to run pnpm directly, such as updating a pnpm-managed global CLI install with `nb self update` +- `nb-image-registry` only affects official NocoBase image defaults used by the CLI. `dockerhub` maps app images to `nocobase/nocobase`, while `aliyun` maps them to `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` only affects official NocoBase app image tags. With version tag `1.7.14`, the CLI resolves `standard` to `1.7.14`, `no-nginx` to `1.7.14-no-nginx`, `full` to `1.7.14-full`, and `full-no-nginx` to `1.7.14-full-no-nginx` +- When `nb-image-registry=aliyun`, the CLI also switches the default built-in database images to the official Aliyun mirrors for PostgreSQL, MySQL, MariaDB, and Kingbase - `proxy.nginx-driver` and `proxy.caddy-driver` store the default driver used by each provider - `proxy.nb-cli-root` and `proxy.upstream-host` are advanced proxy overrides. Most CLI-managed `local` or `docker` envs can use the defaults directly - If you only want to switch the active proxy driver, using `nb proxy nginx use` or `nb proxy caddy use` is usually clearer than setting the config key manually diff --git a/docs/docs/en/api/cli/config/set.md b/docs/docs/en/api/cli/config/set.md index d3cbe334bb5..267093eb130 100644 --- a/docs/docs/en/api/cli/config/set.md +++ b/docs/docs/en/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "nb config set command reference: set a CLI configuration item." -keywords: "nb config set,NocoBase CLI,set configuration" +title: 'nb config set' +description: 'nb config set command reference: set a CLI configuration item.' +keywords: 'nb config set,NocoBase CLI,set configuration' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## Parameters -| Parameter | Type | Description | -| --- | --- | --- | -| `` | string | Configuration item name. See [`nb config`](./index.md) for supported values | -| `` | string | Configuration value, cannot be empty | +| Parameter | Type | Description | +| --------- | ------ | --------------------------------------------------------------------------- | +| `` | string | Configuration item name. See [`nb config`](./index.md) for supported values | +| `` | string | Configuration value, cannot be empty | ## Examples @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -43,7 +47,9 @@ nb config set bin.yarn yarn ## Notes -`update.policy` supports `prompt`, `auto`, and `off`, and the default value is `prompt`. +- `update.policy` supports `prompt`, `auto`, and `off`, and the default value is `prompt` +- `nb-image-registry` supports `dockerhub` and `aliyun`, and the default value is `dockerhub` +- `nb-image-variant` supports `standard`, `no-nginx`, `full`, and `full-no-nginx`, and the default value is `full` ## Related commands diff --git a/docs/docs/en/get-started/_meta.json b/docs/docs/en/get-started/_meta.json index c85bc5b98d9..0e5afe2a48e 100644 --- a/docs/docs/en/get-started/_meta.json +++ b/docs/docs/en/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Docker Installation", + "label": "Docker Installation (Built-in Nginx)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Docker Installation (External Nginx)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Docker Installation (External Caddy)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "create-nocobase-app Installation", diff --git a/docs/docs/en/get-started/installation/docker-caddy.mdx b/docs/docs/en/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..73af166c28e --- /dev/null +++ b/docs/docs/en/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Docker Installation (External Caddy)" +description: "Install NocoBase with Docker and use an external Caddy container as the entry point." +keywords: "Docker,NocoBase,Caddy,installation,reverse proxy" +--- + +# Docker Installation (External Caddy) + +In this setup, the NocoBase app container and the Caddy container run separately. You can start with [Docker Installation (Built-in Nginx)](./docker.mdx) and then switch the entry service to an external Caddy container. + +## When to use this setup + +- You want to deploy NocoBase and the web server separately +- You want to simplify reverse proxy and HTTPS configuration with Caddy +- You want to expose only the proxy container to the public network + +## docker-compose.yml example + +If you need the `full` image, replace `latest-no-nginx` with `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Key points + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extracts client assets and generates proxy config +- `NOCOBASE_PROXY_PROVIDER=caddy` tells the app to generate Caddy config +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` lets the Caddy container reach the `app` service through the Compose network +- `./storage` must be mounted into both the `app` and `caddy` containers so they can share proxy config, static assets, and uploaded files +- The `caddy` container should wait until `nocobase.caddy` is generated, then link it to `/etc/caddy/Caddyfile` with `ln -sf` +- Expose only the Caddy container port to the host. The `app` service does not need to expose its port to the host + +## If you use a local host Caddy + +If your Caddy is installed directly on the host instead of running in a Docker container, it is better to use a separate `docker-compose.yml`. In this setup, the `app` service must expose a host port directly, and the proxy-related environment variables should use host-side values. + +You can use a `docker-compose.yml` like this: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +In this variant: + +- `NOCOBASE_PROXY_STORAGE_PATH` should be the absolute host path of your `storage` directory +- `NOCOBASE_PROXY_UPSTREAM_HOST` should be `127.0.0.1` +- The `app` service must keep `ports`, so the local Caddy can reach the app through `127.0.0.1:13000` + +After the `app` container starts, wait for the config file to be generated, then link it into the local Caddy config path: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +If your host Caddy does not use `/etc/caddy/Caddyfile`, replace the link target with your own config path. Usually it is safer to keep `nocobase.caddy` as the main entry file instead of copying its content manually. + +## Related links + +- [Docker Installation (Built-in Nginx)](./docker.mdx) — Start with the single-container setup +- [Caddy Static Resource Proxy](../deployment/static-resource-proxy/caddy.md) — Learn more about the generated Caddy config diff --git a/docs/docs/en/get-started/installation/docker-nginx.mdx b/docs/docs/en/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..e62f6ae6536 --- /dev/null +++ b/docs/docs/en/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Docker Installation (External Nginx)" +description: "Install NocoBase with Docker and use an external Nginx container as the entry point." +keywords: "Docker,NocoBase,Nginx,installation,reverse proxy" +--- + +# Docker Installation (External Nginx) + +In this setup, the NocoBase app container and the Nginx container run separately. You can start with [Docker Installation (Built-in Nginx)](./docker.mdx) and then switch the entry service to an external Nginx container. + +## When to use this setup + +- You want to deploy NocoBase and the web server separately +- You want to manage the Nginx config and exposed ports yourself +- You want to expose only the proxy container to the public network + +## docker-compose.yml example + +If you need the `full` image, replace `latest-no-nginx` with `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Key points + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extracts client assets and generates proxy config +- `NOCOBASE_PROXY_PROVIDER=nginx` tells the app to generate Nginx config +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` lets the Nginx container reach the `app` service through the Compose network +- `./storage` must be mounted into both the `app` and `nginx` containers so they can share proxy config, static assets, and uploaded files +- The `nginx` container should wait until `nocobase.conf` is generated, then link it to `/etc/nginx/conf.d/default.conf` with `ln -sf` +- If you use the built-in Nginx image, the `app` container itself exposes the port with `ports: "13000:80"` +- If you use an external Nginx container, let the `nginx` container handle the host port mapping, and do not expose the `app` service port to the host + +## If you use a local host Nginx + +If your Nginx is installed directly on the host instead of running in a Docker container, it is better to use a separate `docker-compose.yml`. In this setup, the `app` service must expose a host port directly, and the proxy-related environment variables should use host-side values. + +You can use a `docker-compose.yml` like this: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +In this variant: + +- `NOCOBASE_PROXY_STORAGE_PATH` should be the absolute host path of your `storage` directory +- `NOCOBASE_PROXY_UPSTREAM_HOST` should be `127.0.0.1` +- The `app` service must keep `ports`, so the local Nginx can reach the app through `127.0.0.1:13000` + +After the `app` container starts, wait for the config file to be generated, then link it into the local Nginx config directory: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +If your host Nginx does not use the `conf.d` directory, replace the link target with your own config path. Usually it is safer to keep `nocobase.conf` as a file included from the `http {}` context instead of copying its content manually. + +## Related links + +- [Docker Installation (Built-in Nginx)](./docker.mdx) — Start with the single-container setup +- [Nginx Static Resource Proxy](../deployment/static-resource-proxy/nginx.md) — Learn more about the generated Nginx config diff --git a/docs/docs/es/api/cli/config/delete.md b/docs/docs/es/api/cli/config/delete.md index a61be5e1e7a..bbf2272bf9f 100644 --- a/docs/docs/es/api/cli/config/delete.md +++ b/docs/docs/es/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "Referencia del comando nb config delete: eliminar un elemento de configuración de la CLI establecido explícitamente." -keywords: "nb config delete,NocoBase CLI,eliminar configuración" +title: 'nb config delete' +description: 'Referencia del comando nb config delete: eliminar un elemento de configuración de la CLI establecido explícitamente.' +keywords: 'nb config delete,NocoBase CLI,eliminar configuración' --- # nb config delete @@ -16,9 +16,9 @@ nb config delete ## Parámetros -| Parámetro | Tipo | Descripción | -| --- | --- | --- | -| `` | string | Nombre del elemento de configuración. Consulta [`nb config`](./index.md) para ver los valores admitidos | +| Parámetro | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------------------------------------------- | +| `` | string | Nombre del elemento de configuración. Consulta [`nb config`](./index.md) para ver los valores admitidos | ## Ejemplos @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/es/api/cli/config/get.md b/docs/docs/es/api/cli/config/get.md index 120c3006ae5..59cb460d58f 100644 --- a/docs/docs/es/api/cli/config/get.md +++ b/docs/docs/es/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "Referencia del comando nb config get: leer el valor efectivo de un elemento de configuración de la CLI." -keywords: "nb config get,NocoBase CLI,leer configuración" +title: 'nb config get' +description: 'Referencia del comando nb config get: leer el valor efectivo de un elemento de configuración de la CLI.' +keywords: 'nb config get,NocoBase CLI,leer configuración' --- # nb config get @@ -16,9 +16,9 @@ nb config get ## Parámetros -| Parámetro | Tipo | Descripción | -| --- | --- | --- | -| `` | string | Nombre del elemento de configuración. Consulta [`nb config`](./index.md) para ver los valores admitidos | +| Parámetro | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------------------------------------------- | +| `` | string | Nombre del elemento de configuración. Consulta [`nb config`](./index.md) para ver los valores admitidos | ## Ejemplos @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/es/api/cli/config/index.md b/docs/docs/es/api/cli/config/index.md index 953c020b430..dda8e606561 100644 --- a/docs/docs/es/api/cli/config/index.md +++ b/docs/docs/es/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "Referencia de nb config: gestionar los valores de configuración predeterminados de NocoBase CLI." -keywords: "nb config,NocoBase CLI,configuración,configuración predeterminada" +title: 'nb config' +description: 'Referencia de nb config: gestionar los valores de configuración predeterminados de NocoBase CLI.' +keywords: 'nb config,NocoBase CLI,configuración,configuración predeterminada' --- # nb config @@ -10,6 +10,7 @@ Gestiona los valores de configuración predeterminados de la CLI. Las claves com - La propia CLI: `locale`, `update.policy`, `license.pkg-url` - Runtime de Docker: `docker.network`, `docker.container-prefix` +- Imágenes oficiales de NocoBase: `nb-image-registry`, `nb-image-variant` - Ejecutables externos: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - Generación de proxy: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ La mayoría de los proyectos solo necesitan unas pocas de estas claves. En la pr - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` o `bin.caddy` - `proxy.nginx-driver` o `proxy.caddy-driver` ## Claves de configuración comunes -| Clave | Valor predeterminado | Descripción | -| --- | --- | --- | -| `locale` | se resuelve según las reglas actuales de la CLI | Sobrescribe el idioma usado por la CLI | -| `update.policy` | `prompt` | Política de actualización al iniciar: `prompt`, `auto` u `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | Sobrescribe la URL de descarga de paquetes de extensiones comerciales | -| `docker.network` | `nocobase` | Red predeterminada para aplicaciones Docker gestionadas por la CLI | -| `docker.container-prefix` | `nb` | Prefijo predeterminado para contenedores Docker gestionados por la CLI | -| `bin.docker` | `docker` | Sobrescribe la ruta del ejecutable de Docker | -| `bin.caddy` | `caddy` | Sobrescribe la ruta del ejecutable de Caddy | -| `bin.git` | `git` | Sobrescribe la ruta del ejecutable de Git | -| `bin.nginx` | `nginx` | Sobrescribe la ruta del ejecutable de Nginx | -| `bin.pnpm` | `pnpm` | Sobrescribe la ruta del ejecutable de pnpm | -| `bin.yarn` | `yarn` | Sobrescribe la ruta del ejecutable de Yarn | -| `proxy.nb-cli-root` | raíz de la CLI, normalmente el directorio home del usuario actual | Sobrescribe la ruta raíz visible para la configuración de proxy generada cuando el proceso del proxy y la CLI no ven la misma raíz del sistema de archivos | -| `proxy.upstream-host` | `127.0.0.1` | Sobrescribe el host usado por el proxy para reenviar tráfico a la aplicación NocoBase | -| `proxy.nginx-driver` | `local` | Driver de runtime predeterminado usado por `nb proxy nginx` | -| `proxy.caddy-driver` | `local` | Driver de runtime predeterminado usado por `nb proxy caddy` | +| Clave | Valor predeterminado | Descripción | +| ------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `locale` | se resuelve según las reglas actuales de la CLI | Sobrescribe el idioma usado por la CLI | +| `update.policy` | `prompt` | Política de actualización al iniciar: `prompt`, `auto` u `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | Sobrescribe la URL de descarga de paquetes de extensiones comerciales | +| `docker.network` | `nocobase` | Red predeterminada para aplicaciones Docker gestionadas por la CLI | +| `docker.container-prefix` | `nb` | Prefijo predeterminado para contenedores Docker gestionados por la CLI | +| `nb-image-registry` | `dockerhub` | Familia de registry predeterminada para imágenes oficiales de NocoBase: `dockerhub` o `aliyun` | +| `nb-image-variant` | `full` | Variante de tag predeterminada para imágenes oficiales de app de NocoBase: `standard`, `no-nginx`, `full` o `full-no-nginx` | +| `bin.docker` | `docker` | Sobrescribe la ruta del ejecutable de Docker | +| `bin.caddy` | `caddy` | Sobrescribe la ruta del ejecutable de Caddy | +| `bin.git` | `git` | Sobrescribe la ruta del ejecutable de Git | +| `bin.nginx` | `nginx` | Sobrescribe la ruta del ejecutable de Nginx | +| `bin.pnpm` | `pnpm` | Sobrescribe la ruta del ejecutable de pnpm | +| `bin.yarn` | `yarn` | Sobrescribe la ruta del ejecutable de Yarn | +| `proxy.nb-cli-root` | raíz de la CLI, normalmente el directorio home del usuario actual | Sobrescribe la ruta raíz visible para la configuración de proxy generada cuando el proceso del proxy y la CLI no ven la misma raíz del sistema de archivos | +| `proxy.upstream-host` | `127.0.0.1` | Sobrescribe el host usado por el proxy para reenviar tráfico a la aplicación NocoBase | +| `proxy.nginx-driver` | `local` | Driver de runtime predeterminado usado por `nb proxy nginx` | +| `proxy.caddy-driver` | `local` | Driver de runtime predeterminado usado por `nb proxy caddy` | ## Uso @@ -49,12 +54,12 @@ nb config ## Subcomandos -| Comando | Descripción | -| --- | --- | -| [`nb config get`](./get.md) | Leer el valor efectivo de una clave de configuración | -| [`nb config set`](./set.md) | Establecer una clave de configuración | -| [`nb config delete`](./delete.md) | Eliminar una clave de configuración definida explícitamente | -| [`nb config list`](./list.md) | Listar las claves de configuración definidas explícitamente en este momento | +| Comando | Descripción | +| --------------------------------- | --------------------------------------------------------------------------- | +| [`nb config get`](./get.md) | Leer el valor efectivo de una clave de configuración | +| [`nb config set`](./set.md) | Establecer una clave de configuración | +| [`nb config delete`](./delete.md) | Eliminar una clave de configuración definida explícitamente | +| [`nb config list`](./list.md) | Listar las claves de configuración definidas explícitamente en este momento | ## Ejemplos @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` y `bin.caddy` solo afectan al driver `local` de `nb proxy nginx` y `nb proxy caddy` - `bin.pnpm` se usa cuando los comandos necesitan ejecutar pnpm directamente, como al actualizar una instalación global de la CLI gestionada por pnpm con `nb self update` +- `nb-image-registry` solo afecta a los valores predeterminados de imágenes oficiales de NocoBase que usa la CLI. `dockerhub` usa la imagen de app `nocobase/nocobase`, mientras que `aliyun` usa `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` solo afecta a los tags de las imágenes oficiales de app de NocoBase. Con la versión `1.7.14`, la CLI resuelve `standard` como `1.7.14`, `no-nginx` como `1.7.14-no-nginx`, `full` como `1.7.14-full` y `full-no-nginx` como `1.7.14-full-no-nginx` +- Cuando `nb-image-registry=aliyun`, la CLI también cambia las imágenes predeterminadas de base de datos integrada a los mirrors oficiales de Aliyun para PostgreSQL, MySQL, MariaDB y Kingbase - `proxy.nginx-driver` y `proxy.caddy-driver` almacenan el driver predeterminado usado por cada proveedor - `proxy.nb-cli-root` y `proxy.upstream-host` son overrides avanzados del proxy. La mayoría de los entornos `local` o `docker` gestionados por la CLI pueden usar directamente los valores predeterminados - Si solo quieres cambiar el driver activo del proxy, normalmente es más claro usar `nb proxy nginx use` o `nb proxy caddy use` que establecer la clave manualmente diff --git a/docs/docs/es/api/cli/config/set.md b/docs/docs/es/api/cli/config/set.md index 1a73b355434..a87ac30a038 100644 --- a/docs/docs/es/api/cli/config/set.md +++ b/docs/docs/es/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "Referencia del comando nb config set: establecer un elemento de configuración de la CLI." -keywords: "nb config set,NocoBase CLI,establecer configuración" +title: 'nb config set' +description: 'Referencia del comando nb config set: establecer un elemento de configuración de la CLI.' +keywords: 'nb config set,NocoBase CLI,establecer configuración' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## Parámetros -| Parámetro | Tipo | Descripción | -| --- | --- | --- | -| `` | string | Nombre del elemento de configuración. Consulta [`nb config`](./index.md) para ver los valores admitidos | -| `` | string | Valor de configuración; no puede estar vacío | +| Parámetro | Tipo | Descripción | +| --------- | ------ | ------------------------------------------------------------------------------------------------------- | +| `` | string | Nombre del elemento de configuración. Consulta [`nb config`](./index.md) para ver los valores admitidos | +| `` | string | Valor de configuración; no puede estar vacío | ## Ejemplos @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## Notas -`update.policy` admite `prompt`, `auto` y `off`, y el valor predeterminado es `prompt`. +- `update.policy` admite `prompt`, `auto` y `off`, y el valor predeterminado es `prompt` +- `nb-image-registry` admite `dockerhub` y `aliyun`, y el valor predeterminado es `dockerhub` +- `nb-image-variant` admite `standard`, `no-nginx`, `full` y `full-no-nginx`, y el valor predeterminado es `full` ## Comandos relacionados diff --git a/docs/docs/es/get-started/_meta.json b/docs/docs/es/get-started/_meta.json index 12e749661c2..26f9edffcc0 100644 --- a/docs/docs/es/get-started/_meta.json +++ b/docs/docs/es/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Instalación con Docker", + "label": "Instalación con Docker (Nginx integrado)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Instalación con Docker (Nginx externo)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Instalación con Docker (Caddy externo)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "Instalación con create-nocobase-app", diff --git a/docs/docs/es/get-started/installation/docker-caddy.mdx b/docs/docs/es/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..91c6313ffab --- /dev/null +++ b/docs/docs/es/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Instalación con Docker (Caddy externo)" +description: "Instala NocoBase con Docker y usa un contenedor externo de Caddy como punto de entrada." +keywords: "Docker,NocoBase,Caddy,instalación,proxy inverso" +--- + +# Instalación con Docker (Caddy externo) + +En esta modalidad, el contenedor de la aplicación NocoBase y el contenedor de Caddy se ejecutan por separado. Puedes empezar con [Instalación con Docker (Nginx integrado)](./docker.mdx) y luego cambiar la entrada a un contenedor externo de Caddy. + +## Cuándo usar esta modalidad + +- Quieres desplegar NocoBase y el servidor web por separado +- Quieres simplificar la configuración del proxy inverso y HTTPS con Caddy +- Quieres exponer a la red pública solo el contenedor proxy + +## Ejemplo de docker-compose.yml + +Si necesitas la imagen `full`, sustituye `latest-no-nginx` por `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Puntos clave + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrae los recursos del cliente y genera la configuración del proxy +- `NOCOBASE_PROXY_PROVIDER=caddy` indica que debe generarse la configuración de Caddy +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` permite que el contenedor de Caddy acceda al servicio `app` mediante la red de Compose +- `./storage` debe montarse tanto en `app` como en `caddy` para compartir la configuración del proxy, los recursos estáticos y los archivos subidos +- El contenedor `caddy` debe esperar a que se genere `nocobase.caddy` y luego enlazarlo a `/etc/caddy/Caddyfile` con `ln -sf` +- Expón al host solo el puerto del contenedor de Caddy. El servicio `app` no necesita exponer su puerto al host + +## Si usas Caddy local en el host + +Si tu Caddy está instalado directamente en el host y no se ejecuta dentro de un contenedor Docker, es mejor usar un `docker-compose.yml` independiente. En este caso, el servicio `app` debe exponer un puerto al host y las variables del proxy deben configurarse desde la perspectiva del host. + +Puedes usar un `docker-compose.yml` como este: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +En esta variante: + +- `NOCOBASE_PROXY_STORAGE_PATH` debe ser la ruta absoluta del directorio `storage` en el host +- `NOCOBASE_PROXY_UPSTREAM_HOST` debe ser `127.0.0.1` +- El servicio `app` debe conservar `ports`, para que el Caddy local pueda acceder a la aplicación mediante `127.0.0.1:13000` + +Después de iniciar el contenedor `app`, espera a que se genere el archivo de configuración y luego enlázalo a la ruta de configuración local de Caddy: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +Si tu Caddy local no usa `/etc/caddy/Caddyfile`, sustituye la ruta del enlace por tu propia ruta de configuración. En la mayoría de los casos es más seguro mantener `nocobase.caddy` como archivo de entrada principal en lugar de copiar su contenido manualmente. + +## Enlaces relacionados + +- [Instalación con Docker (Nginx integrado)](./docker.mdx) — Empieza con el despliegue de un solo contenedor +- [Proxy de recursos estáticos con Caddy](../deployment/static-resource-proxy/caddy.md) — Más detalles sobre la configuración generada de Caddy diff --git a/docs/docs/es/get-started/installation/docker-nginx.mdx b/docs/docs/es/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..43208edccc6 --- /dev/null +++ b/docs/docs/es/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Instalación con Docker (Nginx externo)" +description: "Instala NocoBase con Docker y usa un contenedor externo de Nginx como punto de entrada." +keywords: "Docker,NocoBase,Nginx,instalación,proxy inverso" +--- + +# Instalación con Docker (Nginx externo) + +En esta modalidad, el contenedor de la aplicación NocoBase y el contenedor de Nginx se ejecutan por separado. Puedes empezar con [Instalación con Docker (Nginx integrado)](./docker.mdx) y luego cambiar la entrada a un contenedor externo de Nginx. + +## Cuándo usar esta modalidad + +- Quieres desplegar NocoBase y el servidor web por separado +- Quieres gestionar tú mismo la configuración de Nginx y los puertos expuestos +- Quieres exponer a la red pública solo el contenedor proxy + +## Ejemplo de docker-compose.yml + +Si necesitas la imagen `full`, sustituye `latest-no-nginx` por `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Puntos clave + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrae los recursos del cliente y genera la configuración del proxy +- `NOCOBASE_PROXY_PROVIDER=nginx` indica que debe generarse la configuración de Nginx +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` permite que el contenedor de Nginx acceda al servicio `app` mediante la red de Compose +- `./storage` debe montarse tanto en `app` como en `nginx` para compartir la configuración del proxy, los recursos estáticos y los archivos subidos +- El contenedor `nginx` debe esperar a que se genere `nocobase.conf` y luego enlazarlo a `/etc/nginx/conf.d/default.conf` con `ln -sf` +- Si usas la imagen con Nginx integrado, el propio contenedor `app` expone el puerto con `ports: "13000:80"` +- Si usas un contenedor Nginx externo, deja que el contenedor `nginx` gestione el mapeo del puerto al host y no expongas el puerto del servicio `app` al host + +## Si usas Nginx local en el host + +Si tu Nginx está instalado directamente en el host y no se ejecuta dentro de un contenedor Docker, es mejor usar un `docker-compose.yml` independiente. En este caso, el servicio `app` debe exponer un puerto al host y las variables del proxy deben configurarse desde la perspectiva del host. + +Puedes usar un `docker-compose.yml` como este: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +En esta variante: + +- `NOCOBASE_PROXY_STORAGE_PATH` debe ser la ruta absoluta del directorio `storage` en el host +- `NOCOBASE_PROXY_UPSTREAM_HOST` debe ser `127.0.0.1` +- El servicio `app` debe conservar `ports`, para que el Nginx local pueda acceder a la aplicación mediante `127.0.0.1:13000` + +Después de iniciar el contenedor `app`, espera a que se genere el archivo de configuración y luego enlázalo al directorio de configuración local de Nginx: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +Si tu Nginx local no usa el directorio `conf.d`, sustituye la ruta del enlace por tu propia ruta de configuración. En la mayoría de los casos es más seguro mantener `nocobase.conf` como un archivo incluido desde el contexto `http {}` en lugar de copiar su contenido manualmente. + +## Enlaces relacionados + +- [Instalación con Docker (Nginx integrado)](./docker.mdx) — Empieza con el despliegue de un solo contenedor +- [Proxy de recursos estáticos con Nginx](../deployment/static-resource-proxy/nginx.md) — Más detalles sobre la configuración generada de Nginx diff --git a/docs/docs/fr/api/cli/config/delete.md b/docs/docs/fr/api/cli/config/delete.md index 51395d53e60..186ad770222 100644 --- a/docs/docs/fr/api/cli/config/delete.md +++ b/docs/docs/fr/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "Référence de la commande nb config delete : supprimer un élément de configuration CLI défini explicitement." -keywords: "nb config delete,NocoBase CLI,supprimer la configuration" +title: 'nb config delete' +description: 'Référence de la commande nb config delete : supprimer un élément de configuration CLI défini explicitement.' +keywords: 'nb config delete,NocoBase CLI,supprimer la configuration' --- # nb config delete @@ -16,9 +16,9 @@ nb config delete ## Paramètres -| Paramètre | Type | Description | -| --- | --- | --- | -| `` | string | Nom de l’élément de configuration. Voir [`nb config`](./index.md) pour les valeurs prises en charge | +| Paramètre | Type | Description | +| --------- | ------ | --------------------------------------------------------------------------------------------------- | +| `` | string | Nom de l’élément de configuration. Voir [`nb config`](./index.md) pour les valeurs prises en charge | ## Exemples @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/fr/api/cli/config/get.md b/docs/docs/fr/api/cli/config/get.md index bae95472365..30d3055f434 100644 --- a/docs/docs/fr/api/cli/config/get.md +++ b/docs/docs/fr/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "Référence de la commande nb config get : lire la valeur effective d’un élément de configuration de la CLI." -keywords: "nb config get,NocoBase CLI,lire la configuration" +title: 'nb config get' +description: 'Référence de la commande nb config get : lire la valeur effective d’un élément de configuration de la CLI.' +keywords: 'nb config get,NocoBase CLI,lire la configuration' --- # nb config get @@ -16,9 +16,9 @@ nb config get ## Paramètres -| Paramètre | Type | Description | -| --- | --- | --- | -| `` | string | Nom de l’élément de configuration. Voir [`nb config`](./index.md) pour les valeurs prises en charge | +| Paramètre | Type | Description | +| --------- | ------ | --------------------------------------------------------------------------------------------------- | +| `` | string | Nom de l’élément de configuration. Voir [`nb config`](./index.md) pour les valeurs prises en charge | ## Exemples @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/fr/api/cli/config/index.md b/docs/docs/fr/api/cli/config/index.md index 010cc5d6025..dad662e71ce 100644 --- a/docs/docs/fr/api/cli/config/index.md +++ b/docs/docs/fr/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "Référence de nb config : gérer les valeurs de configuration par défaut de la CLI NocoBase." -keywords: "nb config,NocoBase CLI,configuration,configuration par défaut" +title: 'nb config' +description: 'Référence de nb config : gérer les valeurs de configuration par défaut de la CLI NocoBase.' +keywords: 'nb config,NocoBase CLI,configuration,configuration par défaut' --- # nb config @@ -10,6 +10,7 @@ Gère les valeurs de configuration par défaut de la CLI. Les clés actuellement - La CLI elle-même : `locale`, `update.policy`, `license.pkg-url` - Runtime Docker : `docker.network`, `docker.container-prefix` +- Images officielles NocoBase : `nb-image-registry`, `nb-image-variant` - Exécutables externes : `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - Génération de proxy : `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ La plupart des projets n'ont besoin que de quelques-unes de ces clés. En pratiq - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` ou `bin.caddy` - `proxy.nginx-driver` ou `proxy.caddy-driver` ## Clés de configuration courantes -| Clé | Valeur par défaut | Description | -| --- | --- | --- | -| `locale` | résolue selon les règles actuelles de la CLI | Remplace la langue utilisée par la CLI | -| `update.policy` | `prompt` | Politique de mise à jour au démarrage : `prompt`, `auto` ou `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | Remplace l'URL de téléchargement des paquets d'extensions commerciales | -| `docker.network` | `nocobase` | Réseau par défaut pour les applications Docker gérées par la CLI | -| `docker.container-prefix` | `nb` | Préfixe par défaut pour les conteneurs Docker gérés par la CLI | -| `bin.docker` | `docker` | Remplace le chemin de l'exécutable Docker | -| `bin.caddy` | `caddy` | Remplace le chemin de l'exécutable Caddy | -| `bin.git` | `git` | Remplace le chemin de l'exécutable Git | -| `bin.nginx` | `nginx` | Remplace le chemin de l'exécutable Nginx | -| `bin.pnpm` | `pnpm` | Remplace le chemin de l'exécutable pnpm | -| `bin.yarn` | `yarn` | Remplace le chemin de l'exécutable Yarn | -| `proxy.nb-cli-root` | racine de la CLI, généralement le répertoire personnel de l'utilisateur courant | Remplace la racine visible par la configuration proxy générée lorsque le processus proxy et la CLI ne voient pas la même racine du système de fichiers | -| `proxy.upstream-host` | `127.0.0.1` | Remplace l'hôte utilisé par le proxy pour renvoyer le trafic vers l'application NocoBase | -| `proxy.nginx-driver` | `local` | Driver de runtime par défaut utilisé par `nb proxy nginx` | -| `proxy.caddy-driver` | `local` | Driver de runtime par défaut utilisé par `nb proxy caddy` | +| Clé | Valeur par défaut | Description | +| ------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `locale` | résolue selon les règles actuelles de la CLI | Remplace la langue utilisée par la CLI | +| `update.policy` | `prompt` | Politique de mise à jour au démarrage : `prompt`, `auto` ou `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | Remplace l'URL de téléchargement des paquets d'extensions commerciales | +| `docker.network` | `nocobase` | Réseau par défaut pour les applications Docker gérées par la CLI | +| `docker.container-prefix` | `nb` | Préfixe par défaut pour les conteneurs Docker gérés par la CLI | +| `nb-image-registry` | `dockerhub` | Famille de registry par défaut pour les images officielles NocoBase : `dockerhub` ou `aliyun` | +| `nb-image-variant` | `full` | Variante de tag par défaut pour les images d'app officielles NocoBase : `standard`, `no-nginx`, `full` ou `full-no-nginx` | +| `bin.docker` | `docker` | Remplace le chemin de l'exécutable Docker | +| `bin.caddy` | `caddy` | Remplace le chemin de l'exécutable Caddy | +| `bin.git` | `git` | Remplace le chemin de l'exécutable Git | +| `bin.nginx` | `nginx` | Remplace le chemin de l'exécutable Nginx | +| `bin.pnpm` | `pnpm` | Remplace le chemin de l'exécutable pnpm | +| `bin.yarn` | `yarn` | Remplace le chemin de l'exécutable Yarn | +| `proxy.nb-cli-root` | racine de la CLI, généralement le répertoire personnel de l'utilisateur courant | Remplace la racine visible par la configuration proxy générée lorsque le processus proxy et la CLI ne voient pas la même racine du système de fichiers | +| `proxy.upstream-host` | `127.0.0.1` | Remplace l'hôte utilisé par le proxy pour renvoyer le trafic vers l'application NocoBase | +| `proxy.nginx-driver` | `local` | Driver de runtime par défaut utilisé par `nb proxy nginx` | +| `proxy.caddy-driver` | `local` | Driver de runtime par défaut utilisé par `nb proxy caddy` | ## Utilisation @@ -49,12 +54,12 @@ nb config ## Sous-commandes -| Commande | Description | -| --- | --- | -| [`nb config get`](./get.md) | Lire la valeur effective d'une clé de configuration | -| [`nb config set`](./set.md) | Définir une clé de configuration | -| [`nb config delete`](./delete.md) | Supprimer une clé de configuration explicitement définie | -| [`nb config list`](./list.md) | Lister les clés de configuration explicitement définies actuellement | +| Commande | Description | +| --------------------------------- | -------------------------------------------------------------------- | +| [`nb config get`](./get.md) | Lire la valeur effective d'une clé de configuration | +| [`nb config set`](./set.md) | Définir une clé de configuration | +| [`nb config delete`](./delete.md) | Supprimer une clé de configuration explicitement définie | +| [`nb config list`](./list.md) | Lister les clés de configuration explicitement définies actuellement | ## Exemples @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` et `bin.caddy` n'affectent que le driver `local` de `nb proxy nginx` et `nb proxy caddy` - `bin.pnpm` est utilisé lorsque des commandes doivent exécuter pnpm directement, par exemple pour mettre à jour une installation globale de la CLI gérée par pnpm avec `nb self update` +- `nb-image-registry` n'affecte que les valeurs par défaut des images officielles NocoBase utilisées par la CLI. `dockerhub` utilise l'image d'app `nocobase/nocobase`, tandis que `aliyun` utilise `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` n'affecte que les tags des images d'app officielles NocoBase. Avec la version `1.7.14`, la CLI résout `standard` en `1.7.14`, `no-nginx` en `1.7.14-no-nginx`, `full` en `1.7.14-full` et `full-no-nginx` en `1.7.14-full-no-nginx` +- Lorsque `nb-image-registry=aliyun`, la CLI bascule aussi les images de base de données intégrée par défaut vers les mirrors officiels Aliyun pour PostgreSQL, MySQL, MariaDB et Kingbase - `proxy.nginx-driver` et `proxy.caddy-driver` stockent le driver par défaut utilisé par chaque provider - `proxy.nb-cli-root` et `proxy.upstream-host` sont des surcharges proxy avancées. Pour la plupart des environnements `local` ou `docker` gérés par la CLI, les valeurs par défaut suffisent - Si tu veux simplement changer le driver proxy actif, `nb proxy nginx use` ou `nb proxy caddy use` est généralement plus clair que de modifier la clé de configuration manuellement diff --git a/docs/docs/fr/api/cli/config/set.md b/docs/docs/fr/api/cli/config/set.md index d1afeb04a91..6fa630ee6e4 100644 --- a/docs/docs/fr/api/cli/config/set.md +++ b/docs/docs/fr/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "Référence de la commande nb config set : définir un élément de configuration de la CLI." -keywords: "nb config set,NocoBase CLI,définir la configuration" +title: 'nb config set' +description: 'Référence de la commande nb config set : définir un élément de configuration de la CLI.' +keywords: 'nb config set,NocoBase CLI,définir la configuration' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## Paramètres -| Paramètre | Type | Description | -| --- | --- | --- | -| `` | string | Nom de l’élément de configuration. Voir [`nb config`](./index.md) pour les valeurs prises en charge | -| `` | string | Valeur de configuration, ne peut pas être vide | +| Paramètre | Type | Description | +| --------- | ------ | --------------------------------------------------------------------------------------------------- | +| `` | string | Nom de l’élément de configuration. Voir [`nb config`](./index.md) pour les valeurs prises en charge | +| `` | string | Valeur de configuration, ne peut pas être vide | ## Exemples @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## Remarques -`update.policy` prend en charge `prompt`, `auto` et `off`, et la valeur par défaut est `prompt`. +- `update.policy` prend en charge `prompt`, `auto` et `off`, et la valeur par défaut est `prompt` +- `nb-image-registry` prend en charge `dockerhub` et `aliyun`, et la valeur par défaut est `dockerhub` +- `nb-image-variant` prend en charge `standard`, `no-nginx`, `full` et `full-no-nginx`, et la valeur par défaut est `full` ## Commandes associées diff --git a/docs/docs/fr/get-started/_meta.json b/docs/docs/fr/get-started/_meta.json index 895c6e5b22d..5dc3d0f8f7e 100644 --- a/docs/docs/fr/get-started/_meta.json +++ b/docs/docs/fr/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Installation avec Docker", + "label": "Installation Docker (Nginx intégré)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Installation Docker (Nginx externe)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Installation Docker (Caddy externe)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "Installation avec create-nocobase-app", diff --git a/docs/docs/fr/get-started/installation/docker-caddy.mdx b/docs/docs/fr/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..e95b44dceb5 --- /dev/null +++ b/docs/docs/fr/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Installation Docker (Caddy externe)" +description: "Installez NocoBase avec Docker et utilisez un conteneur Caddy externe comme point d'entrée." +keywords: "Docker,NocoBase,Caddy,installation,proxy inverse" +--- + +# Installation Docker (Caddy externe) + +Dans ce mode, le conteneur d'application NocoBase et le conteneur Caddy s'exécutent séparément. Vous pouvez commencer par [Installation Docker (Nginx intégré)](./docker.mdx), puis basculer l'entrée vers un conteneur Caddy externe. + +## Quand utiliser ce mode + +- Vous voulez déployer NocoBase et le serveur web séparément +- Vous voulez simplifier la configuration du proxy inverse et de HTTPS avec Caddy +- Vous voulez exposer au réseau public uniquement le conteneur proxy + +## Exemple de docker-compose.yml + +Si vous avez besoin de l'image `full`, remplacez `latest-no-nginx` par `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Points clés + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrait les ressources client et génère la configuration du proxy +- `NOCOBASE_PROXY_PROVIDER=caddy` indique que la configuration Caddy doit être générée +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` permet au conteneur Caddy d'accéder au service `app` via le réseau Compose +- `./storage` doit être monté dans `app` et `caddy` afin de partager la configuration du proxy, les ressources statiques et les fichiers téléversés +- Le conteneur `caddy` doit attendre que `nocobase.caddy` soit généré, puis créer un lien vers `/etc/caddy/Caddyfile` avec `ln -sf` +- Exposez uniquement le port du conteneur Caddy à l'hôte. Le service `app` n'a pas besoin d'exposer son port à l'hôte + +## Si vous utilisez un Caddy local sur l'hôte + +Si votre Caddy est installé directement sur l'hôte au lieu de s'exécuter dans un conteneur Docker, il est préférable d'utiliser un `docker-compose.yml` séparé. Dans ce mode, le service `app` doit exposer un port vers l'hôte, et les variables du proxy doivent être définies du point de vue de l'hôte. + +Vous pouvez utiliser un `docker-compose.yml` comme celui-ci : + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Dans cette variante : + +- `NOCOBASE_PROXY_STORAGE_PATH` doit être le chemin absolu du répertoire `storage` sur l'hôte +- `NOCOBASE_PROXY_UPSTREAM_HOST` doit être `127.0.0.1` +- Le service `app` doit conserver `ports`, afin que le Caddy local puisse atteindre l'application via `127.0.0.1:13000` + +Une fois le conteneur `app` démarré, attendez que le fichier de configuration soit généré, puis créez le lien vers le chemin de configuration local de Caddy : + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +Si votre Caddy local n'utilise pas `/etc/caddy/Caddyfile`, remplacez la cible du lien par votre propre chemin de configuration. En général, il est plus sûr de garder `nocobase.caddy` comme fichier d'entrée principal plutôt que d'en recopier le contenu manuellement. + +## Liens associés + +- [Installation Docker (Nginx intégré)](./docker.mdx) — Commencez par le déploiement à conteneur unique +- [Proxy de ressources statiques avec Caddy](../deployment/static-resource-proxy/caddy.md) — En savoir plus sur la configuration Caddy générée diff --git a/docs/docs/fr/get-started/installation/docker-nginx.mdx b/docs/docs/fr/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..e664f5c8988 --- /dev/null +++ b/docs/docs/fr/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Installation Docker (Nginx externe)" +description: "Installez NocoBase avec Docker et utilisez un conteneur Nginx externe comme point d'entrée." +keywords: "Docker,NocoBase,Nginx,installation,proxy inverse" +--- + +# Installation Docker (Nginx externe) + +Dans ce mode, le conteneur d'application NocoBase et le conteneur Nginx s'exécutent séparément. Vous pouvez commencer par [Installation Docker (Nginx intégré)](./docker.mdx), puis basculer l'entrée vers un conteneur Nginx externe. + +## Quand utiliser ce mode + +- Vous voulez déployer NocoBase et le serveur web séparément +- Vous voulez gérer vous-même la configuration Nginx et les ports exposés +- Vous voulez exposer au réseau public uniquement le conteneur proxy + +## Exemple de docker-compose.yml + +Si vous avez besoin de l'image `full`, remplacez `latest-no-nginx` par `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Points clés + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrait les ressources client et génère la configuration du proxy +- `NOCOBASE_PROXY_PROVIDER=nginx` indique que la configuration Nginx doit être générée +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` permet au conteneur Nginx d'accéder au service `app` via le réseau Compose +- `./storage` doit être monté dans `app` et `nginx` afin de partager la configuration du proxy, les ressources statiques et les fichiers téléversés +- Le conteneur `nginx` doit attendre que `nocobase.conf` soit généré, puis créer un lien vers `/etc/nginx/conf.d/default.conf` avec `ln -sf` +- Si vous utilisez l'image avec Nginx intégré, le conteneur `app` expose lui-même le port avec `ports: "13000:80"` +- Si vous utilisez un conteneur Nginx externe, laissez le conteneur `nginx` gérer le mapping du port vers l'hôte et n'exposez pas le port du service `app` à l'hôte + +## Si vous utilisez un Nginx local sur l'hôte + +Si votre Nginx est installé directement sur l'hôte au lieu de s'exécuter dans un conteneur Docker, il est préférable d'utiliser un `docker-compose.yml` séparé. Dans ce mode, le service `app` doit exposer un port vers l'hôte, et les variables du proxy doivent être définies du point de vue de l'hôte. + +Vous pouvez utiliser un `docker-compose.yml` comme celui-ci : + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Dans cette variante : + +- `NOCOBASE_PROXY_STORAGE_PATH` doit être le chemin absolu du répertoire `storage` sur l'hôte +- `NOCOBASE_PROXY_UPSTREAM_HOST` doit être `127.0.0.1` +- Le service `app` doit conserver `ports`, afin que le Nginx local puisse atteindre l'application via `127.0.0.1:13000` + +Une fois le conteneur `app` démarré, attendez que le fichier de configuration soit généré, puis créez le lien vers le répertoire de configuration local de Nginx : + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +Si votre Nginx local n'utilise pas le répertoire `conf.d`, remplacez la cible du lien par votre propre chemin de configuration. En général, il est plus sûr de garder `nocobase.conf` comme un fichier inclus depuis le contexte `http {}` plutôt que d'en recopier le contenu manuellement. + +## Liens associés + +- [Installation Docker (Nginx intégré)](./docker.mdx) — Commencez par le déploiement à conteneur unique +- [Proxy de ressources statiques avec Nginx](../deployment/static-resource-proxy/nginx.md) — En savoir plus sur la configuration Nginx générée diff --git a/docs/docs/id/api/cli/config/delete.md b/docs/docs/id/api/cli/config/delete.md index ce7d4d9bc2f..856c9396db4 100644 --- a/docs/docs/id/api/cli/config/delete.md +++ b/docs/docs/id/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "Referensi perintah nb config delete: menghapus item konfigurasi CLI yang diatur secara eksplisit." -keywords: "nb config delete,NocoBase CLI,menghapus konfigurasi" +title: 'nb config delete' +description: 'Referensi perintah nb config delete: menghapus item konfigurasi CLI yang diatur secara eksplisit.' +keywords: 'nb config delete,NocoBase CLI,menghapus konfigurasi' --- # nb config delete @@ -16,9 +16,9 @@ nb config delete ## Parameter -| Parameter | Tipe | Deskripsi | -| --- | --- | --- | -| `` | string | Nama item konfigurasi. Lihat [`nb config`](./index.md) untuk nilai yang didukung | +| Parameter | Tipe | Deskripsi | +| --------- | ------ | -------------------------------------------------------------------------------- | +| `` | string | Nama item konfigurasi. Lihat [`nb config`](./index.md) untuk nilai yang didukung | ## Contoh @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/id/api/cli/config/get.md b/docs/docs/id/api/cli/config/get.md index 20745e6246f..c47e69d03e7 100644 --- a/docs/docs/id/api/cli/config/get.md +++ b/docs/docs/id/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "Referensi perintah nb config get: membaca nilai efektif dari item konfigurasi CLI." -keywords: "nb config get,NocoBase CLI,membaca konfigurasi" +title: 'nb config get' +description: 'Referensi perintah nb config get: membaca nilai efektif dari item konfigurasi CLI.' +keywords: 'nb config get,NocoBase CLI,membaca konfigurasi' --- # nb config get @@ -16,9 +16,9 @@ nb config get ## Parameter -| Parameter | Tipe | Deskripsi | -| --- | --- | --- | -| `` | string | Nama item konfigurasi. Lihat [`nb config`](./index.md) untuk nilai yang didukung | +| Parameter | Tipe | Deskripsi | +| --------- | ------ | -------------------------------------------------------------------------------- | +| `` | string | Nama item konfigurasi. Lihat [`nb config`](./index.md) untuk nilai yang didukung | ## Contoh @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/id/api/cli/config/index.md b/docs/docs/id/api/cli/config/index.md index e1cdb20a379..a7dcbbb8e5d 100644 --- a/docs/docs/id/api/cli/config/index.md +++ b/docs/docs/id/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "Referensi nb config: kelola nilai konfigurasi default untuk NocoBase CLI." -keywords: "nb config,NocoBase CLI,konfigurasi,konfigurasi default" +title: 'nb config' +description: 'Referensi nb config: kelola nilai konfigurasi default untuk NocoBase CLI.' +keywords: 'nb config,NocoBase CLI,konfigurasi,konfigurasi default' --- # nb config @@ -10,6 +10,7 @@ Mengelola nilai konfigurasi default CLI. Kunci yang saat ini didukung secara umu - CLI itu sendiri: `locale`, `update.policy`, `license.pkg-url` - Runtime Docker: `docker.network`, `docker.container-prefix` +- Image resmi NocoBase: `nb-image-registry`, `nb-image-variant` - Executable eksternal: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - Pembuatan proxy: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ Sebagian besar proyek hanya membutuhkan beberapa kunci saja. Dalam praktiknya, y - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` atau `bin.caddy` - `proxy.nginx-driver` atau `proxy.caddy-driver` ## Kunci konfigurasi umum -| Kunci | Default | Deskripsi | -| --- | --- | --- | -| `locale` | diselesaikan menurut aturan CLI saat ini | Menimpa bahasa yang digunakan oleh CLI | -| `update.policy` | `prompt` | Kebijakan pembaruan saat startup: `prompt`, `auto`, atau `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | Menimpa URL unduhan untuk paket ekstensi komersial | -| `docker.network` | `nocobase` | Jaringan default untuk aplikasi Docker yang dikelola CLI | -| `docker.container-prefix` | `nb` | Prefix default untuk container Docker yang dikelola CLI | -| `bin.docker` | `docker` | Menimpa path executable Docker | -| `bin.caddy` | `caddy` | Menimpa path executable Caddy | -| `bin.git` | `git` | Menimpa path executable Git | -| `bin.nginx` | `nginx` | Menimpa path executable Nginx | -| `bin.pnpm` | `pnpm` | Menimpa path executable pnpm | -| `bin.yarn` | `yarn` | Menimpa path executable Yarn | -| `proxy.nb-cli-root` | root CLI, biasanya direktori home pengguna saat ini | Menimpa root path yang terlihat oleh konfigurasi proxy yang dihasilkan ketika proses proxy dan CLI tidak melihat root filesystem yang sama | -| `proxy.upstream-host` | `127.0.0.1` | Menimpa host yang digunakan proxy untuk meneruskan trafik kembali ke aplikasi NocoBase | -| `proxy.nginx-driver` | `local` | Driver runtime default yang digunakan oleh `nb proxy nginx` | -| `proxy.caddy-driver` | `local` | Driver runtime default yang digunakan oleh `nb proxy caddy` | +| Kunci | Default | Deskripsi | +| ------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `locale` | diselesaikan menurut aturan CLI saat ini | Menimpa bahasa yang digunakan oleh CLI | +| `update.policy` | `prompt` | Kebijakan pembaruan saat startup: `prompt`, `auto`, atau `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | Menimpa URL unduhan untuk paket ekstensi komersial | +| `docker.network` | `nocobase` | Jaringan default untuk aplikasi Docker yang dikelola CLI | +| `docker.container-prefix` | `nb` | Prefix default untuk container Docker yang dikelola CLI | +| `nb-image-registry` | `dockerhub` | Keluarga registry default untuk image resmi NocoBase: `dockerhub` atau `aliyun` | +| `nb-image-variant` | `full` | Varian tag default untuk image app resmi NocoBase: `standard`, `no-nginx`, `full`, atau `full-no-nginx` | +| `bin.docker` | `docker` | Menimpa path executable Docker | +| `bin.caddy` | `caddy` | Menimpa path executable Caddy | +| `bin.git` | `git` | Menimpa path executable Git | +| `bin.nginx` | `nginx` | Menimpa path executable Nginx | +| `bin.pnpm` | `pnpm` | Menimpa path executable pnpm | +| `bin.yarn` | `yarn` | Menimpa path executable Yarn | +| `proxy.nb-cli-root` | root CLI, biasanya direktori home pengguna saat ini | Menimpa root path yang terlihat oleh konfigurasi proxy yang dihasilkan ketika proses proxy dan CLI tidak melihat root filesystem yang sama | +| `proxy.upstream-host` | `127.0.0.1` | Menimpa host yang digunakan proxy untuk meneruskan trafik kembali ke aplikasi NocoBase | +| `proxy.nginx-driver` | `local` | Driver runtime default yang digunakan oleh `nb proxy nginx` | +| `proxy.caddy-driver` | `local` | Driver runtime default yang digunakan oleh `nb proxy caddy` | ## Penggunaan @@ -49,12 +54,12 @@ nb config ## Subcommand -| Command | Deskripsi | -| --- | --- | -| [`nb config get`](./get.md) | Membaca nilai efektif dari sebuah kunci konfigurasi | -| [`nb config set`](./set.md) | Menetapkan sebuah kunci konfigurasi | -| [`nb config delete`](./delete.md) | Menghapus kunci konfigurasi yang ditetapkan secara eksplisit | -| [`nb config list`](./list.md) | Menampilkan kunci konfigurasi yang saat ini ditetapkan secara eksplisit | +| Command | Deskripsi | +| --------------------------------- | ----------------------------------------------------------------------- | +| [`nb config get`](./get.md) | Membaca nilai efektif dari sebuah kunci konfigurasi | +| [`nb config set`](./set.md) | Menetapkan sebuah kunci konfigurasi | +| [`nb config delete`](./delete.md) | Menghapus kunci konfigurasi yang ditetapkan secara eksplisit | +| [`nb config list`](./list.md) | Menampilkan kunci konfigurasi yang saat ini ditetapkan secara eksplisit | ## Contoh @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` dan `bin.caddy` hanya memengaruhi driver `local` untuk `nb proxy nginx` dan `nb proxy caddy` - `bin.pnpm` digunakan saat perintah perlu menjalankan pnpm secara langsung, misalnya saat memperbarui instalasi CLI global yang dikelola pnpm dengan `nb self update` +- `nb-image-registry` hanya memengaruhi default image resmi NocoBase yang digunakan oleh CLI. `dockerhub` menggunakan image app `nocobase/nocobase`, sedangkan `aliyun` menggunakan `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` hanya memengaruhi tag image app resmi NocoBase. Dengan versi `1.7.14`, CLI menyelesaikan `standard` menjadi `1.7.14`, `no-nginx` menjadi `1.7.14-no-nginx`, `full` menjadi `1.7.14-full`, dan `full-no-nginx` menjadi `1.7.14-full-no-nginx` +- Saat `nb-image-registry=aliyun`, CLI juga mengganti image database bawaan default ke mirror resmi Aliyun untuk PostgreSQL, MySQL, MariaDB, dan Kingbase - `proxy.nginx-driver` dan `proxy.caddy-driver` menyimpan driver default yang digunakan oleh masing-masing provider - `proxy.nb-cli-root` dan `proxy.upstream-host` adalah override proxy tingkat lanjut. Untuk sebagian besar env `local` atau `docker` yang dikelola CLI, nilai default sudah cukup - Jika kamu hanya ingin mengganti driver proxy aktif, menggunakan `nb proxy nginx use` atau `nb proxy caddy use` biasanya lebih jelas daripada mengatur kunci konfigurasi secara manual diff --git a/docs/docs/id/api/cli/config/set.md b/docs/docs/id/api/cli/config/set.md index 76b0703a6bd..b352816a175 100644 --- a/docs/docs/id/api/cli/config/set.md +++ b/docs/docs/id/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "Referensi perintah nb config set: menetapkan item konfigurasi CLI." -keywords: "nb config set,NocoBase CLI,menetapkan konfigurasi" +title: 'nb config set' +description: 'Referensi perintah nb config set: menetapkan item konfigurasi CLI.' +keywords: 'nb config set,NocoBase CLI,menetapkan konfigurasi' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## Parameter -| Parameter | Tipe | Deskripsi | -| --- | --- | --- | -| `` | string | Nama item konfigurasi. Lihat [`nb config`](./index.md) untuk nilai yang didukung | -| `` | string | Nilai konfigurasi, tidak boleh kosong | +| Parameter | Tipe | Deskripsi | +| --------- | ------ | -------------------------------------------------------------------------------- | +| `` | string | Nama item konfigurasi. Lihat [`nb config`](./index.md) untuk nilai yang didukung | +| `` | string | Nilai konfigurasi, tidak boleh kosong | ## Contoh @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## Catatan -`update.policy` mendukung `prompt`, `auto`, dan `off`, dengan nilai default `prompt`. +- `update.policy` mendukung `prompt`, `auto`, dan `off`, dengan nilai default `prompt` +- `nb-image-registry` mendukung `dockerhub` dan `aliyun`, dengan nilai default `dockerhub` +- `nb-image-variant` mendukung `standard`, `no-nginx`, `full`, dan `full-no-nginx`, dengan nilai default `full` ## Perintah terkait diff --git a/docs/docs/id/get-started/_meta.json b/docs/docs/id/get-started/_meta.json index 8ea5fdc7a65..57ff40dad85 100644 --- a/docs/docs/id/get-started/_meta.json +++ b/docs/docs/id/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Instalasi Docker", + "label": "Instalasi Docker (Nginx bawaan)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Instalasi Docker (Nginx eksternal)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Instalasi Docker (Caddy eksternal)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "Instalasi create-nocobase-app", diff --git a/docs/docs/id/get-started/installation/docker-caddy.mdx b/docs/docs/id/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..970d1997d82 --- /dev/null +++ b/docs/docs/id/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Instalasi Docker (Caddy eksternal)" +description: "Instal NocoBase dengan Docker dan gunakan kontainer Caddy eksternal sebagai pintu masuk." +keywords: "Docker,NocoBase,Caddy,instalasi,reverse proxy" +--- + +# Instalasi Docker (Caddy eksternal) + +Dalam mode ini, kontainer aplikasi NocoBase dan kontainer Caddy berjalan terpisah. Anda bisa mulai dari [Instalasi Docker (Nginx bawaan)](./docker.mdx), lalu mengganti pintu masuk ke kontainer Caddy eksternal. + +## Kapan menggunakan mode ini + +- Anda ingin memisahkan deployment NocoBase dan web server +- Anda ingin menyederhanakan konfigurasi reverse proxy dan HTTPS dengan Caddy +- Anda ingin hanya mengekspos kontainer proxy ke jaringan publik + +## Contoh docker-compose.yml + +Jika Anda membutuhkan image `full`, ganti `latest-no-nginx` dengan `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Poin penting + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` mengekstrak aset klien dan membuat konfigurasi proxy +- `NOCOBASE_PROXY_PROVIDER=caddy` menandakan bahwa konfigurasi Caddy harus dibuat +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` memungkinkan kontainer Caddy mengakses layanan `app` melalui jaringan Compose +- `./storage` harus dimount ke `app` dan `caddy` agar konfigurasi proxy, aset statis, dan file unggahan bisa dipakai bersama +- Kontainer `caddy` perlu menunggu sampai `nocobase.caddy` dibuat, lalu menautkannya ke `/etc/caddy/Caddyfile` dengan `ln -sf` +- Ekspos hanya port kontainer Caddy ke host. Layanan `app` tidak perlu membuka port ke host + +## Jika menggunakan Caddy lokal di host + +Jika Caddy Anda terpasang langsung di host dan tidak berjalan di dalam kontainer Docker, sebaiknya gunakan `docker-compose.yml` terpisah. Dalam mode ini, layanan `app` perlu membuka port ke host, dan variabel proxy harus memakai nilai dari sudut pandang host. + +Anda bisa memakai `docker-compose.yml` seperti ini: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Dalam varian ini: + +- `NOCOBASE_PROXY_STORAGE_PATH` harus berupa path absolut direktori `storage` di host +- `NOCOBASE_PROXY_UPSTREAM_HOST` harus `127.0.0.1` +- Layanan `app` perlu mempertahankan `ports`, supaya Caddy lokal bisa mengakses aplikasi melalui `127.0.0.1:13000` + +Setelah kontainer `app` berjalan, tunggu file konfigurasi dibuat lalu tautkan ke path konfigurasi Caddy lokal: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +Jika Caddy lokal Anda tidak menggunakan `/etc/caddy/Caddyfile`, ganti target link dengan path konfigurasi Anda sendiri. Biasanya lebih aman membiarkan `nocobase.caddy` tetap sebagai file masuk utama daripada menyalin isinya secara manual. + +## Tautan terkait + +- [Instalasi Docker (Nginx bawaan)](./docker.mdx) — Mulai dari deployment satu kontainer +- [Proxy sumber daya statis Caddy](../deployment/static-resource-proxy/caddy.md) — Pelajari lebih lanjut tentang konfigurasi Caddy yang dihasilkan diff --git a/docs/docs/id/get-started/installation/docker-nginx.mdx b/docs/docs/id/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..e6e0352ee8b --- /dev/null +++ b/docs/docs/id/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Instalasi Docker (Nginx eksternal)" +description: "Instal NocoBase dengan Docker dan gunakan kontainer Nginx eksternal sebagai pintu masuk." +keywords: "Docker,NocoBase,Nginx,instalasi,reverse proxy" +--- + +# Instalasi Docker (Nginx eksternal) + +Dalam mode ini, kontainer aplikasi NocoBase dan kontainer Nginx berjalan terpisah. Anda bisa mulai dari [Instalasi Docker (Nginx bawaan)](./docker.mdx), lalu mengganti pintu masuk ke kontainer Nginx eksternal. + +## Kapan menggunakan mode ini + +- Anda ingin memisahkan deployment NocoBase dan web server +- Anda ingin mengelola sendiri konfigurasi Nginx dan port yang dibuka +- Anda ingin hanya mengekspos kontainer proxy ke jaringan publik + +## Contoh docker-compose.yml + +Jika Anda membutuhkan image `full`, ganti `latest-no-nginx` dengan `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Poin penting + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` mengekstrak aset klien dan membuat konfigurasi proxy +- `NOCOBASE_PROXY_PROVIDER=nginx` menandakan bahwa konfigurasi Nginx harus dibuat +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` memungkinkan kontainer Nginx mengakses layanan `app` melalui jaringan Compose +- `./storage` harus dimount ke `app` dan `nginx` agar konfigurasi proxy, aset statis, dan file unggahan bisa dipakai bersama +- Kontainer `nginx` perlu menunggu sampai `nocobase.conf` dibuat, lalu menautkannya ke `/etc/nginx/conf.d/default.conf` dengan `ln -sf` +- Jika Anda memakai image dengan Nginx bawaan, kontainer `app` sendiri membuka port dengan `ports: "13000:80"` +- Jika Anda memakai kontainer Nginx eksternal, biarkan kontainer `nginx` yang menangani pemetaan port ke host, dan layanan `app` tidak perlu membuka port ke host + +## Jika menggunakan Nginx lokal di host + +Jika Nginx Anda terpasang langsung di host dan tidak berjalan di dalam kontainer Docker, sebaiknya gunakan `docker-compose.yml` terpisah. Dalam mode ini, layanan `app` perlu membuka port ke host, dan variabel proxy harus memakai nilai dari sudut pandang host. + +Anda bisa memakai `docker-compose.yml` seperti ini: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Dalam varian ini: + +- `NOCOBASE_PROXY_STORAGE_PATH` harus berupa path absolut direktori `storage` di host +- `NOCOBASE_PROXY_UPSTREAM_HOST` harus `127.0.0.1` +- Layanan `app` perlu mempertahankan `ports`, supaya Nginx lokal bisa mengakses aplikasi melalui `127.0.0.1:13000` + +Setelah kontainer `app` berjalan, tunggu file konfigurasi dibuat lalu tautkan ke direktori konfigurasi Nginx lokal: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +Jika Nginx lokal Anda tidak menggunakan direktori `conf.d`, ganti target link dengan path konfigurasi Anda sendiri. Biasanya lebih aman membiarkan `nocobase.conf` tetap sebagai file yang di-include dari konteks `http {}` daripada menyalin isinya secara manual. + +## Tautan terkait + +- [Instalasi Docker (Nginx bawaan)](./docker.mdx) — Mulai dari deployment satu kontainer +- [Proxy sumber daya statis Nginx](../deployment/static-resource-proxy/nginx.md) — Pelajari lebih lanjut tentang konfigurasi Nginx yang dihasilkan diff --git a/docs/docs/ja/api/cli/config/delete.md b/docs/docs/ja/api/cli/config/delete.md index 3293636ffad..0d08e8a00c4 100644 --- a/docs/docs/ja/api/cli/config/delete.md +++ b/docs/docs/ja/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "nb config delete コマンドリファレンス:明示的に設定された CLI 設定項目を削除します。" -keywords: "nb config delete,NocoBase CLI,設定を削除" +title: 'nb config delete' +description: 'nb config delete コマンドリファレンス:明示的に設定された CLI 設定項目を削除します。' +keywords: 'nb config delete,NocoBase CLI,設定を削除' --- # nb config delete @@ -16,9 +16,9 @@ nb config delete ## パラメータ -| パラメータ | 型 | 説明 | -| --- | --- | --- | -| `` | string | 設定項目名。対応している値は [`nb config`](./index.md) を参照してください | +| パラメータ | 型 | 説明 | +| ---------- | ------ | ------------------------------------------------------------------------- | +| `` | string | 設定項目名。対応している値は [`nb config`](./index.md) を参照してください | ## 例 @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/ja/api/cli/config/get.md b/docs/docs/ja/api/cli/config/get.md index a5d92a637c1..fce9a7509c1 100644 --- a/docs/docs/ja/api/cli/config/get.md +++ b/docs/docs/ja/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "nb config get コマンドリファレンス:CLI 設定項目の実際に有効な値を読み取ります。" -keywords: "nb config get,NocoBase CLI,設定を読む" +title: 'nb config get' +description: 'nb config get コマンドリファレンス:CLI 設定項目の実際に有効な値を読み取ります。' +keywords: 'nb config get,NocoBase CLI,設定を読む' --- # nb config get @@ -16,9 +16,9 @@ nb config get ## パラメータ -| パラメータ | 型 | 説明 | -| --- | --- | --- | -| `` | string | 設定項目名。対応している値は [`nb config`](./index.md) を参照してください | +| パラメータ | 型 | 説明 | +| ---------- | ------ | ------------------------------------------------------------------------- | +| `` | string | 設定項目名。対応している値は [`nb config`](./index.md) を参照してください | ## 例 @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/ja/api/cli/config/index.md b/docs/docs/ja/api/cli/config/index.md index 267ba5f9591..6a51efe732c 100644 --- a/docs/docs/ja/api/cli/config/index.md +++ b/docs/docs/ja/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "nb config リファレンス: NocoBase CLI のデフォルト設定値を管理します。" -keywords: "nb config,NocoBase CLI,configuration,default configuration" +title: 'nb config' +description: 'nb config リファレンス: NocoBase CLI のデフォルト設定値を管理します。' +keywords: 'nb config,NocoBase CLI,configuration,default configuration' --- # nb config @@ -10,6 +10,7 @@ CLI のデフォルト設定値を管理します。現在サポートされて - CLI 自体: `locale`, `update.policy`, `license.pkg-url` - Docker ランタイム: `docker.network`, `docker.container-prefix` +- NocoBase 公式イメージ: `nb-image-registry`, `nb-image-variant` - 外部実行ファイル: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - プロキシ生成: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ CLI のデフォルト設定値を管理します。現在サポートされて - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` または `bin.caddy` - `proxy.nginx-driver` または `proxy.caddy-driver` ## よく使う設定キー -| キー | デフォルト | 説明 | -| --- | --- | --- | -| `locale` | 現在の CLI ルールに従って解決 | CLI が使用する言語を上書きします | -| `update.policy` | `prompt` | 起動時の更新ポリシー: `prompt`, `auto`, `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | 商用拡張パッケージのダウンロード URL を上書きします | -| `docker.network` | `nocobase` | CLI 管理の Docker アプリで使用するデフォルトネットワーク | -| `docker.container-prefix` | `nb` | CLI 管理の Docker コンテナで使用するデフォルトプレフィックス | -| `bin.docker` | `docker` | Docker 実行ファイルのパスを上書きします | -| `bin.caddy` | `caddy` | Caddy 実行ファイルのパスを上書きします | -| `bin.git` | `git` | Git 実行ファイルのパスを上書きします | -| `bin.nginx` | `nginx` | Nginx 実行ファイルのパスを上書きします | -| `bin.pnpm` | `pnpm` | pnpm 実行ファイルのパスを上書きします | -| `bin.yarn` | `yarn` | Yarn 実行ファイルのパスを上書きします | -| `proxy.nb-cli-root` | CLI ルート。通常は現在のユーザーのホームディレクトリ | プロキシプロセスと CLI が同じファイルシステムルートを見ていない場合に、生成されるプロキシ設定から見えるルートパスを上書きします | -| `proxy.upstream-host` | `127.0.0.1` | プロキシが NocoBase アプリへトラフィックを転送する際に使うホストを上書きします | -| `proxy.nginx-driver` | `local` | `nb proxy nginx` が使用するデフォルトランタイムドライバ | -| `proxy.caddy-driver` | `local` | `nb proxy caddy` が使用するデフォルトランタイムドライバ | +| キー | デフォルト | 説明 | +| ------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `locale` | 現在の CLI ルールに従って解決 | CLI が使用する言語を上書きします | +| `update.policy` | `prompt` | 起動時の更新ポリシー: `prompt`, `auto`, `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | 商用拡張パッケージのダウンロード URL を上書きします | +| `docker.network` | `nocobase` | CLI 管理の Docker アプリで使用するデフォルトネットワーク | +| `docker.container-prefix` | `nb` | CLI 管理の Docker コンテナで使用するデフォルトプレフィックス | +| `nb-image-registry` | `dockerhub` | NocoBase 公式イメージで使用するデフォルトの registry 系統: `dockerhub` または `aliyun` | +| `nb-image-variant` | `full` | NocoBase 公式アプリイメージで使用するデフォルトの tag バリアント: `standard`, `no-nginx`, `full`, `full-no-nginx` | +| `bin.docker` | `docker` | Docker 実行ファイルのパスを上書きします | +| `bin.caddy` | `caddy` | Caddy 実行ファイルのパスを上書きします | +| `bin.git` | `git` | Git 実行ファイルのパスを上書きします | +| `bin.nginx` | `nginx` | Nginx 実行ファイルのパスを上書きします | +| `bin.pnpm` | `pnpm` | pnpm 実行ファイルのパスを上書きします | +| `bin.yarn` | `yarn` | Yarn 実行ファイルのパスを上書きします | +| `proxy.nb-cli-root` | CLI ルート。通常は現在のユーザーのホームディレクトリ | プロキシプロセスと CLI が同じファイルシステムルートを見ていない場合に、生成されるプロキシ設定から見えるルートパスを上書きします | +| `proxy.upstream-host` | `127.0.0.1` | プロキシが NocoBase アプリへトラフィックを転送する際に使うホストを上書きします | +| `proxy.nginx-driver` | `local` | `nb proxy nginx` が使用するデフォルトランタイムドライバ | +| `proxy.caddy-driver` | `local` | `nb proxy caddy` が使用するデフォルトランタイムドライバ | ## 使い方 @@ -49,12 +54,12 @@ nb config ## サブコマンド -| コマンド | 説明 | -| --- | --- | -| [`nb config get`](./get.md) | 設定キーの実効値を読み取ります | -| [`nb config set`](./set.md) | 設定キーを設定します | -| [`nb config delete`](./delete.md) | 明示的に設定された設定キーを削除します | -| [`nb config list`](./list.md) | 現在明示的に設定されている設定キーを一覧表示します | +| コマンド | 説明 | +| --------------------------------- | -------------------------------------------------- | +| [`nb config get`](./get.md) | 設定キーの実効値を読み取ります | +| [`nb config set`](./set.md) | 設定キーを設定します | +| [`nb config delete`](./delete.md) | 明示的に設定された設定キーを削除します | +| [`nb config list`](./list.md) | 現在明示的に設定されている設定キーを一覧表示します | ## 例 @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` と `bin.caddy` は、`nb proxy nginx` および `nb proxy caddy` の `local` ドライバにのみ影響します - `bin.pnpm` は、pnpm を直接実行する必要があるコマンドで使われます。たとえば pnpm 管理のグローバル CLI インストールを `nb self update` で更新する場合です +- `nb-image-registry` は、CLI が使用する NocoBase 公式イメージのデフォルト値にのみ影響します。`dockerhub` はアプリイメージ `nocobase/nocobase` を使い、`aliyun` は `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` を使います +- `nb-image-variant` は、NocoBase 公式アプリイメージの tag にのみ影響します。バージョン `1.7.14` の場合、CLI は `standard` を `1.7.14`、`no-nginx` を `1.7.14-no-nginx`、`full` を `1.7.14-full`、`full-no-nginx` を `1.7.14-full-no-nginx` に解決します +- `nb-image-registry=aliyun` の場合、CLI は内蔵データベースのデフォルトイメージも PostgreSQL、MySQL、MariaDB、Kingbase の Aliyun 公式ミラーに切り替えます - `proxy.nginx-driver` と `proxy.caddy-driver` は、それぞれの provider が使用するデフォルトドライバを保存します - `proxy.nb-cli-root` と `proxy.upstream-host` は高度なプロキシ上書き設定です。ほとんどの CLI 管理 `local` / `docker` env ではデフォルト値のままで十分です - アクティブなプロキシドライバを切り替えたいだけなら、設定キーを直接書き換えるより `nb proxy nginx use` や `nb proxy caddy use` を使う方が通常は分かりやすいです diff --git a/docs/docs/ja/api/cli/config/set.md b/docs/docs/ja/api/cli/config/set.md index 2cf0eb0eb6c..17e485ade6f 100644 --- a/docs/docs/ja/api/cli/config/set.md +++ b/docs/docs/ja/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "nb config set コマンドリファレンス:CLI 設定項目を設定します。" -keywords: "nb config set,NocoBase CLI,設定を保存" +title: 'nb config set' +description: 'nb config set コマンドリファレンス:CLI 設定項目を設定します。' +keywords: 'nb config set,NocoBase CLI,設定を保存' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## パラメータ -| パラメータ | 型 | 説明 | -| --- | --- | --- | -| `` | string | 設定項目名。対応している値は [`nb config`](./index.md) を参照してください | -| `` | string | 設定値。空にはできません | +| パラメータ | 型 | 説明 | +| ---------- | ------ | ------------------------------------------------------------------------- | +| `` | string | 設定項目名。対応している値は [`nb config`](./index.md) を参照してください | +| `` | string | 設定値。空にはできません | ## 例 @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## 補足 -`update.policy` では `prompt`、`auto`、`off` が使えます。デフォルト値は `prompt` です。 +- `update.policy` では `prompt`、`auto`、`off` が使えます。デフォルト値は `prompt` です +- `nb-image-registry` では `dockerhub` と `aliyun` が使えます。デフォルト値は `dockerhub` です +- `nb-image-variant` では `standard`、`no-nginx`、`full`、`full-no-nginx` が使えます。デフォルト値は `full` です ## 関連コマンド diff --git a/docs/docs/ja/get-started/_meta.json b/docs/docs/ja/get-started/_meta.json index ecc3ff5352f..06a4851d370 100644 --- a/docs/docs/ja/get-started/_meta.json +++ b/docs/docs/ja/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Dockerでのインストール", + "label": "Docker でのインストール(内蔵 Nginx)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Docker でのインストール(外部 Nginx)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Docker でのインストール(外部 Caddy)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "create-nocobase-appでのインストール", diff --git a/docs/docs/ja/get-started/installation/docker-caddy.mdx b/docs/docs/ja/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..ff0297d3d83 --- /dev/null +++ b/docs/docs/ja/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Docker でのインストール(外部 Caddy)" +description: "Docker で NocoBase をインストールし、外部 Caddy コンテナをエントリとして使います。" +keywords: "Docker,NocoBase,Caddy,インストール,リバースプロキシ" +--- + +# Docker でのインストール(外部 Caddy) + +この構成では、NocoBase アプリケーションコンテナと Caddy コンテナを分けて実行します。まず [Docker でのインストール(内蔵 Nginx)](./docker.mdx) を完了し、その後エントリを外部 Caddy コンテナへ切り替える形です。 + +## この構成を使う場面 + +- NocoBase と Web サーバーを分けて運用したい +- Caddy でリバースプロキシや HTTPS 設定を簡単にしたい +- 公開するのはプロキシコンテナだけにしたい + +## docker-compose.yml の例 + +`full` イメージが必要な場合は、`latest-no-nginx` を `latest-full-no-nginx` に置き換えてください。 + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## 重要なポイント + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` でクライアントアセットを抽出し、プロキシ設定を生成します +- `NOCOBASE_PROXY_PROVIDER=caddy` で Caddy 用の設定を生成します +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` により、Caddy コンテナは Compose ネットワーク経由で `app` サービスへ接続します +- `./storage` は `app` と `caddy` の両方にマウントし、プロキシ設定、静的アセット、アップロードファイルを共有できるようにします +- `caddy` コンテナは `nocobase.caddy` が生成されるまで待機し、その後 `ln -sf` で `/etc/caddy/Caddyfile` にリンクしてから起動します +- ホストへ公開するのは Caddy コンテナのポートだけで十分です。`app` サービスはホストへポートを公開する必要はありません + +## ホストにインストールした Caddy を使う場合 + +Caddy を Docker コンテナではなくホストに直接インストールしている場合は、別の `docker-compose.yml` を使うのがおすすめです。この構成では `app` サービスがホストへ直接ポートを公開し、プロキシ関連の環境変数もホスト視点の値にする必要があります。 + +次のような `docker-compose.yml` を使えます。 + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +この構成では: + +- `NOCOBASE_PROXY_STORAGE_PATH` はホスト上の `storage` ディレクトリの絶対パスにします +- `NOCOBASE_PROXY_UPSTREAM_HOST` は `127.0.0.1` にします +- ローカル Caddy が `127.0.0.1:13000` 経由でアプリへアクセスできるよう、`app` サービスは `ports` を残します + +そのうえで、`app` コンテナ起動後に設定ファイルが生成されるのを待ち、ホスト側の Caddy 設定パスへリンクします。 + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +ホスト側の Caddy が `/etc/caddy/Caddyfile` を使っていない場合は、リンク先を自分の設定パスに置き換えてください。通常は `nocobase.caddy` を主入口ファイルとしてそのまま使うほうが安全で、内容を手で分解してコピーするのはおすすめしません。 + +## 関連リンク + +- [Docker でのインストール(内蔵 Nginx)](./docker.mdx) — まずは単一コンテナ構成から始める +- [Caddy 静的リソースプロキシ](../deployment/static-resource-proxy/caddy.md) — 生成される Caddy 設定の詳細 diff --git a/docs/docs/ja/get-started/installation/docker-nginx.mdx b/docs/docs/ja/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..34cee7037e0 --- /dev/null +++ b/docs/docs/ja/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Docker でのインストール(外部 Nginx)" +description: "Docker で NocoBase をインストールし、外部 Nginx コンテナをエントリとして使います。" +keywords: "Docker,NocoBase,Nginx,インストール,リバースプロキシ" +--- + +# Docker でのインストール(外部 Nginx) + +この構成では、NocoBase アプリケーションコンテナと Nginx コンテナを分けて実行します。まず [Docker でのインストール(内蔵 Nginx)](./docker.mdx) を完了し、その後エントリを外部 Nginx コンテナへ切り替える形です。 + +## この構成を使う場面 + +- NocoBase と Web サーバーを分けて運用したい +- Nginx の設定や公開ポートを自分で管理したい +- 公開するのはプロキシコンテナだけにしたい + +## docker-compose.yml の例 + +`full` イメージが必要な場合は、`latest-no-nginx` を `latest-full-no-nginx` に置き換えてください。 + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## 重要なポイント + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` でクライアントアセットを抽出し、プロキシ設定を生成します +- `NOCOBASE_PROXY_PROVIDER=nginx` で Nginx 用の設定を生成します +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` により、Nginx コンテナは Compose ネットワーク経由で `app` サービスへ接続します +- `./storage` は `app` と `nginx` の両方にマウントし、プロキシ設定、静的アセット、アップロードファイルを共有できるようにします +- `nginx` コンテナは `nocobase.conf` が生成されるまで待機し、その後 `ln -sf` で `/etc/nginx/conf.d/default.conf` にリンクしてから起動します +- 内蔵 Nginx のイメージを使う場合は、`app` コンテナ自体が `ports: "13000:80"` でポートを公開します +- 外部 Nginx コンテナを使う場合は、ホスト側へのポートマッピングは `nginx` コンテナに任せ、`app` サービスはホストへポートを公開する必要はありません + +## ホストにインストールした Nginx を使う場合 + +Nginx を Docker コンテナではなくホストに直接インストールしている場合は、別の `docker-compose.yml` を使うのがおすすめです。この構成では `app` サービスがホストへ直接ポートを公開し、プロキシ関連の環境変数もホスト視点の値にする必要があります。 + +次のような `docker-compose.yml` を使えます。 + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +この構成では: + +- `NOCOBASE_PROXY_STORAGE_PATH` はホスト上の `storage` ディレクトリの絶対パスにします +- `NOCOBASE_PROXY_UPSTREAM_HOST` は `127.0.0.1` にします +- ローカル Nginx が `127.0.0.1:13000` 経由でアプリへアクセスできるよう、`app` サービスは `ports` を残します + +そのうえで、`app` コンテナ起動後に設定ファイルが生成されるのを待ち、ホスト側の Nginx 設定ディレクトリへリンクします。 + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +ホスト側の Nginx が `conf.d` ディレクトリを使っていない場合は、リンク先を自分の設定パスに置き換えてください。通常は `nocobase.conf` を `http {}` から include するファイルとしてそのまま使うほうが安全で、内容を手で分解してコピーするのはおすすめしません。 + +## 関連リンク + +- [Docker でのインストール(内蔵 Nginx)](./docker.mdx) — まずは単一コンテナ構成から始める +- [Nginx 静的リソースプロキシ](../deployment/static-resource-proxy/nginx.md) — 生成される Nginx 設定の詳細 diff --git a/docs/docs/pt/api/cli/config/delete.md b/docs/docs/pt/api/cli/config/delete.md index 9c47e81befe..30436314910 100644 --- a/docs/docs/pt/api/cli/config/delete.md +++ b/docs/docs/pt/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "Referência do comando nb config delete: exclua um item de configuração da CLI definido explicitamente." -keywords: "nb config delete,NocoBase CLI,excluir configuração" +title: 'nb config delete' +description: 'Referência do comando nb config delete: exclua um item de configuração da CLI definido explicitamente.' +keywords: 'nb config delete,NocoBase CLI,excluir configuração' --- # nb config delete @@ -16,9 +16,9 @@ nb config delete ## Parâmetros -| Parâmetro | Tipo | Descrição | -| --- | --- | --- | -| `` | string | Nome do item de configuração. Consulte [`nb config`](./index.md) para ver os valores suportados | +| Parâmetro | Tipo | Descrição | +| --------- | ------ | ----------------------------------------------------------------------------------------------- | +| `` | string | Nome do item de configuração. Consulte [`nb config`](./index.md) para ver os valores suportados | ## Exemplos @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/pt/api/cli/config/get.md b/docs/docs/pt/api/cli/config/get.md index b26331a920d..dc1e663b510 100644 --- a/docs/docs/pt/api/cli/config/get.md +++ b/docs/docs/pt/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "Referência do comando nb config get: leia o valor efetivo de um item de configuração da CLI." -keywords: "nb config get,NocoBase CLI,ler configuração" +title: 'nb config get' +description: 'Referência do comando nb config get: leia o valor efetivo de um item de configuração da CLI.' +keywords: 'nb config get,NocoBase CLI,ler configuração' --- # nb config get @@ -16,9 +16,9 @@ nb config get ## Parâmetros -| Parâmetro | Tipo | Descrição | -| --- | --- | --- | -| `` | string | Nome do item de configuração. Consulte [`nb config`](./index.md) para ver os valores suportados | +| Parâmetro | Tipo | Descrição | +| --------- | ------ | ----------------------------------------------------------------------------------------------- | +| `` | string | Nome do item de configuração. Consulte [`nb config`](./index.md) para ver os valores suportados | ## Exemplos @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/pt/api/cli/config/index.md b/docs/docs/pt/api/cli/config/index.md index 27bab7ad46e..3412d4e55df 100644 --- a/docs/docs/pt/api/cli/config/index.md +++ b/docs/docs/pt/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "Referência do nb config: gerencie os valores de configuração padrão da CLI do NocoBase." -keywords: "nb config,NocoBase CLI,configuração,configuração padrão" +title: 'nb config' +description: 'Referência do nb config: gerencie os valores de configuração padrão da CLI do NocoBase.' +keywords: 'nb config,NocoBase CLI,configuração,configuração padrão' --- # nb config @@ -10,6 +10,7 @@ Gerencia os valores de configuração padrão da CLI. As chaves atualmente supor - A própria CLI: `locale`, `update.policy`, `license.pkg-url` - Runtime do Docker: `docker.network`, `docker.container-prefix` +- Imagens oficiais do NocoBase: `nb-image-registry`, `nb-image-variant` - Executáveis externos: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - Geração de proxy: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ A maioria dos projetos só precisa de algumas dessas chaves. Na prática, as mai - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` ou `bin.caddy` - `proxy.nginx-driver` ou `proxy.caddy-driver` ## Chaves de configuração comuns -| Chave | Padrão | Descrição | -| --- | --- | --- | -| `locale` | resolvida pelas regras atuais da CLI | Sobrescreve o idioma usado pela CLI | -| `update.policy` | `prompt` | Política de atualização na inicialização: `prompt`, `auto` ou `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | Sobrescreve a URL de download dos pacotes de extensões comerciais | -| `docker.network` | `nocobase` | Rede padrão para apps Docker gerenciados pela CLI | -| `docker.container-prefix` | `nb` | Prefixo padrão para containers Docker gerenciados pela CLI | -| `bin.docker` | `docker` | Sobrescreve o caminho do executável do Docker | -| `bin.caddy` | `caddy` | Sobrescreve o caminho do executável do Caddy | -| `bin.git` | `git` | Sobrescreve o caminho do executável do Git | -| `bin.nginx` | `nginx` | Sobrescreve o caminho do executável do Nginx | -| `bin.pnpm` | `pnpm` | Sobrescreve o caminho do executável do pnpm | -| `bin.yarn` | `yarn` | Sobrescreve o caminho do executável do Yarn | -| `proxy.nb-cli-root` | raiz da CLI, normalmente o diretório home do usuário atual | Sobrescreve o caminho raiz visível para a configuração de proxy gerada quando o processo do proxy e a CLI não enxergam a mesma raiz do sistema de arquivos | -| `proxy.upstream-host` | `127.0.0.1` | Sobrescreve o host usado pelo proxy para encaminhar tráfego de volta para a aplicação NocoBase | -| `proxy.nginx-driver` | `local` | Driver de runtime padrão usado por `nb proxy nginx` | -| `proxy.caddy-driver` | `local` | Driver de runtime padrão usado por `nb proxy caddy` | +| Chave | Padrão | Descrição | +| ------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `locale` | resolvida pelas regras atuais da CLI | Sobrescreve o idioma usado pela CLI | +| `update.policy` | `prompt` | Política de atualização na inicialização: `prompt`, `auto` ou `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | Sobrescreve a URL de download dos pacotes de extensões comerciais | +| `docker.network` | `nocobase` | Rede padrão para apps Docker gerenciados pela CLI | +| `docker.container-prefix` | `nb` | Prefixo padrão para containers Docker gerenciados pela CLI | +| `nb-image-registry` | `dockerhub` | Família de registry padrão para imagens oficiais do NocoBase: `dockerhub` ou `aliyun` | +| `nb-image-variant` | `full` | Variante de tag padrão para imagens oficiais de app do NocoBase: `standard`, `no-nginx`, `full` ou `full-no-nginx` | +| `bin.docker` | `docker` | Sobrescreve o caminho do executável do Docker | +| `bin.caddy` | `caddy` | Sobrescreve o caminho do executável do Caddy | +| `bin.git` | `git` | Sobrescreve o caminho do executável do Git | +| `bin.nginx` | `nginx` | Sobrescreve o caminho do executável do Nginx | +| `bin.pnpm` | `pnpm` | Sobrescreve o caminho do executável do pnpm | +| `bin.yarn` | `yarn` | Sobrescreve o caminho do executável do Yarn | +| `proxy.nb-cli-root` | raiz da CLI, normalmente o diretório home do usuário atual | Sobrescreve o caminho raiz visível para a configuração de proxy gerada quando o processo do proxy e a CLI não enxergam a mesma raiz do sistema de arquivos | +| `proxy.upstream-host` | `127.0.0.1` | Sobrescreve o host usado pelo proxy para encaminhar tráfego de volta para a aplicação NocoBase | +| `proxy.nginx-driver` | `local` | Driver de runtime padrão usado por `nb proxy nginx` | +| `proxy.caddy-driver` | `local` | Driver de runtime padrão usado por `nb proxy caddy` | ## Uso @@ -49,12 +54,12 @@ nb config ## Subcomandos -| Comando | Descrição | -| --- | --- | -| [`nb config get`](./get.md) | Lê o valor efetivo de uma chave de configuração | -| [`nb config set`](./set.md) | Define uma chave de configuração | -| [`nb config delete`](./delete.md) | Remove uma chave de configuração definida explicitamente | -| [`nb config list`](./list.md) | Lista as chaves de configuração atualmente definidas explicitamente | +| Comando | Descrição | +| --------------------------------- | ------------------------------------------------------------------- | +| [`nb config get`](./get.md) | Lê o valor efetivo de uma chave de configuração | +| [`nb config set`](./set.md) | Define uma chave de configuração | +| [`nb config delete`](./delete.md) | Remove uma chave de configuração definida explicitamente | +| [`nb config list`](./list.md) | Lista as chaves de configuração atualmente definidas explicitamente | ## Exemplos @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` e `bin.caddy` afetam apenas o driver `local` de `nb proxy nginx` e `nb proxy caddy` - `bin.pnpm` é usado quando comandos precisam executar pnpm diretamente, por exemplo ao atualizar uma instalação global da CLI gerenciada por pnpm com `nb self update` +- `nb-image-registry` afeta apenas os padrões de imagens oficiais do NocoBase usados pela CLI. `dockerhub` usa a imagem de app `nocobase/nocobase`, enquanto `aliyun` usa `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` afeta apenas as tags das imagens oficiais de app do NocoBase. Com a versão `1.7.14`, a CLI resolve `standard` para `1.7.14`, `no-nginx` para `1.7.14-no-nginx`, `full` para `1.7.14-full` e `full-no-nginx` para `1.7.14-full-no-nginx` +- Quando `nb-image-registry=aliyun`, a CLI também troca as imagens padrão de banco de dados embutido para os mirrors oficiais da Aliyun de PostgreSQL, MySQL, MariaDB e Kingbase - `proxy.nginx-driver` e `proxy.caddy-driver` armazenam o driver padrão usado por cada provider - `proxy.nb-cli-root` e `proxy.upstream-host` são overrides avançados de proxy. Para a maioria dos envs `local` ou `docker` gerenciados pela CLI, os valores padrão já são suficientes - Se você só quer trocar o driver ativo do proxy, normalmente é mais claro usar `nb proxy nginx use` ou `nb proxy caddy use` do que definir a chave manualmente diff --git a/docs/docs/pt/api/cli/config/set.md b/docs/docs/pt/api/cli/config/set.md index 66430f4fc27..43d8a4645f4 100644 --- a/docs/docs/pt/api/cli/config/set.md +++ b/docs/docs/pt/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "Referência do comando nb config set: defina um item de configuração da CLI." -keywords: "nb config set,NocoBase CLI,definir configuração" +title: 'nb config set' +description: 'Referência do comando nb config set: defina um item de configuração da CLI.' +keywords: 'nb config set,NocoBase CLI,definir configuração' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## Parâmetros -| Parâmetro | Tipo | Descrição | -| --- | --- | --- | -| `` | string | Nome do item de configuração. Consulte [`nb config`](./index.md) para ver os valores suportados | -| `` | string | Valor de configuração; não pode estar vazio | +| Parâmetro | Tipo | Descrição | +| --------- | ------ | ----------------------------------------------------------------------------------------------- | +| `` | string | Nome do item de configuração. Consulte [`nb config`](./index.md) para ver os valores suportados | +| `` | string | Valor de configuração; não pode estar vazio | ## Exemplos @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## Notas -`update.policy` aceita `prompt`, `auto` e `off`, e o valor padrão é `prompt`. +- `update.policy` aceita `prompt`, `auto` e `off`, e o valor padrão é `prompt` +- `nb-image-registry` aceita `dockerhub` e `aliyun`, e o valor padrão é `dockerhub` +- `nb-image-variant` aceita `standard`, `no-nginx`, `full` e `full-no-nginx`, e o valor padrão é `full` ## Comandos relacionados diff --git a/docs/docs/pt/get-started/_meta.json b/docs/docs/pt/get-started/_meta.json index 90e5ea2d0f3..68f1db461b6 100644 --- a/docs/docs/pt/get-started/_meta.json +++ b/docs/docs/pt/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Instalação com Docker", + "label": "Instalação com Docker (Nginx embutido)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Instalação com Docker (Nginx externo)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Instalação com Docker (Caddy externo)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "Instalação com create-nocobase-app", diff --git a/docs/docs/pt/get-started/installation/docker-caddy.mdx b/docs/docs/pt/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..2a8c83b3239 --- /dev/null +++ b/docs/docs/pt/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Instalação com Docker (Caddy externo)" +description: "Instale o NocoBase com Docker e use um contêiner externo do Caddy como entrada." +keywords: "Docker,NocoBase,Caddy,instalação,proxy reverso" +--- + +# Instalação com Docker (Caddy externo) + +Neste modo, o contêiner da aplicação NocoBase e o contêiner do Caddy são executados separadamente. Você pode começar por [Instalação com Docker (Nginx embutido)](./docker.mdx) e depois trocar a entrada para um contêiner externo do Caddy. + +## Quando usar este modo + +- Você quer implantar o NocoBase e o servidor web separadamente +- Você quer simplificar a configuração de proxy reverso e HTTPS com Caddy +- Você quer expor à rede pública apenas o contêiner de proxy + +## Exemplo de docker-compose.yml + +Se você precisar da imagem `full`, substitua `latest-no-nginx` por `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Pontos-chave + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrai os recursos do cliente e gera a configuração do proxy +- `NOCOBASE_PROXY_PROVIDER=caddy` indica que a configuração do Caddy deve ser gerada +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` permite que o contêiner do Caddy acesse o serviço `app` pela rede do Compose +- `./storage` precisa ser montado em `app` e `caddy` para compartilhar a configuração do proxy, os arquivos estáticos e os uploads +- O contêiner `caddy` deve esperar até que `nocobase.caddy` seja gerado e então criar um link para `/etc/caddy/Caddyfile` com `ln -sf` +- Exponha ao host apenas a porta do contêiner Caddy. O serviço `app` não precisa expor sua porta para o host + +## Se você usar Caddy local no host + +Se o seu Caddy estiver instalado diretamente no host e não rodando em um contêiner Docker, é melhor usar um `docker-compose.yml` separado. Nesse modo, o serviço `app` precisa expor uma porta para o host, e as variáveis do proxy devem usar valores do ponto de vista do host. + +Você pode usar um `docker-compose.yml` como este: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Nesta variante: + +- `NOCOBASE_PROXY_STORAGE_PATH` deve ser o caminho absoluto do diretório `storage` no host +- `NOCOBASE_PROXY_UPSTREAM_HOST` deve ser `127.0.0.1` +- O serviço `app` precisa manter `ports`, para que o Caddy local consiga acessar a aplicação por `127.0.0.1:13000` + +Depois que o contêiner `app` iniciar, espere a geração do arquivo de configuração e então faça o link para o caminho de configuração local do Caddy: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +Se o Caddy do host não usar `/etc/caddy/Caddyfile`, substitua o caminho do link pelo seu próprio caminho de configuração. Normalmente é mais seguro manter `nocobase.caddy` como o arquivo principal de entrada em vez de copiar o conteúdo manualmente. + +## Links relacionados + +- [Instalação com Docker (Nginx embutido)](./docker.mdx) — Comece pela implantação de contêiner único +- [Proxy de recursos estáticos com Caddy](../deployment/static-resource-proxy/caddy.md) — Saiba mais sobre a configuração gerada do Caddy diff --git a/docs/docs/pt/get-started/installation/docker-nginx.mdx b/docs/docs/pt/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..1bb5cd3717a --- /dev/null +++ b/docs/docs/pt/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Instalação com Docker (Nginx externo)" +description: "Instale o NocoBase com Docker e use um contêiner externo do Nginx como entrada." +keywords: "Docker,NocoBase,Nginx,instalação,proxy reverso" +--- + +# Instalação com Docker (Nginx externo) + +Neste modo, o contêiner da aplicação NocoBase e o contêiner do Nginx são executados separadamente. Você pode começar por [Instalação com Docker (Nginx embutido)](./docker.mdx) e depois trocar a entrada para um contêiner externo do Nginx. + +## Quando usar este modo + +- Você quer implantar o NocoBase e o servidor web separadamente +- Você quer gerenciar por conta própria a configuração do Nginx e as portas expostas +- Você quer expor à rede pública apenas o contêiner de proxy + +## Exemplo de docker-compose.yml + +Se você precisar da imagem `full`, substitua `latest-no-nginx` por `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Pontos-chave + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` extrai os recursos do cliente e gera a configuração do proxy +- `NOCOBASE_PROXY_PROVIDER=nginx` indica que a configuração do Nginx deve ser gerada +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` permite que o contêiner do Nginx acesse o serviço `app` pela rede do Compose +- `./storage` precisa ser montado em `app` e `nginx` para compartilhar a configuração do proxy, os arquivos estáticos e os uploads +- O contêiner `nginx` deve esperar até que `nocobase.conf` seja gerado e então criar um link para `/etc/nginx/conf.d/default.conf` com `ln -sf` +- Se você usar a imagem com Nginx embutido, o próprio contêiner `app` expõe a porta com `ports: "13000:80"` +- Se você usar um contêiner Nginx externo, deixe o contêiner `nginx` cuidar do mapeamento da porta para o host e não exponha a porta do serviço `app` para o host + +## Se você usar Nginx local no host + +Se o seu Nginx estiver instalado diretamente no host e não rodando em um contêiner Docker, é melhor usar um `docker-compose.yml` separado. Nesse modo, o serviço `app` precisa expor uma porta para o host, e as variáveis do proxy devem usar valores do ponto de vista do host. + +Você pode usar um `docker-compose.yml` como este: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Nesta variante: + +- `NOCOBASE_PROXY_STORAGE_PATH` deve ser o caminho absoluto do diretório `storage` no host +- `NOCOBASE_PROXY_UPSTREAM_HOST` deve ser `127.0.0.1` +- O serviço `app` precisa manter `ports`, para que o Nginx local consiga acessar a aplicação por `127.0.0.1:13000` + +Depois que o contêiner `app` iniciar, espere a geração do arquivo de configuração e então faça o link para o diretório de configuração local do Nginx: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +Se o Nginx do host não usar o diretório `conf.d`, substitua o caminho do link pelo seu próprio caminho de configuração. Normalmente é mais seguro manter `nocobase.conf` como um arquivo incluído a partir do contexto `http {}` em vez de copiar o conteúdo manualmente. + +## Links relacionados + +- [Instalação com Docker (Nginx embutido)](./docker.mdx) — Comece pela implantação de contêiner único +- [Proxy de recursos estáticos com Nginx](../deployment/static-resource-proxy/nginx.md) — Saiba mais sobre a configuração gerada do Nginx diff --git a/docs/docs/ru/api/cli/config/delete.md b/docs/docs/ru/api/cli/config/delete.md index cfe006dab6c..8b88d840ee7 100644 --- a/docs/docs/ru/api/cli/config/delete.md +++ b/docs/docs/ru/api/cli/config/delete.md @@ -16,9 +16,9 @@ nb config delete ## Параметры -| Параметр | Тип | Описание | -| --- | --- | --- | -| `` | string | Имя параметра конфигурации. Поддерживаемые значения см. в [`nb config`](./index.md) | +| Параметр | Тип | Описание | +| -------- | ------ | ----------------------------------------------------------------------------------- | +| `` | string | Имя параметра конфигурации. Поддерживаемые значения см. в [`nb config`](./index.md) | ## Примеры @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete proxy.nginx-driver diff --git a/docs/docs/ru/api/cli/config/get.md b/docs/docs/ru/api/cli/config/get.md index e8ee2727b2b..9dd055416e2 100644 --- a/docs/docs/ru/api/cli/config/get.md +++ b/docs/docs/ru/api/cli/config/get.md @@ -16,9 +16,9 @@ nb config get ## Параметры -| Параметр | Тип | Описание | -| --- | --- | --- | -| `` | string | Имя параметра конфигурации. Поддерживаемые значения см. в [`nb config`](./index.md) | +| Параметр | Тип | Описание | +| -------- | ------ | ----------------------------------------------------------------------------------- | +| `` | string | Имя параметра конфигурации. Поддерживаемые значения см. в [`nb config`](./index.md) | ## Примеры @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get proxy.nginx-driver diff --git a/docs/docs/ru/api/cli/config/index.md b/docs/docs/ru/api/cli/config/index.md index dd77a1775ae..e8494a95ae5 100644 --- a/docs/docs/ru/api/cli/config/index.md +++ b/docs/docs/ru/api/cli/config/index.md @@ -10,6 +10,7 @@ keywords: "nb config,NocoBase CLI,конфигурация,конфигурац - Сама CLI: `locale`, `update.policy`, `license.pkg-url` - Среда выполнения Docker: `docker.network`, `docker.container-prefix` +- Официальные образы NocoBase: `nb-image-registry`, `nb-image-variant` - Внешние исполняемые файлы: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.yarn` - Генерация прокси: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,6 +19,8 @@ keywords: "nb config,NocoBase CLI,конфигурация,конфигурац - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` или `bin.caddy` - `proxy.nginx-driver` или `proxy.caddy-driver` @@ -30,6 +33,8 @@ keywords: "nb config,NocoBase CLI,конфигурация,конфигурац | `license.pkg-url` | `https://pkg.nocobase.com/` | Переопределяет URL загрузки коммерческих плагинов | | `docker.network` | `nocobase` | Сеть по умолчанию для Docker-приложений, управляемых CLI | | `docker.container-prefix` | `nb` | Префикс по умолчанию для Docker-контейнеров, управляемых CLI | +| `nb-image-registry` | `dockerhub` | Семейство реестров по умолчанию для официальных образов NocoBase: `dockerhub` или `aliyun` | +| `nb-image-variant` | `full` | Вариант тэга по умолчанию для официальных образов приложения NocoBase: `standard`, `no-nginx`, `full` или `full-no-nginx` | | `bin.docker` | `docker` | Переопределяет путь к исполняемому файлу Docker | | `bin.caddy` | `caddy` | Переопределяет путь к исполняемому файлу Caddy | | `bin.git` | `git` | Переопределяет путь к исполняемому файлу Git | @@ -49,12 +54,12 @@ nb config ## Подкоманды -| Команда | Описание | -| --- | --- | -| [`nb config get`](./get.md) | Прочитать эффективное значение ключа конфигурации | -| [`nb config set`](./set.md) | Установить ключ конфигурации | -| [`nb config delete`](./delete.md) | Удалить явно заданный ключ конфигурации | -| [`nb config list`](./list.md) | Показать ключи конфигурации, которые сейчас заданы явно | +| Команда | Описание | +| --------------------------------- | ------------------------------------------------------- | +| [`nb config get`](./get.md) | Прочитать эффективное значение ключа конфигурации | +| [`nb config set`](./set.md) | Установить ключ конфигурации | +| [`nb config delete`](./delete.md) | Удалить явно заданный ключ конфигурации | +| [`nb config list`](./list.md) | Показать ключи конфигурации, которые сейчас заданы явно | ## Примеры @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,9 +87,12 @@ nb config delete docker.container-prefix - `bin.nginx` и `bin.caddy` влияют только на драйвер `local` для `nb proxy nginx` и `nb proxy caddy` - `bin.pnpm` используется, когда командам нужно запускать pnpm напрямую, например при обновлении глобальной установки CLI, управляемой pnpm, через `nb self update` +- `nb-image-registry` влияет только на значения по умолчанию для официальных образов NocoBase, которые выводит CLI. `dockerhub` использует app-образ `nocobase/nocobase`, а `aliyun` — `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` влияет только на tag официального app-образа NocoBase. Для версии `1.7.14` CLI сопоставляет `standard` с `1.7.14`, `no-nginx` с `1.7.14-no-nginx`, `full` с `1.7.14-full`, а `full-no-nginx` с `1.7.14-full-no-nginx` +- При `nb-image-registry=aliyun` CLI также переключает встроенные database-образы по умолчанию на официальные Aliyun mirrors для PostgreSQL, MySQL, MariaDB и Kingbase - `proxy.nginx-driver` и `proxy.caddy-driver` хранят драйвер по умолчанию для каждого провайдера - `proxy.nb-cli-root` и `proxy.upstream-host` — это расширенные настройки прокси. Для большинства окружений типов `local` и `docker`, управляемых CLI, достаточно значений по умолчанию -- Если вам нужно только переключить активный драйвер прокси, обычно понятнее использовать `nb proxy nginx use` или `nb proxy caddy use`, чем вручную менять ключ конфигурации +- Если вам нужно только переключить активный proxy-драйвер, обычно понятнее использовать `nb proxy nginx use` или `nb proxy caddy use`, чем вручную менять ключ конфигурации ## Связанные команды diff --git a/docs/docs/ru/api/cli/config/set.md b/docs/docs/ru/api/cli/config/set.md index dd098516f7d..4f4bf307078 100644 --- a/docs/docs/ru/api/cli/config/set.md +++ b/docs/docs/ru/api/cli/config/set.md @@ -16,10 +16,10 @@ nb config set ## Параметры -| Параметр | Тип | Описание | -| --- | --- | --- | -| `` | string | Имя параметра конфигурации. Поддерживаемые значения см. в [`nb config`](./index.md) | -| `` | string | Значение конфигурации, не может быть пустым | +| Параметр | Тип | Описание | +| --------- | ------ | ----------------------------------------------------------------------------------- | +| `` | string | Имя параметра конфигурации. Поддерживаемые значения см. в [`nb config`](./index.md) | +| `` | string | Значение конфигурации, не может быть пустым | ## Примеры @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -43,7 +47,9 @@ nb config set bin.yarn yarn ## Примечания -`update.policy` поддерживает `prompt`, `auto` и `off`, значение по умолчанию — `prompt`. +- `update.policy` поддерживает `prompt`, `auto` и `off`, значение по умолчанию — `prompt` +- `nb-image-registry` поддерживает `dockerhub` и `aliyun`, значение по умолчанию — `dockerhub` +- `nb-image-variant` поддерживает `standard`, `no-nginx`, `full` и `full-no-nginx`, значение по умолчанию — `full` ## Связанные команды diff --git a/docs/docs/ru/get-started/_meta.json b/docs/docs/ru/get-started/_meta.json index 0988102251a..ca7cc0847b6 100644 --- a/docs/docs/ru/get-started/_meta.json +++ b/docs/docs/ru/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Установка через Docker", + "label": "Установка через Docker (встроенный Nginx)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Установка через Docker (внешний Nginx)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Установка через Docker (внешний Caddy)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "Установка через create-nocobase-app", diff --git a/docs/docs/ru/get-started/installation/docker-caddy.mdx b/docs/docs/ru/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..cb72f4d834b --- /dev/null +++ b/docs/docs/ru/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Установка через Docker (внешний Caddy)" +description: "Установите NocoBase через Docker и используйте внешний контейнер Caddy как точку входа." +keywords: "Docker,NocoBase,Caddy,установка,обратный прокси" +--- + +# Установка через Docker (внешний Caddy) + +В этом варианте контейнер приложения NocoBase и контейнер Caddy запускаются отдельно. Можно начать с [Установка через Docker (встроенный Nginx)](./docker.mdx), а затем переключить точку входа на внешний контейнер Caddy. + +## Когда использовать этот вариант + +- Вы хотите разнести NocoBase и веб-сервер по разным контейнерам +- Вы хотите упростить настройку обратного прокси и HTTPS с помощью Caddy +- Вы хотите публиковать во внешнюю сеть только контейнер прокси + +## Пример docker-compose.yml + +Если вам нужен образ `full`, замените `latest-no-nginx` на `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Ключевые моменты + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` извлекает клиентские ресурсы и генерирует конфигурацию прокси +- `NOCOBASE_PROXY_PROVIDER=caddy` указывает, что нужно сгенерировать конфигурацию Caddy +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` позволяет контейнеру Caddy обращаться к сервису `app` через сеть Compose +- `./storage` нужно смонтировать и в `app`, и в `caddy`, чтобы они могли совместно использовать конфигурацию прокси, статические ресурсы и загруженные файлы +- Контейнер `caddy` должен дождаться создания `nocobase.caddy`, а затем с помощью `ln -sf` связать его с `/etc/caddy/Caddyfile` +- На хост нужно публиковать только порт контейнера Caddy. Сервису `app` не нужно публиковать порт на хост + +## Если используется локальный Caddy на хосте + +Если ваш Caddy установлен прямо на хосте, а не работает в Docker-контейнере, лучше использовать отдельный `docker-compose.yml`. В этом варианте сервис `app` должен публиковать порт на хост, а переменные прокси должны быть заданы с точки зрения хоста. + +Можно использовать такой `docker-compose.yml`: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +В этом варианте: + +- `NOCOBASE_PROXY_STORAGE_PATH` должен быть абсолютным путём к каталогу `storage` на хосте +- `NOCOBASE_PROXY_UPSTREAM_HOST` должен быть `127.0.0.1` +- Сервис `app` должен сохранить `ports`, чтобы локальный Caddy мог обращаться к приложению через `127.0.0.1:13000` + +После запуска контейнера `app` дождитесь генерации файла конфигурации, а затем создайте ссылку на него в локальном пути конфигурации Caddy: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +Если ваш локальный Caddy не использует `/etc/caddy/Caddyfile`, замените путь ссылки на свой путь конфигурации. Обычно безопаснее оставлять `nocobase.caddy` как основной входной файл, а не копировать его содержимое вручную. + +## Связанные ссылки + +- [Установка через Docker (встроенный Nginx)](./docker.mdx) — Начните с одноконтейнерного варианта +- [Прокси статических ресурсов Caddy](../deployment/static-resource-proxy/caddy.md) — Подробнее о сгенерированной конфигурации Caddy diff --git a/docs/docs/ru/get-started/installation/docker-nginx.mdx b/docs/docs/ru/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..c365121d958 --- /dev/null +++ b/docs/docs/ru/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Установка через Docker (внешний Nginx)" +description: "Установите NocoBase через Docker и используйте внешний контейнер Nginx как точку входа." +keywords: "Docker,NocoBase,Nginx,установка,обратный прокси" +--- + +# Установка через Docker (внешний Nginx) + +В этом варианте контейнер приложения NocoBase и контейнер Nginx запускаются отдельно. Можно начать с [Установка через Docker (встроенный Nginx)](./docker.mdx), а затем переключить точку входа на внешний контейнер Nginx. + +## Когда использовать этот вариант + +- Вы хотите разнести NocoBase и веб-сервер по разным контейнерам +- Вы хотите самостоятельно управлять конфигурацией Nginx и опубликованными портами +- Вы хотите публиковать во внешнюю сеть только контейнер прокси + +## Пример docker-compose.yml + +Если вам нужен образ `full`, замените `latest-no-nginx` на `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Ключевые моменты + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` извлекает клиентские ресурсы и генерирует конфигурацию прокси +- `NOCOBASE_PROXY_PROVIDER=nginx` указывает, что нужно сгенерировать конфигурацию Nginx +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` позволяет контейнеру Nginx обращаться к сервису `app` через сеть Compose +- `./storage` нужно смонтировать и в `app`, и в `nginx`, чтобы они могли совместно использовать конфигурацию прокси, статические ресурсы и загруженные файлы +- Контейнер `nginx` должен дождаться создания `nocobase.conf`, а затем с помощью `ln -sf` связать его с `/etc/nginx/conf.d/default.conf` +- Если вы используете образ со встроенным Nginx, контейнер `app` сам публикует порт через `ports: "13000:80"` +- Если вы используете внешний контейнер Nginx, сопоставление порта с хостом должен обрабатывать контейнер `nginx`, а сервису `app` не нужно публиковать порт на хост + +## Если используется локальный Nginx на хосте + +Если ваш Nginx установлен прямо на хосте, а не работает в Docker-контейнере, лучше использовать отдельный `docker-compose.yml`. В этом варианте сервис `app` должен публиковать порт на хост, а переменные прокси должны быть заданы с точки зрения хоста. + +Можно использовать такой `docker-compose.yml`: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +В этом варианте: + +- `NOCOBASE_PROXY_STORAGE_PATH` должен быть абсолютным путём к каталогу `storage` на хосте +- `NOCOBASE_PROXY_UPSTREAM_HOST` должен быть `127.0.0.1` +- Сервис `app` должен сохранить `ports`, чтобы локальный Nginx мог обращаться к приложению через `127.0.0.1:13000` + +После запуска контейнера `app` дождитесь генерации файла конфигурации, а затем создайте ссылку на него в локальном каталоге конфигурации Nginx: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +Если ваш локальный Nginx не использует каталог `conf.d`, замените путь ссылки на свой путь конфигурации. Обычно безопаснее оставлять `nocobase.conf` как файл, который подключается из контекста `http {}`, а не копировать его содержимое вручную. + +## Связанные ссылки + +- [Установка через Docker (встроенный Nginx)](./docker.mdx) — Начните с одноконтейнерного варианта +- [Прокси статических ресурсов Nginx](../deployment/static-resource-proxy/nginx.md) — Подробнее о сгенерированной конфигурации Nginx diff --git a/docs/docs/vi/api/cli/config/delete.md b/docs/docs/vi/api/cli/config/delete.md index 37c37897a32..766e777f6db 100644 --- a/docs/docs/vi/api/cli/config/delete.md +++ b/docs/docs/vi/api/cli/config/delete.md @@ -1,7 +1,7 @@ --- -title: "nb config delete" -description: "Tài liệu tham khảo lệnh nb config delete: xóa một mục cấu hình CLI đã được đặt tường minh." -keywords: "nb config delete,NocoBase CLI,xóa cấu hình" +title: 'nb config delete' +description: 'Tài liệu tham khảo lệnh nb config delete: xóa một mục cấu hình CLI đã được đặt tường minh.' +keywords: 'nb config delete,NocoBase CLI,xóa cấu hình' --- # nb config delete @@ -16,8 +16,8 @@ nb config delete ## Tham số -| Tham số | Kiểu | Mô tả | -| --- | --- | --- | +| Tham số | Kiểu | Mô tả | +| ------- | ------ | ------------------------------------------------------------------------------- | | `` | string | Tên mục cấu hình. Xem [`nb config`](./index.md) để biết các giá trị được hỗ trợ | ## Ví dụ @@ -27,6 +27,8 @@ nb config delete locale nb config delete update.policy nb config delete docker.network nb config delete docker.container-prefix +nb config delete nb-image-registry +nb config delete nb-image-variant nb config delete proxy.nb-cli-root nb config delete proxy.upstream-host nb config delete bin.nginx diff --git a/docs/docs/vi/api/cli/config/get.md b/docs/docs/vi/api/cli/config/get.md index a6557221596..48aaee791e8 100644 --- a/docs/docs/vi/api/cli/config/get.md +++ b/docs/docs/vi/api/cli/config/get.md @@ -1,7 +1,7 @@ --- -title: "nb config get" -description: "Tài liệu tham khảo lệnh nb config get: đọc giá trị hiệu lực của một mục cấu hình CLI." -keywords: "nb config get,NocoBase CLI,đọc cấu hình" +title: 'nb config get' +description: 'Tài liệu tham khảo lệnh nb config get: đọc giá trị hiệu lực của một mục cấu hình CLI.' +keywords: 'nb config get,NocoBase CLI,đọc cấu hình' --- # nb config get @@ -16,8 +16,8 @@ nb config get ## Tham số -| Tham số | Kiểu | Mô tả | -| --- | --- | --- | +| Tham số | Kiểu | Mô tả | +| ------- | ------ | ------------------------------------------------------------------------------- | | `` | string | Tên mục cấu hình. Xem [`nb config`](./index.md) để biết các giá trị được hỗ trợ | ## Ví dụ @@ -28,6 +28,8 @@ nb config get update.policy nb config get license.pkg-url nb config get docker.network nb config get docker.container-prefix +nb config get nb-image-registry +nb config get nb-image-variant nb config get proxy.nb-cli-root nb config get proxy.upstream-host nb config get bin.nginx diff --git a/docs/docs/vi/api/cli/config/index.md b/docs/docs/vi/api/cli/config/index.md index 846517b09a4..3596f0b683d 100644 --- a/docs/docs/vi/api/cli/config/index.md +++ b/docs/docs/vi/api/cli/config/index.md @@ -1,7 +1,7 @@ --- -title: "nb config" -description: "Tài liệu tham khảo nb config: quản lý các giá trị cấu hình mặc định của NocoBase CLI." -keywords: "nb config,NocoBase CLI,cấu hình,cấu hình mặc định" +title: 'nb config' +description: 'Tài liệu tham khảo nb config: quản lý các giá trị cấu hình mặc định của NocoBase CLI.' +keywords: 'nb config,NocoBase CLI,cấu hình,cấu hình mặc định' --- # nb config @@ -10,6 +10,7 @@ Quản lý các giá trị cấu hình mặc định của CLI. Các khóa hiệ - Bản thân CLI: `locale`, `update.policy`, `license.pkg-url` - Runtime Docker: `docker.network`, `docker.container-prefix` +- Image chính thức của NocoBase: `nb-image-registry`, `nb-image-variant` - Tệp thực thi bên ngoài: `bin.docker`, `bin.caddy`, `bin.git`, `bin.nginx`, `bin.pnpm`, `bin.yarn` - Sinh proxy: `proxy.nb-cli-root`, `proxy.upstream-host`, `proxy.nginx-driver`, `proxy.caddy-driver` @@ -18,28 +19,32 @@ Phần lớn dự án chỉ cần một vài khóa trong số này. Trên thực - `update.policy` - `docker.network` - `docker.container-prefix` +- `nb-image-registry` +- `nb-image-variant` - `bin.nginx` hoặc `bin.caddy` - `proxy.nginx-driver` hoặc `proxy.caddy-driver` ## Các khóa cấu hình thường dùng -| Khóa | Mặc định | Mô tả | -| --- | --- | --- | -| `locale` | được phân giải theo quy tắc CLI hiện tại | Ghi đè ngôn ngữ mà CLI sử dụng | -| `update.policy` | `prompt` | Chính sách cập nhật khi khởi động: `prompt`, `auto`, hoặc `off` | -| `license.pkg-url` | `https://pkg.nocobase.com/` | Ghi đè URL tải về của các gói extension thương mại | -| `docker.network` | `nocobase` | Mạng mặc định cho các ứng dụng Docker do CLI quản lý | -| `docker.container-prefix` | `nb` | Tiền tố mặc định cho các container Docker do CLI quản lý | -| `bin.docker` | `docker` | Ghi đè đường dẫn thực thi Docker | -| `bin.caddy` | `caddy` | Ghi đè đường dẫn thực thi Caddy | -| `bin.git` | `git` | Ghi đè đường dẫn thực thi Git | -| `bin.nginx` | `nginx` | Ghi đè đường dẫn thực thi Nginx | -| `bin.pnpm` | `pnpm` | Ghi đè đường dẫn thực thi pnpm | -| `bin.yarn` | `yarn` | Ghi đè đường dẫn thực thi Yarn | -| `proxy.nb-cli-root` | root của CLI, thường là thư mục home của người dùng hiện tại | Ghi đè root path mà cấu hình proxy được sinh ra nhìn thấy khi tiến trình proxy và CLI không nhìn cùng một root filesystem | -| `proxy.upstream-host` | `127.0.0.1` | Ghi đè host mà proxy dùng để chuyển tiếp lưu lượng trở lại ứng dụng NocoBase | -| `proxy.nginx-driver` | `local` | Driver runtime mặc định dùng bởi `nb proxy nginx` | -| `proxy.caddy-driver` | `local` | Driver runtime mặc định dùng bởi `nb proxy caddy` | +| Khóa | Mặc định | Mô tả | +| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `locale` | được phân giải theo quy tắc CLI hiện tại | Ghi đè ngôn ngữ mà CLI sử dụng | +| `update.policy` | `prompt` | Chính sách cập nhật khi khởi động: `prompt`, `auto`, hoặc `off` | +| `license.pkg-url` | `https://pkg.nocobase.com/` | Ghi đè URL tải về của các gói extension thương mại | +| `docker.network` | `nocobase` | Mạng mặc định cho các ứng dụng Docker do CLI quản lý | +| `docker.container-prefix` | `nb` | Tiền tố mặc định cho các container Docker do CLI quản lý | +| `nb-image-registry` | `dockerhub` | Họ registry mặc định cho image chính thức của NocoBase: `dockerhub` hoặc `aliyun` | +| `nb-image-variant` | `full` | Biến thể tag mặc định cho image app chính thức của NocoBase: `standard`, `no-nginx`, `full`, hoặc `full-no-nginx` | +| `bin.docker` | `docker` | Ghi đè đường dẫn thực thi Docker | +| `bin.caddy` | `caddy` | Ghi đè đường dẫn thực thi Caddy | +| `bin.git` | `git` | Ghi đè đường dẫn thực thi Git | +| `bin.nginx` | `nginx` | Ghi đè đường dẫn thực thi Nginx | +| `bin.pnpm` | `pnpm` | Ghi đè đường dẫn thực thi pnpm | +| `bin.yarn` | `yarn` | Ghi đè đường dẫn thực thi Yarn | +| `proxy.nb-cli-root` | root của CLI, thường là thư mục home của người dùng hiện tại | Ghi đè root path mà cấu hình proxy được sinh ra nhìn thấy khi tiến trình proxy và CLI không nhìn cùng một root filesystem | +| `proxy.upstream-host` | `127.0.0.1` | Ghi đè host mà proxy dùng để chuyển tiếp lưu lượng trở lại ứng dụng NocoBase | +| `proxy.nginx-driver` | `local` | Driver runtime mặc định dùng bởi `nb proxy nginx` | +| `proxy.caddy-driver` | `local` | Driver runtime mặc định dùng bởi `nb proxy caddy` | ## Cách dùng @@ -49,12 +54,12 @@ nb config ## Lệnh con -| Lệnh | Mô tả | -| --- | --- | -| [`nb config get`](./get.md) | Đọc giá trị hiệu lực của một khóa cấu hình | -| [`nb config set`](./set.md) | Thiết lập một khóa cấu hình | -| [`nb config delete`](./delete.md) | Xóa một khóa cấu hình đã được đặt tường minh | -| [`nb config list`](./list.md) | Liệt kê các khóa cấu hình hiện đang được đặt tường minh | +| Lệnh | Mô tả | +| --------------------------------- | ------------------------------------------------------- | +| [`nb config get`](./get.md) | Đọc giá trị hiệu lực của một khóa cấu hình | +| [`nb config set`](./set.md) | Thiết lập một khóa cấu hình | +| [`nb config delete`](./delete.md) | Xóa một khóa cấu hình đã được đặt tường minh | +| [`nb config list`](./list.md) | Liệt kê các khóa cấu hình hiện đang được đặt tường minh | ## Ví dụ @@ -69,6 +74,9 @@ nb config set proxy.nginx-driver docker nb config set proxy.caddy-driver local nb config get docker.network nb config set docker.network nocobase +nb config get nb-image-registry +nb config set nb-image-registry aliyun +nb config set nb-image-variant full-no-nginx nb config set bin.nginx /usr/sbin/nginx nb config set bin.git /usr/bin/git nb config set bin.pnpm /usr/local/bin/pnpm @@ -79,6 +87,9 @@ nb config delete docker.container-prefix - `bin.nginx` và `bin.caddy` chỉ ảnh hưởng tới driver `local` của `nb proxy nginx` và `nb proxy caddy` - `bin.pnpm` được dùng khi lệnh cần chạy pnpm trực tiếp, chẳng hạn cập nhật cài đặt CLI global do pnpm quản lý bằng `nb self update` +- `nb-image-registry` chỉ ảnh hưởng tới các giá trị mặc định cho image chính thức của NocoBase mà CLI sử dụng. `dockerhub` dùng image app `nocobase/nocobase`, còn `aliyun` dùng `registry.cn-shanghai.aliyuncs.com/nocobase/nocobase` +- `nb-image-variant` chỉ ảnh hưởng tới tag của image app chính thức của NocoBase. Với phiên bản `1.7.14`, CLI phân giải `standard` thành `1.7.14`, `no-nginx` thành `1.7.14-no-nginx`, `full` thành `1.7.14-full`, và `full-no-nginx` thành `1.7.14-full-no-nginx` +- Khi `nb-image-registry=aliyun`, CLI cũng chuyển các image database tích hợp mặc định sang mirror chính thức của Aliyun cho PostgreSQL, MySQL, MariaDB và Kingbase - `proxy.nginx-driver` và `proxy.caddy-driver` lưu driver mặc định mà từng provider sử dụng - `proxy.nb-cli-root` và `proxy.upstream-host` là các thiết lập override proxy nâng cao. Với hầu hết env `local` hoặc `docker` do CLI quản lý, giá trị mặc định là đủ - Nếu bạn chỉ muốn đổi driver proxy đang hoạt động, dùng `nb proxy nginx use` hoặc `nb proxy caddy use` thường rõ ràng hơn là tự đặt khóa cấu hình diff --git a/docs/docs/vi/api/cli/config/set.md b/docs/docs/vi/api/cli/config/set.md index d889f10c0c8..6a166951531 100644 --- a/docs/docs/vi/api/cli/config/set.md +++ b/docs/docs/vi/api/cli/config/set.md @@ -1,7 +1,7 @@ --- -title: "nb config set" -description: "Tài liệu tham khảo lệnh nb config set: đặt một mục cấu hình CLI." -keywords: "nb config set,NocoBase CLI,đặt cấu hình" +title: 'nb config set' +description: 'Tài liệu tham khảo lệnh nb config set: đặt một mục cấu hình CLI.' +keywords: 'nb config set,NocoBase CLI,đặt cấu hình' --- # nb config set @@ -16,10 +16,10 @@ nb config set ## Tham số -| Tham số | Kiểu | Mô tả | -| --- | --- | --- | -| `` | string | Tên mục cấu hình. Xem [`nb config`](./index.md) để biết các giá trị được hỗ trợ | -| `` | string | Giá trị cấu hình, không được để trống | +| Tham số | Kiểu | Mô tả | +| --------- | ------ | ------------------------------------------------------------------------------- | +| `` | string | Tên mục cấu hình. Xem [`nb config`](./index.md) để biết các giá trị được hỗ trợ | +| `` | string | Giá trị cấu hình, không được để trống | ## Ví dụ @@ -29,6 +29,10 @@ nb config set update.policy auto nb config set license.pkg-url https://pkg.nocobase.com/ nb config set docker.network nocobase nb config set docker.container-prefix nb +nb config set nb-image-registry dockerhub +nb config set nb-image-registry aliyun +nb config set nb-image-variant full +nb config set nb-image-variant full-no-nginx nb config set bin.docker /usr/local/bin/docker nb config set bin.caddy /opt/homebrew/bin/caddy nb config set bin.git /usr/bin/git @@ -41,7 +45,9 @@ nb config set bin.yarn yarn ## Ghi chú -`update.policy` hỗ trợ `prompt`, `auto` và `off`, với giá trị mặc định là `prompt`. +- `update.policy` hỗ trợ `prompt`, `auto` và `off`, với giá trị mặc định là `prompt` +- `nb-image-registry` hỗ trợ `dockerhub` và `aliyun`, với giá trị mặc định là `dockerhub` +- `nb-image-variant` hỗ trợ `standard`, `no-nginx`, `full` và `full-no-nginx`, với giá trị mặc định là `full` ## Lệnh liên quan diff --git a/docs/docs/vi/get-started/_meta.json b/docs/docs/vi/get-started/_meta.json index bf74a19da00..e9f673db2e8 100644 --- a/docs/docs/vi/get-started/_meta.json +++ b/docs/docs/vi/get-started/_meta.json @@ -20,9 +20,19 @@ "items": [ { "type": "custom-link", - "label": "Cài đặt bằng Docker", + "label": "Cài đặt Docker (Nginx tích hợp)", "link": "/get-started/installation/docker" }, + { + "type": "custom-link", + "label": "Cài đặt Docker (Nginx bên ngoài)", + "link": "/get-started/installation/docker-nginx" + }, + { + "type": "custom-link", + "label": "Cài đặt Docker (Caddy bên ngoài)", + "link": "/get-started/installation/docker-caddy" + }, { "type": "custom-link", "label": "Cài đặt bằng create-nocobase-app", diff --git a/docs/docs/vi/get-started/installation/docker-caddy.mdx b/docs/docs/vi/get-started/installation/docker-caddy.mdx new file mode 100644 index 00000000000..e5a34768029 --- /dev/null +++ b/docs/docs/vi/get-started/installation/docker-caddy.mdx @@ -0,0 +1,170 @@ +--- +title: "Cài đặt Docker (Caddy bên ngoài)" +description: "Cài đặt NocoBase bằng Docker và dùng một container Caddy bên ngoài làm điểm vào." +keywords: "Docker,NocoBase,Caddy,cài đặt,reverse proxy" +--- + +# Cài đặt Docker (Caddy bên ngoài) + +Trong cách triển khai này, container ứng dụng NocoBase và container Caddy chạy tách rời nhau. Bạn có thể bắt đầu từ [Cài đặt Docker (Nginx tích hợp)](./docker.mdx), rồi chuyển điểm vào sang container Caddy bên ngoài. + +## Khi nào nên dùng cách này + +- Bạn muốn tách riêng NocoBase và web server +- Bạn muốn đơn giản hóa cấu hình reverse proxy và HTTPS với Caddy +- Bạn chỉ muốn đưa container proxy ra mạng công khai + +## Ví dụ docker-compose.yml + +Nếu bạn cần image `full`, hãy thay `latest-no-nginx` bằng `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + caddy: + image: caddy:2 + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 + done + ln -sf /app/nocobase/storage/.nocobase/proxy/caddy/nocobase.caddy /etc/caddy/Caddyfile + caddy run --config /etc/caddy/Caddyfile --adapter caddyfile + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Điểm chính + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` dùng để tách tài nguyên client và tạo cấu hình proxy +- `NOCOBASE_PROXY_PROVIDER=caddy` cho biết cần tạo cấu hình Caddy +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` cho phép container Caddy truy cập dịch vụ `app` qua mạng Compose +- `./storage` cần được mount vào cả `app` và `caddy` để cùng dùng cấu hình proxy, tài nguyên tĩnh và tệp tải lên +- Container `caddy` cần chờ `nocobase.caddy` được tạo xong, sau đó dùng `ln -sf` liên kết nó tới `/etc/caddy/Caddyfile` +- Chỉ cần publish cổng của container Caddy ra host. Dịch vụ `app` không cần publish cổng ra host + +## Nếu dùng Caddy cài trực tiếp trên máy host + +Nếu Caddy của bạn được cài trực tiếp trên máy host thay vì chạy trong container Docker, bạn nên dùng một `docker-compose.yml` riêng. Trong cách này, dịch vụ `app` cần publish cổng ra host, và các biến proxy phải dùng giá trị theo góc nhìn của host. + +Bạn có thể dùng `docker-compose.yml` như sau: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=caddy + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Trong biến thể này: + +- `NOCOBASE_PROXY_STORAGE_PATH` cần là đường dẫn tuyệt đối của thư mục `storage` trên host +- `NOCOBASE_PROXY_UPSTREAM_HOST` cần là `127.0.0.1` +- Dịch vụ `app` cần giữ `ports`, để Caddy trên host có thể truy cập ứng dụng qua `127.0.0.1:13000` + +Sau khi container `app` khởi động, hãy chờ file cấu hình được tạo rồi liên kết nó vào đường dẫn cấu hình Caddy trên host: + +```bash +while [ ! -f ./storage/.nocobase/proxy/caddy/nocobase.caddy ]; do + echo "waiting for nocobase.caddy..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/caddy/nocobase.caddy" /etc/caddy/Caddyfile +sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile +sudo systemctl reload caddy +``` + +Nếu Caddy trên host của bạn không dùng `/etc/caddy/Caddyfile`, hãy thay đường dẫn đích bằng đường dẫn cấu hình thực tế của bạn. Thông thường, giữ `nocobase.caddy` như file đầu vào chính sẽ an toàn hơn là chép thủ công nội dung của nó. + +## Liên kết liên quan + +- [Cài đặt Docker (Nginx tích hợp)](./docker.mdx) — Bắt đầu từ mô hình một container +- [Proxy tài nguyên tĩnh với Caddy](../deployment/static-resource-proxy/caddy.md) — Tìm hiểu thêm về cấu hình Caddy được tạo ra diff --git a/docs/docs/vi/get-started/installation/docker-nginx.mdx b/docs/docs/vi/get-started/installation/docker-nginx.mdx new file mode 100644 index 00000000000..b2e09e1574c --- /dev/null +++ b/docs/docs/vi/get-started/installation/docker-nginx.mdx @@ -0,0 +1,172 @@ +--- +title: "Cài đặt Docker (Nginx bên ngoài)" +description: "Cài đặt NocoBase bằng Docker và dùng một container Nginx bên ngoài làm điểm vào." +keywords: "Docker,NocoBase,Nginx,cài đặt,reverse proxy" +--- + +# Cài đặt Docker (Nginx bên ngoài) + +Trong cách triển khai này, container ứng dụng NocoBase và container Nginx chạy tách rời nhau. Bạn có thể bắt đầu từ [Cài đặt Docker (Nginx tích hợp)](./docker.mdx), rồi chuyển điểm vào sang container Nginx bên ngoài. + +## Khi nào nên dùng cách này + +- Bạn muốn tách riêng NocoBase và web server +- Bạn muốn tự quản lý cấu hình Nginx và các cổng được mở +- Bạn chỉ muốn đưa container proxy ra mạng công khai + +## Ví dụ docker-compose.yml + +Nếu bạn cần image `full`, hãy thay `latest-no-nginx` bằng `latest-full-no-nginx`. + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/app/nocobase/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=app + volumes: + - ./storage:/app/nocobase/storage + + nginx: + image: nginx:latest + restart: always + depends_on: + - app + networks: + - nocobase + volumes: + - ./storage:/app/nocobase/storage + command: > + /bin/sh -c ' + while [ ! -f /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 + done + rm -f /etc/nginx/conf.d/default.conf + ln -sf /app/nocobase/storage/.nocobase/proxy/nginx/nocobase.conf /etc/nginx/conf.d/default.conf + nginx -g "daemon off;" + ' + ports: + - "13000:80" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +## Điểm chính + +- `NOCOBASE_EXTRACT_CLIENT_ASSETS=true` dùng để tách tài nguyên client và tạo cấu hình proxy +- `NOCOBASE_PROXY_PROVIDER=nginx` cho biết cần tạo cấu hình Nginx +- `NOCOBASE_PROXY_UPSTREAM_HOST=app` cho phép container Nginx truy cập dịch vụ `app` qua mạng Compose +- `./storage` cần được mount vào cả `app` và `nginx` để cùng dùng cấu hình proxy, tài nguyên tĩnh và tệp tải lên +- Container `nginx` cần chờ `nocobase.conf` được tạo xong, sau đó dùng `ln -sf` liên kết nó tới `/etc/nginx/conf.d/default.conf` +- Nếu bạn dùng image có Nginx tích hợp sẵn, chính container `app` sẽ publish cổng bằng `ports: "13000:80"` +- Nếu bạn dùng container Nginx bên ngoài, hãy để container `nginx` xử lý phần ánh xạ cổng ra host, còn dịch vụ `app` không cần publish cổng ra host + +## Nếu dùng Nginx cài trực tiếp trên máy host + +Nếu Nginx của bạn được cài trực tiếp trên máy host thay vì chạy trong container Docker, bạn nên dùng một `docker-compose.yml` riêng. Trong cách này, dịch vụ `app` cần publish cổng ra host, và các biến proxy phải dùng giá trị theo góc nhìn của host. + +Bạn có thể dùng `docker-compose.yml` như sau: + +```yml +networks: + nocobase: + driver: bridge + +services: + app: + image: nocobase/nocobase:latest-no-nginx + restart: always + depends_on: + - postgres + networks: + - nocobase + environment: + - APP_KEY=your-secret-key + - DB_DIALECT=postgres + - DB_HOST=postgres + - DB_PORT=5432 + - DB_DATABASE=nocobase + - DB_USER=nocobase + - DB_PASSWORD=nocobase + - TZ=Etc/UTC + - NOCOBASE_EXTRACT_CLIENT_ASSETS=true + - NOCOBASE_PROXY_PROVIDER=nginx + - NOCOBASE_PROXY_STORAGE_PATH=/path/to/your-project/storage + - NOCOBASE_PROXY_UPSTREAM_HOST=127.0.0.1 + - NOCOBASE_PROXY_UPSTREAM_PORT=13000 + volumes: + - ./storage:/app/nocobase/storage + ports: + - "13000:13000" + + postgres: + image: postgres:16 + restart: always + command: postgres -c wal_level=logical + environment: + POSTGRES_USER: nocobase + POSTGRES_DB: nocobase + POSTGRES_PASSWORD: nocobase + volumes: + - ./storage/db/postgres:/var/lib/postgresql/data + networks: + - nocobase +``` + +Trong biến thể này: + +- `NOCOBASE_PROXY_STORAGE_PATH` cần là đường dẫn tuyệt đối của thư mục `storage` trên host +- `NOCOBASE_PROXY_UPSTREAM_HOST` cần là `127.0.0.1` +- Dịch vụ `app` cần giữ `ports`, để Nginx trên host có thể truy cập ứng dụng qua `127.0.0.1:13000` + +Sau khi container `app` khởi động, hãy chờ file cấu hình được tạo rồi liên kết nó vào thư mục cấu hình Nginx trên host: + +```bash +while [ ! -f ./storage/.nocobase/proxy/nginx/nocobase.conf ]; do + echo "waiting for nocobase.conf..." + sleep 1 +done + +sudo ln -sf "$(pwd)/storage/.nocobase/proxy/nginx/nocobase.conf" /etc/nginx/conf.d/nocobase.conf +sudo nginx -t +sudo systemctl reload nginx +``` + +Nếu Nginx trên host của bạn không dùng thư mục `conf.d`, hãy thay đường dẫn đích bằng đường dẫn cấu hình thực tế của bạn. Thông thường, giữ `nocobase.conf` như một file được include từ ngữ cảnh `http {}` sẽ an toàn hơn là chép thủ công nội dung của nó. + +## Liên kết liên quan + +- [Cài đặt Docker (Nginx tích hợp)](./docker.mdx) — Bắt đầu từ mô hình một container +- [Proxy tài nguyên tĩnh với Nginx](../deployment/static-resource-proxy/nginx.md) — Tìm hiểu thêm về cấu hình Nginx được tạo ra diff --git a/packages/core/cli/src/__tests__/app-management-commands.test.ts b/packages/core/cli/src/__tests__/app-management-commands.test.ts index 7a39ae00245..55f74260393 100644 --- a/packages/core/cli/src/__tests__/app-management-commands.test.ts +++ b/packages/core/cli/src/__tests__/app-management-commands.test.ts @@ -30,7 +30,11 @@ async function createNpmSourceProject( ): Promise { const actualFsp = await vi.importActual('node:fs/promises'); const projectRoot = await actualFsp.mkdtemp(path.join(os.tmpdir(), 'nb-source-dev-')); - await actualFsp.writeFile(path.join(projectRoot, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\n`, 'utf-8'); + await actualFsp.writeFile( + path.join(projectRoot, 'package.json'), + `${JSON.stringify(packageJson, null, 2)}\n`, + 'utf-8', + ); if (options?.devtoolsInstalled) { const devtoolsDir = path.join(projectRoot, 'node_modules', '@nocobase', 'devtools'); @@ -1619,6 +1623,49 @@ test('start recreates docker app containers through docker run', async () => { ]); }); +test('start maps no-nginx docker app containers to the app port inside the container', async () => { + const { default: Start } = await import('../commands/app/start.js'); + mocks.resolveManagedAppRuntime.mockResolvedValue({ + kind: 'docker', + envName: 'docker-local', + source: 'docker', + containerName: 'nb-demo-docker-local-app', + workspaceName: 'nb-demo', + env: { + config: { + builtinDb: false, + appKey: 'app-key-123', + timezone: 'Asia/Shanghai', + dbDialect: 'postgres', + dbHost: 'nb-demo-docker-local-postgres', + dbPort: '5432', + dbDatabase: 'nocobase', + dbUser: 'nocobase', + dbPassword: 'nocobase', + dockerRegistry: 'nocobase/nocobase', + downloadVersion: 'next-full-no-nginx', + storagePath: './docker-local/storage', + }, + appPort: 13000, + }, + }); + + const command = createCommandHarness({ + flags: { + env: 'docker-local', + verbose: true, + }, + }); + + await Start.prototype.run.call(command); + + const dockerRunCall = mocks.run.mock.calls.find( + ([bin, args]) => bin === 'docker' && Array.isArray(args) && args[0] === 'run', + ); + expect(dockerRunCall?.[1]).toContain('13000:13000'); + expect(dockerRunCall?.[1]).not.toContain('13000:80'); +}); + test('start enables NOCOBASE_EXTRACT_CLIENT_ASSETS for docker envs by default', async () => { const { default: Start } = await import('../commands/app/start.js'); mocks.resolveManagedAppRuntime.mockResolvedValue({ @@ -2202,10 +2249,7 @@ test('restart forwards app restart hook command for saved hook scripts', async ( expect(runCommand.mock.calls).toEqual([ ['license:plugins:sync', ['--env', 'local', '--skip-if-no-license']], ['app:stop', ['--env', 'local']], - [ - 'app:start', - ['--env', 'local', '--quickstart', '--no-sync-licensed-plugins', '--hook-command', 'app:restart'], - ], + ['app:start', ['--env', 'local', '--quickstart', '--no-sync-licensed-plugins', '--hook-command', 'app:restart']], ]); }); diff --git a/packages/core/cli/src/__tests__/config-command.test.ts b/packages/core/cli/src/__tests__/config-command.test.ts index e2934c7fab4..84bfb2c19a3 100644 --- a/packages/core/cli/src/__tests__/config-command.test.ts +++ b/packages/core/cli/src/__tests__/config-command.test.ts @@ -614,6 +614,86 @@ test('nb config set/get/delete supports caddy/nginx binaries and proxy settings' }); }); +test('nb config set/get/delete supports nb image settings', async () => { + await withTempCliHome(async () => { + const { default: ConfigSet } = await import('../commands/config/set.js'); + const { default: ConfigGet } = await import('../commands/config/get.js'); + const { default: ConfigDelete } = await import('../commands/config/delete.js'); + + const setRegistryCommand = Object.assign(Object.create(ConfigSet.prototype), { + parse: vi.fn(async () => ({ + args: { + key: 'nb-image-registry', + value: 'aliyun', + }, + })), + log: vi.fn(), + }); + await ConfigSet.prototype.run.call(setRegistryCommand); + expect(setRegistryCommand.log).toHaveBeenCalledWith('nb-image-registry=aliyun'); + + const setVariantCommand = Object.assign(Object.create(ConfigSet.prototype), { + parse: vi.fn(async () => ({ + args: { + key: 'nb-image-variant', + value: 'full-no-nginx', + }, + })), + log: vi.fn(), + }); + await ConfigSet.prototype.run.call(setVariantCommand); + expect(setVariantCommand.log).toHaveBeenCalledWith('nb-image-variant=full-no-nginx'); + + const getRegistryCommand = Object.assign(Object.create(ConfigGet.prototype), { + parse: vi.fn(async () => ({ + args: { + key: 'nb-image-registry', + }, + })), + log: vi.fn(), + }); + await ConfigGet.prototype.run.call(getRegistryCommand); + expect(getRegistryCommand.log).toHaveBeenCalledWith('aliyun'); + + const getVariantCommand = Object.assign(Object.create(ConfigGet.prototype), { + parse: vi.fn(async () => ({ + args: { + key: 'nb-image-variant', + }, + })), + log: vi.fn(), + }); + await ConfigGet.prototype.run.call(getVariantCommand); + expect(getVariantCommand.log).toHaveBeenCalledWith('full-no-nginx'); + + const deleteRegistryCommand = Object.assign(Object.create(ConfigDelete.prototype), { + parse: vi.fn(async () => ({ + args: { + key: 'nb-image-registry', + }, + })), + log: vi.fn(), + }); + await ConfigDelete.prototype.run.call(deleteRegistryCommand); + expect(deleteRegistryCommand.log).toHaveBeenCalledWith('Deleted nb-image-registry'); + + const deleteVariantCommand = Object.assign(Object.create(ConfigDelete.prototype), { + parse: vi.fn(async () => ({ + args: { + key: 'nb-image-variant', + }, + })), + log: vi.fn(), + }); + await ConfigDelete.prototype.run.call(deleteVariantCommand); + expect(deleteVariantCommand.log).toHaveBeenCalledWith('Deleted nb-image-variant'); + + const config = await loadAuthConfig({ scope: 'global' }); + expect(config.settings?.docker?.nbImageRegistry).toBe(undefined); + expect(config.settings?.docker?.nbImageVariant).toBe(undefined); + }); +}); + test('nb config list prints only explicit settings', async () => { await withTempCliHome(async () => { const { default: ConfigSet } = await import('../commands/config/set.js'); diff --git a/packages/core/cli/src/__tests__/docker-image.test.ts b/packages/core/cli/src/__tests__/docker-image.test.ts index 6b667079a99..888d6367065 100644 --- a/packages/core/cli/src/__tests__/docker-image.test.ts +++ b/packages/core/cli/src/__tests__/docker-image.test.ts @@ -9,8 +9,15 @@ import { expect, test } from 'vitest'; import { + DEFAULT_KINGBASE_IMAGE, + inferNbImageRegistryFromRepository, + normalizeNbImageRegistry, + normalizeNbImageVariant, normalizeDockerImageTag, + resolveBuiltinDbImage, + resolveDockerImageContainerPort, resolveDockerImageRef, + resolveOfficialDockerRegistry, shouldUseFullDockerImageTag, } from '../lib/docker-image.js'; @@ -18,7 +25,9 @@ test('official docker registries use the -full image tag suffix', () => { expect(shouldUseFullDockerImageTag('nocobase/nocobase')).toBe(true); expect(shouldUseFullDockerImageTag('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase')).toBe(true); expect(normalizeDockerImageTag('nocobase/nocobase', 'alpha')).toBe('alpha-full'); - expect(normalizeDockerImageTag('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase', 'pr-9313')).toBe('pr-9313-full'); + expect(normalizeDockerImageTag('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase', 'pr-9313')).toBe( + 'pr-9313-full', + ); expect(resolveDockerImageRef('nocobase/nocobase', 'beta')).toBe('nocobase/nocobase:beta-full'); }); @@ -34,3 +43,44 @@ test('full suffix is not duplicated when the version already includes it', () => expect(normalizeDockerImageTag('nocobase/nocobase', 'alpha-full')).toBe('alpha-full'); expect(resolveDockerImageRef('nocobase/nocobase', 'beta-full')).toBe('nocobase/nocobase:beta-full'); }); + +test('nb image registry and variant helpers resolve official mappings', () => { + expect(normalizeNbImageRegistry('dockerhub')).toBe('dockerhub'); + expect(normalizeNbImageRegistry('aliyun')).toBe('aliyun'); + expect(normalizeNbImageVariant('full-no-nginx')).toBe('full-no-nginx'); + expect(resolveOfficialDockerRegistry('dockerhub')).toBe('nocobase/nocobase'); + expect(resolveOfficialDockerRegistry('aliyun')).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase'); + expect(inferNbImageRegistryFromRepository('nocobase/nocobase')).toBe('dockerhub'); + expect(inferNbImageRegistryFromRepository('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase')).toBe('aliyun'); +}); + +test('official image variant mapping supports no-nginx and full-no-nginx', () => { + expect(resolveDockerImageRef('nocobase/nocobase', 'latest', { variant: 'standard' })).toBe( + 'nocobase/nocobase:latest', + ); + expect(resolveDockerImageRef('nocobase/nocobase', 'latest', { variant: 'no-nginx' })).toBe( + 'nocobase/nocobase:latest-no-nginx', + ); + expect(resolveDockerImageRef('nocobase/nocobase', 'latest', { variant: 'full' })).toBe( + 'nocobase/nocobase:latest-full', + ); + expect(resolveDockerImageRef('nocobase/nocobase', 'latest', { variant: 'full-no-nginx' })).toBe( + 'nocobase/nocobase:latest-full-no-nginx', + ); +}); + +test('docker image container port follows the resolved nginx variant tag', () => { + expect(resolveDockerImageContainerPort('nocobase/nocobase:latest')).toBe('80'); + expect(resolveDockerImageContainerPort('nocobase/nocobase:latest-full')).toBe('80'); + expect(resolveDockerImageContainerPort('nocobase/nocobase:latest-no-nginx')).toBe('13000'); + expect(resolveDockerImageContainerPort('localhost:5000/nocobase/nocobase:latest-full-no-nginx')).toBe('13000'); +}); + +test('builtin db image mapping follows the selected official image registry', () => { + expect(resolveBuiltinDbImage('postgres', { registry: 'dockerhub' })).toBe('postgres:16'); + expect(resolveBuiltinDbImage('mysql', { registry: 'dockerhub' })).toBe('mysql:8'); + expect(resolveBuiltinDbImage('mariadb', { registry: 'aliyun' })).toBe( + 'registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11', + ); + expect(resolveBuiltinDbImage('kingbase', { registry: 'dockerhub' })).toBe(DEFAULT_KINGBASE_IMAGE); +}); diff --git a/packages/core/cli/src/__tests__/download.test.ts b/packages/core/cli/src/__tests__/download.test.ts index 30b25a2dca7..2f16b848b57 100644 --- a/packages/core/cli/src/__tests__/download.test.ts +++ b/packages/core/cli/src/__tests__/download.test.ts @@ -13,6 +13,7 @@ import path from 'node:path'; import { afterEach, beforeEach, test, vi, expect } from 'vitest'; import type { DownloadResolvedFlags } from '../commands/source/download.js'; import Download from '../commands/source/download.js'; +import { setCliConfigValue } from '../lib/cli-config.js'; const mocks = vi.hoisted(() => ({ run: vi.fn(), @@ -66,6 +67,23 @@ async function useTempCwd(): Promise { return dir; } +async function withTempCliHome(run: () => Promise) { + const previous = process.env.NB_CLI_ROOT; + const tempHome = await fsp.mkdtemp(path.join(os.tmpdir(), 'nocobase-cli-download-config-')); + tempDirs.push(tempHome); + + try { + process.env.NB_CLI_ROOT = tempHome; + await run(); + } finally { + if (previous === undefined) { + delete process.env.NB_CLI_ROOT; + } else { + process.env.NB_CLI_ROOT = previous; + } + } +} + async function pathExists(target: string): Promise { try { await fsp.access(target); @@ -409,40 +427,47 @@ test('download forwards raw command output only in verbose mode', async () => { test('download shows a delayed loading indicator for long-running commands in non-verbose mode', async () => { await useTempCwd(); - vi.useFakeTimers(); + await withTempCliHome(async () => { + vi.useFakeTimers(); - let resolveRun: (() => void) | undefined; - mocks.run.mockImplementationOnce( - () => - new Promise((resolve) => { - resolveRun = resolve; - }), - ); + let resolveRun: (() => void) | undefined; + mocks.run.mockImplementationOnce( + () => + new Promise((resolve) => { + resolveRun = resolve; + }), + ); - const { command } = createCommand(); - const flags: DownloadResolvedFlags = { - source: 'docker', - version: 'latest', - replace: false, - build: true, - 'build-dts': false, - 'docker-registry': 'nocobase/nocobase', - 'docker-save': false, - }; + const { command } = createCommand(); + ( + command as Download & { + resolveConfiguredDockerRegistryDefault: () => Promise; + } + ).resolveConfiguredDockerRegistryDefault = vi.fn(async () => 'nocobase/nocobase'); + const flags: DownloadResolvedFlags = { + source: 'docker', + version: 'latest', + replace: false, + build: true, + 'build-dts': false, + 'docker-registry': 'nocobase/nocobase', + 'docker-save': false, + }; - const promise = command.downloadFromDocker(flags); + const promise = command.downloadFromDocker(flags); - await vi.advanceTimersByTimeAsync(7_999); - expect(mocks.startTask.mock.calls.length).toBe(0); + await vi.advanceTimersByTimeAsync(7_999); + expect(mocks.startTask.mock.calls.length).toBe(0); - await vi.advanceTimersByTimeAsync(1); - expect(mocks.startTask.mock.calls).toEqual([['Pulling the Docker image. Please wait...']]); + await vi.advanceTimersByTimeAsync(1); + expect(mocks.startTask.mock.calls).toEqual([['Pulling the Docker image. Please wait...']]); - resolveRun?.(); - await promise; + resolveRun?.(); + await promise; - expect(mocks.stopTask.mock.calls.length).toBe(1); - expect(mocks.updateTask.mock.calls.length).toBe(0); + expect(mocks.stopTask.mock.calls.length).toBe(1); + expect(mocks.updateTask.mock.calls.length).toBe(0); + }); }); test('download shows a preparation loading state before entering the source-specific flow', async () => { @@ -618,26 +643,29 @@ test('download preserves raw failures in verbose mode', async () => { await expect(command.run()).rejects.toThrow('yarn install exited with code 1'); }); -test('downloadFromDocker uses the locale-aware default registry when docker-registry is not set', async () => { +test('downloadFromDocker uses the configured nb image registry when docker-registry is not set', async () => { await useTempCwd(); - process.env.NB_LOCALE = 'zh-CN'; - mocks.run.mockResolvedValue(undefined); - const { command } = createCommand(); - const flags: DownloadResolvedFlags = { - source: 'docker', - version: 'alpha', - replace: false, - build: true, - 'build-dts': false, - 'docker-save': false, - }; + await withTempCliHome(async () => { + await setCliConfigValue('nb-image-registry', 'aliyun', { scope: 'global' }); + await setCliConfigValue('nb-image-variant', 'full', { scope: 'global' }); + mocks.run.mockResolvedValue(undefined); + const { command } = createCommand(); + const flags: DownloadResolvedFlags = { + source: 'docker', + version: 'alpha', + replace: false, + build: true, + 'build-dts': false, + 'docker-save': false, + }; - await command.downloadFromDocker(flags); + await command.downloadFromDocker(flags); - expect(mocks.run.mock.calls[0]?.[1]).toEqual([ - 'pull', - 'registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:alpha-full', - ]); + expect(mocks.run.mock.calls[0]?.[1]).toEqual([ + 'pull', + 'registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:alpha-full', + ]); + }); }); test('download resolves otherVersion into the final version value', async () => { diff --git a/packages/core/cli/src/__tests__/install-db.test.ts b/packages/core/cli/src/__tests__/install-db.test.ts index 61c692b21c2..2ca5daa760a 100644 --- a/packages/core/cli/src/__tests__/install-db.test.ts +++ b/packages/core/cli/src/__tests__/install-db.test.ts @@ -14,7 +14,7 @@ import path from 'node:path'; import { afterEach, beforeEach, test, expect, vi } from 'vitest'; import Install from '../commands/install.js'; import EnvAdd from '../commands/env/add.js'; -import { deleteCliConfigValue } from '../lib/cli-config.js'; +import { deleteCliConfigValue, setCliConfigValue } from '../lib/cli-config.js'; import { resolveCliHomeRoot, resolveEnvRelativePath } from '../lib/cli-home.js'; import { ENV_CONFIG_SCHEMA_VERSION } from '../lib/env-config.js'; @@ -565,16 +565,14 @@ test('builtin postgres db plan can use the workspace name from config', () => { expect(plan.containerName).toBe('nb-shared-workspace-demo-postgres'); }); -test('builtin db plan uses locale-aware default images when NB_LOCALE is zh-CN', () => { - process.env.NB_LOCALE = 'zh-CN'; - +test('builtin db plan uses dockerhub defaults when no image registry override is configured', () => { const postgresPlan = Install.buildBuiltinDbPlan({ envName: 'demo', storagePath: './storage/demo', source: 'npm', dbDialect: 'postgres', }); - expect(postgresPlan.image).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16'); + expect(postgresPlan.image).toBe('postgres:16'); const mysqlPlan = Install.buildBuiltinDbPlan({ envName: 'demo', @@ -582,7 +580,7 @@ test('builtin db plan uses locale-aware default images when NB_LOCALE is zh-CN', source: 'npm', dbDialect: 'mysql', }); - expect(mysqlPlan.image).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/mysql:8'); + expect(mysqlPlan.image).toBe('mysql:8'); const mariadbPlan = Install.buildBuiltinDbPlan({ envName: 'demo', @@ -590,7 +588,7 @@ test('builtin db plan uses locale-aware default images when NB_LOCALE is zh-CN', source: 'npm', dbDialect: 'mariadb', }); - expect(mariadbPlan.image).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11'); + expect(mariadbPlan.image).toBe('mariadb:11'); }); test('builtin db plan does not publish host port for docker source and uses container host', () => { @@ -729,6 +727,56 @@ test('docker app plan wires app, db, network, port, and image settings', async ( expect(plan.args.includes('DB_UNDERSCORED=true')).toBe(true); }); +test('docker app plan uses configured nb image registry and variant defaults', async () => { + const installStatics = Install as unknown as InstallStatics; + const previousCliRoot = process.env.NB_CLI_ROOT; + const tempCliRoot = await mkdtemp(path.join(os.tmpdir(), 'nocobase-install-db-image-config-')); + + try { + process.env.NB_CLI_ROOT = tempCliRoot; + await setCliConfigValue('nb-image-registry', 'aliyun', { scope: 'global' }); + await setCliConfigValue('nb-image-variant', 'full-no-nginx', { scope: 'global' }); + + const plan = await installStatics.buildDockerAppPlan({ + envName: 'demo', + networkName: 'nocobase', + appResults: { + appPort: '13000', + storagePath: './storage/demo', + }, + downloadResults: { + source: 'docker', + version: 'latest', + }, + dbResults: { + dbDialect: 'postgres', + dbHost: '127.0.0.1', + dbPort: '5432', + dbDatabase: 'nocobase', + dbUser: 'nocobase', + dbPassword: 'nocobase', + }, + rootResults: { + rootUsername: 'nocobase', + rootEmail: 'admin@nocobase.com', + rootPassword: 'admin123', + rootNickname: 'Super Admin', + }, + }); + + expect(plan.imageRef).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase:latest-full-no-nginx'); + expect(plan.args.includes('13000:13000')).toBe(true); + expect(plan.args.includes('13000:80')).toBe(false); + } finally { + if (previousCliRoot === undefined) { + delete process.env.NB_CLI_ROOT; + } else { + process.env.NB_CLI_ROOT = previousCliRoot; + } + await rm(tempCliRoot, { recursive: true, force: true }); + } +}); + test('docker app plan enables NOCOBASE_EXTRACT_CLIENT_ASSETS by default', async () => { const installStatics = Install as unknown as InstallStatics; const plan = await installStatics.buildDockerAppPlan({ @@ -1253,7 +1301,9 @@ test('install does not seed built-in database host port for docker source or exp dbDialect: 'postgres', }, }), - ).toEqual({}); + ).toEqual({ + builtinDbImage: 'postgres:16', + }); expect( await installStatics.buildDbPromptInitialValues({ flags: { @@ -1267,7 +1317,9 @@ test('install does not seed built-in database host port for docker source or exp dbDialect: 'postgres', }, }), - ).toEqual({}); + ).toEqual({ + builtinDbImage: 'postgres:16', + }); }); test('install does not seed a built-in database host port for external db host presets', async () => { diff --git a/packages/core/cli/src/__tests__/prompt-validators.test.ts b/packages/core/cli/src/__tests__/prompt-validators.test.ts index 3ab115e9a50..1aa17adbfc0 100644 --- a/packages/core/cli/src/__tests__/prompt-validators.test.ts +++ b/packages/core/cli/src/__tests__/prompt-validators.test.ts @@ -16,6 +16,7 @@ import Download, { defaultDockerRegistryForLang } from '../commands/source/downl import Init from '../commands/init.js'; import EnvAdd from '../commands/env/add.js'; import Install from '../commands/install.js'; +import { setCliConfigValue } from '../lib/cli-config.js'; import { saveAuthConfig } from '../lib/auth-store.js'; import { resolveLocalizedText } from '../lib/cli-locale.js'; import { runPromptCatalog } from '../lib/prompt-catalog.js'; @@ -62,6 +63,23 @@ async function withTempProjectCwd(run: () => Promise) { } } +async function withTempCliHome(run: () => Promise) { + const previous = process.env.NB_CLI_ROOT; + const tempHome = await mkdtemp(path.join(os.tmpdir(), 'nocobase-cli-config-')); + + try { + process.env.NB_CLI_ROOT = tempHome; + await run(); + } finally { + if (previous === undefined) { + delete process.env.NB_CLI_ROOT; + } else { + process.env.NB_CLI_ROOT = previous; + } + await rm(tempHome, { recursive: true, force: true }); + } +} + const originalNbLocale = process.env.NB_LOCALE; beforeEach(() => { @@ -769,31 +787,25 @@ test('version prompt uses presets and reveals otherVersion when needed', () => { expect(otherVersionPrompt.hidden?.({ version: 'other' })).toBe(false); }); -test('builtin database image defaults follow NB_LOCALE', async () => { +test('builtin database image prompt defaults use dockerhub-compatible images by default', async () => { process.env.NB_LOCALE = 'zh-CN'; const { default: InstallWithZhLocale } = await import('../commands/install.js'); const builtinDbImagePrompt = InstallWithZhLocale.dbPrompts.builtinDbImage; - expect(builtinDbImagePrompt.initialValue?.({ dbDialect: 'postgres' })).toBe( - 'registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16', - ); - expect(builtinDbImagePrompt.initialValue?.({ dbDialect: 'mysql' })).toBe( - 'registry.cn-shanghai.aliyuncs.com/nocobase/mysql:8', - ); - expect(builtinDbImagePrompt.initialValue?.({ dbDialect: 'mariadb' })).toBe( - 'registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11', - ); + expect(builtinDbImagePrompt.initialValue?.({ dbDialect: 'postgres' })).toBe('postgres:16'); + expect(builtinDbImagePrompt.initialValue?.({ dbDialect: 'mysql' })).toBe('mysql:8'); + expect(builtinDbImagePrompt.initialValue?.({ dbDialect: 'mariadb' })).toBe('mariadb:11'); }); -test('install download prompt options follow CLI locale for docker registry defaults', () => { +test('install download prompt options follow nb image registry config for docker registry defaults', async () => { const installStatics = Install as unknown as { buildDownloadPromptOptionsForInstall: ( appResults: Record, envName: string, - ) => { + ) => Promise<{ initialValues: Record; values: Record; - }; + }>; buildDownloadPresetValuesForInstall: ( flags: Record, appResults: Record, @@ -803,30 +815,32 @@ test('install download prompt options follow CLI locale for docker registry defa buildPresetValuesFromFlags: (flags: Record) => Record; }; - process.env.NB_LOCALE = 'zh-CN'; - const zhOptions = installStatics.buildDownloadPromptOptionsForInstall( - { - lang: 'en-US', - appRootPath: './apps/zh-demo', - }, - 'zh-demo', - ); - expect(zhOptions.initialValues.lang).toBe('en-US'); - expect(zhOptions.initialValues.dockerRegistry).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase'); - expect(zhOptions.initialValues.outputDir).toBe('./apps/zh-demo'); - expect(zhOptions.values.lang).toBe('en-US'); + await withTempCliHome(async () => { + await setCliConfigValue('nb-image-registry', 'aliyun', { scope: 'global' }); + const aliyunOptions = await installStatics.buildDownloadPromptOptionsForInstall( + { + lang: 'en-US', + appRootPath: './apps/aliyun-demo', + }, + 'aliyun-demo', + ); + expect(aliyunOptions.initialValues.lang).toBe('en-US'); + expect(aliyunOptions.initialValues.dockerRegistry).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/nocobase'); + expect(aliyunOptions.initialValues.outputDir).toBe('./apps/aliyun-demo'); + expect(aliyunOptions.values.lang).toBe('en-US'); - process.env.NB_LOCALE = 'en-US'; - const enOptions = installStatics.buildDownloadPromptOptionsForInstall( - { - lang: 'zh-CN', - appRootPath: './apps/en-demo', - }, - 'en-demo', - ); - expect(enOptions.initialValues.lang).toBe('zh-CN'); - expect(enOptions.initialValues.dockerRegistry).toBe('nocobase/nocobase'); - expect(enOptions.values.lang).toBe('zh-CN'); + await setCliConfigValue('nb-image-registry', 'dockerhub', { scope: 'global' }); + const dockerhubOptions = await installStatics.buildDownloadPromptOptionsForInstall( + { + lang: 'zh-CN', + appRootPath: './apps/dockerhub-demo', + }, + 'dockerhub-demo', + ); + expect(dockerhubOptions.initialValues.lang).toBe('zh-CN'); + expect(dockerhubOptions.initialValues.dockerRegistry).toBe('nocobase/nocobase'); + expect(dockerhubOptions.values.lang).toBe('zh-CN'); + }); const originalArgv = process.argv; process.argv = ['node', 'nb', 'install', '--yes']; diff --git a/packages/core/cli/src/__tests__/prompt-web-ui.test.ts b/packages/core/cli/src/__tests__/prompt-web-ui.test.ts index 0e87660d131..bb0c56cf705 100644 --- a/packages/core/cli/src/__tests__/prompt-web-ui.test.ts +++ b/packages/core/cli/src/__tests__/prompt-web-ui.test.ts @@ -259,29 +259,32 @@ test('runPromptCatalogWebUI treats host as the browser URL host and listens on a test('buildWebFormValuesFromCatalog resolves function defaults for password fields', async () => { const { buildWebFormValuesFromCatalog } = await import('../lib/prompt-web-ui.js'); - const values = buildWebFormValuesFromCatalog({ - rootPassword: { - type: 'password', - message: 'Root password', - required: true, + const values = buildWebFormValuesFromCatalog( + { + rootPassword: { + type: 'password', + message: 'Root password', + required: true, + }, + authType: { + type: 'select', + message: 'Authentication type', + options: ['basic', 'oauth'], + initialValue: 'basic', + required: true, + }, + installPassword: { + type: 'password', + message: 'Install password', + required: true, + hidden: (currentValues) => currentValues.authType !== 'basic', + initialValue: (currentValues) => String(currentValues.rootPassword ?? ''), + }, }, - authType: { - type: 'select', - message: 'Authentication type', - options: ['basic', 'oauth'], - initialValue: 'basic', - required: true, + { + rootPassword: 'admin123', }, - installPassword: { - type: 'password', - message: 'Install password', - required: true, - hidden: (currentValues) => currentValues.authType !== 'basic', - initialValue: (currentValues) => String(currentValues.rootPassword ?? ''), - }, - }, { - rootPassword: 'admin123', - }); + ); expect(values.installPassword).toBe('admin123'); }); @@ -797,7 +800,7 @@ test('reflow recomputes the built-in database image from the current database di ); }); -test('reflow uses locale-aware built-in database images when NB_LOCALE is zh-CN', async () => { +test('reflow uses dockerhub-compatible built-in database images by default', async () => { process.env.NB_LOCALE = 'zh-CN'; const { reflowWebFormState } = await import('../lib/prompt-web-ui.js'); const { default: Init } = await import('../commands/init.js'); @@ -808,7 +811,7 @@ test('reflow uses locale-aware built-in database images when NB_LOCALE is zh-CN' builtinDb: true, }); - expect(state.values.builtinDbImage).toBe('registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16'); + expect(state.values.builtinDbImage).toBe('postgres:16'); }); test('reflow uses CLI locale-aware docker registry defaults even when app language is en-US', async () => { diff --git a/packages/core/cli/src/__tests__/proxy-caddy-command.test.ts b/packages/core/cli/src/__tests__/proxy-caddy-command.test.ts index 3c642e94303..fe7333b66e6 100644 --- a/packages/core/cli/src/__tests__/proxy-caddy-command.test.ts +++ b/packages/core/cli/src/__tests__/proxy-caddy-command.test.ts @@ -254,12 +254,12 @@ test('proxy caddy generate supports manual mode', async () => { flags: { manual: true, name: 'default', - 'app-port': '13000', 'storage-path': '/path/to/storage', 'dist-root-path': '/path/to/dist-client', 'runtime-version': '2.1.0', 'app-public-path': '/console/', 'upstream-host': 'host.docker.internal', + 'upstream-port': '14000', 'cdn-base-url': 'https://cdn.example.com/ui/', port: '8080', }, @@ -272,12 +272,12 @@ test('proxy caddy generate supports manual mode', async () => { expect(mocks.writeManualCaddyProxyBundle).toHaveBeenCalledWith( { name: 'default', - appPort: '13000', storagePath: '/path/to/storage', distRootPath: '/path/to/dist-client', runtimeVersion: '2.1.0', appPublicPath: '/console/', upstreamHost: 'host.docker.internal', + upstreamPort: '14000', cdnBaseUrl: 'https://cdn.example.com/ui/', }, { @@ -298,17 +298,17 @@ test('proxy caddy generate supports manual mode', async () => { ); }); -test('proxy caddy generate rejects invalid manual app port values', async () => { +test('proxy caddy generate rejects invalid manual upstream port values', async () => { const { default: ProxyCaddyGenerate } = await import('../commands/proxy/caddy/generate.js'); const command = Object.assign(Object.create(ProxyCaddyGenerate.prototype), { parse: vi.fn(async () => ({ flags: { manual: true, name: 'default', - 'app-port': '70000', 'storage-path': '/path/to/storage', 'dist-root-path': '/path/to/dist-client', 'runtime-version': '2.1.0', + 'upstream-port': '70000', }, })), error: vi.fn((message: string) => { @@ -317,7 +317,7 @@ test('proxy caddy generate rejects invalid manual app port values', async () => }); await expect(ProxyCaddyGenerate.prototype.run.call(command)).rejects.toThrow( - 'Invalid manual app port "70000". Use an integer between 1 and 65535.', + 'Invalid manual upstream port "70000". Use an integer between 1 and 65535.', ); expect(mocks.writeManualCaddyProxyBundle).not.toHaveBeenCalled(); }); diff --git a/packages/core/cli/src/__tests__/proxy-nginx-command.test.ts b/packages/core/cli/src/__tests__/proxy-nginx-command.test.ts index 2d96cf27c47..5285129c5fb 100644 --- a/packages/core/cli/src/__tests__/proxy-nginx-command.test.ts +++ b/packages/core/cli/src/__tests__/proxy-nginx-command.test.ts @@ -256,12 +256,12 @@ test('proxy nginx generate supports manual mode', async () => { flags: { manual: true, name: 'default', - 'app-port': '13000', 'storage-path': '/path/to/storage', 'dist-root-path': '/path/to/dist-client', 'runtime-version': '2.1.0', 'app-public-path': '/console/', 'upstream-host': 'host.docker.internal', + 'upstream-port': '14000', 'cdn-base-url': 'https://cdn.example.com/ui/', port: '8080', force: true, @@ -275,12 +275,12 @@ test('proxy nginx generate supports manual mode', async () => { expect(mocks.writeManualNginxProxyBundle).toHaveBeenCalledWith( { name: 'default', - appPort: '13000', storagePath: '/path/to/storage', distRootPath: '/path/to/dist-client', runtimeVersion: '2.1.0', appPublicPath: '/console/', upstreamHost: 'host.docker.internal', + upstreamPort: '14000', cdnBaseUrl: 'https://cdn.example.com/ui/', }, { @@ -301,17 +301,17 @@ test('proxy nginx generate supports manual mode', async () => { ); }); -test('proxy nginx generate rejects invalid manual app port values', async () => { +test('proxy nginx generate rejects invalid manual upstream port values', async () => { const { default: ProxyNginxGenerate } = await import('../commands/proxy/nginx/generate.js'); const command = Object.assign(Object.create(ProxyNginxGenerate.prototype), { parse: vi.fn(async () => ({ flags: { manual: true, name: 'default', - 'app-port': '70000', 'storage-path': '/path/to/storage', 'dist-root-path': '/path/to/dist-client', 'runtime-version': '2.1.0', + 'upstream-port': '70000', }, })), error: vi.fn((message: string) => { @@ -320,7 +320,7 @@ test('proxy nginx generate rejects invalid manual app port values', async () => }); await expect(ProxyNginxGenerate.prototype.run.call(command)).rejects.toThrow( - 'Invalid manual app port "70000". Use an integer between 1 and 65535.', + 'Invalid manual upstream port "70000". Use an integer between 1 and 65535.', ); expect(mocks.writeManualNginxProxyBundle).not.toHaveBeenCalled(); }); diff --git a/packages/core/cli/src/commands/install.ts b/packages/core/cli/src/commands/install.ts index c4c637b88f9..005a6cb42d3 100644 --- a/packages/core/cli/src/commands/install.ts +++ b/packages/core/cli/src/commands/install.ts @@ -35,8 +35,22 @@ import { defaultDockerNetworkName, managedAppLifecycleEnvVars, } from '../lib/app-runtime.js'; -import { resolveDefaultApiHost, resolveDockerContainerPrefix, resolveDockerNetworkName } from '../lib/cli-config.js'; -import { DEFAULT_DOCKER_VERSION, resolveDockerImageRef } from '../lib/docker-image.ts'; +import { + getCliConfigValue, + resolveDefaultApiHost, + resolveDockerContainerPrefix, + resolveDockerNetworkName, +} from '../lib/cli-config.js'; +import { + DEFAULT_DOCKER_VERSION, + DEFAULT_NB_IMAGE_VARIANT, + inferNbImageRegistryFromRepository, + normalizeNbImageVariant, + resolveBuiltinDbImage, + resolveDockerImageContainerPort, + resolveDockerImageRef, + resolveOfficialDockerRegistry, +} from '../lib/docker-image.ts'; import { findAvailableTcpPort, validateAppPublicPath, @@ -82,18 +96,6 @@ const DEFAULT_INSTALL_DB_PORTS = { mariadb: '3306', kingbase: '54321', } as const; -const DEFAULT_INSTALL_BUILTIN_DB_IMAGES = { - postgres: 'postgres:16', - mysql: 'mysql:8', - mariadb: 'mariadb:11', - kingbase: 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86', -} as const; -const DEFAULT_INSTALL_BUILTIN_DB_IMAGES_ZH_CN = { - postgres: 'registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16', - mysql: 'registry.cn-shanghai.aliyuncs.com/nocobase/mysql:8', - mariadb: 'registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11', - kingbase: 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86', -} as const; const DEFAULT_INSTALL_DB_DATABASE = 'nocobase'; const DEFAULT_INSTALL_DB_USER = 'nocobase'; const DEFAULT_INSTALL_DB_PASSWORD = 'nocobase'; @@ -231,11 +233,9 @@ function downloadVersionPromptValue(version: string): 'latest' | 'beta' | 'alpha return version === 'latest' || version === 'beta' || version === 'alpha' ? version : 'other'; } -function supportsBuiltinDbDialect( - value: PromptValue | undefined, -): value is keyof typeof DEFAULT_INSTALL_BUILTIN_DB_IMAGES { +function supportsBuiltinDbDialect(value: PromptValue | undefined): value is (typeof INSTALL_DB_DIALECTS)[number] { const dialect = String(value ?? '').trim(); - return Object.prototype.hasOwnProperty.call(DEFAULT_INSTALL_BUILTIN_DB_IMAGES, dialect); + return (INSTALL_DB_DIALECTS as readonly string[]).includes(dialect); } export function defaultDbPortForDialect(value: PromptValue | undefined): string { @@ -243,13 +243,9 @@ export function defaultDbPortForDialect(value: PromptValue | undefined): string return DEFAULT_INSTALL_DB_PORTS[isInstallDbDialect(dialect) ? dialect : 'postgres']; } -function defaultBuiltinDbImageForDialect(value: PromptValue | undefined): string { +function defaultBuiltinDbImageForDialect(value: PromptValue | undefined, options?: { registry?: string }): string { const dialect = String(value ?? 'postgres').trim(); - const defaults = - resolveCliLocale(process.env.NB_LOCALE) === 'zh-CN' - ? DEFAULT_INSTALL_BUILTIN_DB_IMAGES_ZH_CN - : DEFAULT_INSTALL_BUILTIN_DB_IMAGES; - return supportsBuiltinDbDialect(dialect) ? defaults[dialect] : defaults.postgres; + return resolveBuiltinDbImage(dialect, { registry: options?.registry }); } function defaultDbDatabaseForDialect(value: PromptValue | undefined): string { @@ -1667,21 +1663,30 @@ export default class Install extends Command { dbPreset: PromptInitialValues; warnOnPortFallback?: boolean; }): Promise { - if (params.flags['db-port'] !== undefined) { - return {}; - } - + const configuredRegistry = await getCliConfigValue('nb-image-registry'); const values = { ...params.downloadResults, ...params.dbPreset, } as Record; + const dockerRegistry = + String(values.dockerRegistry ?? '').trim() || resolveOfficialDockerRegistry(configuredRegistry); + const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres'; + const initialValues: PromptInitialValues = + values.builtinDb !== false && params.dbPreset.builtinDbImage === undefined + ? { builtinDbImage: defaultBuiltinDbImageForDialect(dialect, { registry: dockerRegistry }) } + : {}; + + if (params.flags['db-port'] !== undefined) { + return initialValues; + } + if (!Install.shouldPublishBuiltinDbPortForValues(values)) { - return {}; + return initialValues; } - const dialect = String(values.dbDialect ?? 'postgres').trim() || 'postgres'; const defaultPort = defaultDbPortForDialect(dialect); return { + ...initialValues, dbPort: await Install.resolveAvailableDefaultPort(defaultPort, { label: `Default ${dialect} port`, warn: params.warnOnPortFallback ?? true, @@ -1693,15 +1698,16 @@ export default class Install extends Command { * When install runs {@link Download.prompts} after app prompts, align the download * output directory with app settings, while Docker registry defaults follow the CLI locale. */ - private static buildDownloadPromptOptionsForInstall( + private static async buildDownloadPromptOptionsForInstall( appResults: Record, envName: string, - ): RunPromptCatalogOptions { + ): Promise { const appRoot = resolveConfiguredSourcePathValue(appResults, envName); const lang = String(appResults.lang ?? DEFAULT_INSTALL_LANG).trim() || DEFAULT_INSTALL_LANG; + const dockerRegistry = resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry')); const initialValues: PromptInitialValues = { lang, - dockerRegistry: defaultDockerRegistryForLang(process.env.NB_LOCALE), + dockerRegistry, outputDir: appRoot, }; @@ -2293,14 +2299,18 @@ export default class Install extends Command { rootResults: Record; networkName: string; }): Promise { + const configuredRegistry = await getCliConfigValue('nb-image-registry'); + const configuredVariant = + normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT; const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() || - defaultDockerRegistryForLang(process.env.NB_LOCALE); + resolveOfficialDockerRegistry(configuredRegistry); const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION; const imageRef = resolveDockerImageRef(dockerRegistry, version, { - defaultRegistry: defaultDockerRegistryForLang(process.env.NB_LOCALE), + defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry), defaultVersion: DEFAULT_DOCKER_VERSION, + variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined, }); const appPort = String(params.appResults.appPort ?? DEFAULT_INSTALL_APP_PORT).trim() || DEFAULT_INSTALL_APP_PORT; const configuredStoragePath = resolveConfiguredStoragePathValue(params.appResults, params.envName); @@ -2337,6 +2347,7 @@ export default class Install extends Command { appResults: params.appResults, rootResults: params.rootResults, }); + const containerPort = resolveDockerImageContainerPort(imageRef); const args = [ 'run', '-d', @@ -2345,7 +2356,7 @@ export default class Install extends Command { '--network', params.networkName, '-p', - `${appPort}:80`, + `${appPort}:${containerPort}`, ]; if (envFile) { @@ -2636,14 +2647,18 @@ export default class Install extends Command { downloadResults: Record; }): Promise { if (params.source === 'docker') { + const configuredRegistry = await getCliConfigValue('nb-image-registry'); + const configuredVariant = + normalizeNbImageVariant(await getCliConfigValue('nb-image-variant')) ?? DEFAULT_NB_IMAGE_VARIANT; const dockerRegistry = String(downloadResultsValue(params.downloadResults, 'dockerRegistry') ?? '').trim() || - defaultDockerRegistryForLang(process.env.NB_LOCALE); + resolveOfficialDockerRegistry(configuredRegistry); const version = String(downloadResultsValue(params.downloadResults, 'version') ?? '').trim() || DEFAULT_DOCKER_VERSION; const imageRef = resolveDockerImageRef(dockerRegistry, version, { - defaultRegistry: defaultDockerRegistryForLang(process.env.NB_LOCALE), + defaultRegistry: resolveOfficialDockerRegistry(configuredRegistry), defaultVersion: DEFAULT_DOCKER_VERSION, + variant: inferNbImageRegistryFromRepository(dockerRegistry) ? configuredVariant : undefined, }); const imageExists = await commandSucceeds('docker', ['image', 'inspect', imageRef]); if (!imageExists) { @@ -3164,7 +3179,7 @@ export default class Install extends Command { appResults.hookScript = resumePreset.appPreset.hookScript; } - const downloadOpts = Install.buildDownloadPromptOptionsForInstall(appResults, envName); + const downloadOpts = await Install.buildDownloadPromptOptionsForInstall(appResults, envName); downloadOpts.values = { ...(resumePreset?.downloadPreset ?? {}), ...downloadOpts.values, diff --git a/packages/core/cli/src/commands/proxy/caddy/generate.ts b/packages/core/cli/src/commands/proxy/caddy/generate.ts index 0fa3e371a60..6a1d1de74e6 100644 --- a/packages/core/cli/src/commands/proxy/caddy/generate.ts +++ b/packages/core/cli/src/commands/proxy/caddy/generate.ts @@ -30,7 +30,7 @@ export default class ProxyCaddyGenerate extends Command { '<%= config.bin %> proxy caddy generate --host app1.example.com', '<%= config.bin %> proxy caddy generate --env app1 --host app1.example.com', '<%= config.bin %> proxy caddy generate --env app1 --host app1.example.com --port 8080', - '<%= config.bin %> proxy caddy generate --manual --name default --app-port 13000 --storage-path /path/to/storage --dist-root-path /path/to/dist-client --runtime-version 2.1.0', + '<%= config.bin %> proxy caddy generate --manual --name default --storage-path /path/to/storage --dist-root-path /path/to/dist-client --runtime-version 2.1.0 --upstream-port 13000', ]; static override flags = { @@ -45,9 +45,6 @@ export default class ProxyCaddyGenerate extends Command { name: Flags.string({ description: 'Output bundle name used under .nocobase/proxy/caddy in manual mode', }), - 'app-port': Flags.string({ - description: 'Upstream NocoBase app port in manual mode', - }), 'storage-path': Flags.string({ description: 'Path to the NocoBase storage directory in manual mode', }), @@ -64,6 +61,9 @@ export default class ProxyCaddyGenerate extends Command { 'upstream-host': Flags.string({ description: 'Upstream host used by caddy reverse_proxy in manual mode', }), + 'upstream-port': Flags.string({ + description: 'Upstream port used by caddy reverse_proxy in manual mode', + }), 'cdn-base-url': Flags.string({ description: 'Client asset CDN base URL used when generating runtime HTML', }), @@ -92,19 +92,19 @@ export default class ProxyCaddyGenerate extends Command { if (manual) { const name = flags.name?.trim() || undefined; - const requestedAppPort = flags['app-port']?.trim() || undefined; - const appPort = normalizeProxyListenPort(requestedAppPort); + const requestedUpstreamPort = flags['upstream-port']?.trim() || undefined; + const upstreamPort = normalizeProxyListenPort(requestedUpstreamPort); const storagePath = flags['storage-path']?.trim() || undefined; const distRootPath = flags['dist-root-path']?.trim() || undefined; const runtimeVersion = flags['runtime-version']?.trim() || undefined; - if (requestedAppPort && !appPort) { - this.error(`Invalid manual app port "${requestedAppPort}". Use an integer between 1 and 65535.`); + if (requestedUpstreamPort && !upstreamPort) { + this.error(`Invalid manual upstream port "${requestedUpstreamPort}". Use an integer between 1 and 65535.`); } - if (!name || !appPort || !storagePath || !distRootPath || !runtimeVersion) { + if (!name || !upstreamPort || !storagePath || !distRootPath || !runtimeVersion) { this.error( - 'Manual mode requires `--name`, `--app-port`, `--storage-path`, `--dist-root-path`, and `--runtime-version`.', + 'Manual mode requires `--name`, `--upstream-port`, `--storage-path`, `--dist-root-path`, and `--runtime-version`.', ); } @@ -117,12 +117,12 @@ export default class ProxyCaddyGenerate extends Command { const { bundle, status } = await writeManualCaddyProxyBundle( { name, - appPort, storagePath, distRootPath, runtimeVersion, appPublicPath: flags['app-public-path']?.trim() || undefined, upstreamHost: flags['upstream-host']?.trim() || undefined, + upstreamPort, cdnBaseUrl: flags['cdn-base-url']?.trim() || undefined, }, { diff --git a/packages/core/cli/src/commands/proxy/nginx/generate.ts b/packages/core/cli/src/commands/proxy/nginx/generate.ts index fe22e426e8b..ceb36dd5f2f 100644 --- a/packages/core/cli/src/commands/proxy/nginx/generate.ts +++ b/packages/core/cli/src/commands/proxy/nginx/generate.ts @@ -30,7 +30,7 @@ export default class ProxyNginxGenerate extends Command { '<%= config.bin %> proxy nginx generate --host app1.example.com', '<%= config.bin %> proxy nginx generate --env app1 --host app1.example.com', '<%= config.bin %> proxy nginx generate --env app1 --host app1.example.com --port 8080', - '<%= config.bin %> proxy nginx generate --manual --name default --app-port 13000 --storage-path /path/to/storage --dist-root-path /path/to/dist-client --runtime-version 2.1.0', + '<%= config.bin %> proxy nginx generate --manual --name default --storage-path /path/to/storage --dist-root-path /path/to/dist-client --runtime-version 2.1.0 --upstream-port 13000', ]; static override flags = { @@ -45,9 +45,6 @@ export default class ProxyNginxGenerate extends Command { name: Flags.string({ description: 'Output bundle name used under .nocobase/proxy/nginx in manual mode', }), - 'app-port': Flags.string({ - description: 'Upstream NocoBase app port in manual mode', - }), 'storage-path': Flags.string({ description: 'Path to the NocoBase storage directory in manual mode', }), @@ -64,6 +61,9 @@ export default class ProxyNginxGenerate extends Command { 'upstream-host': Flags.string({ description: 'Upstream host used by nginx proxy_pass in manual mode', }), + 'upstream-port': Flags.string({ + description: 'Upstream port used by nginx proxy_pass in manual mode', + }), 'cdn-base-url': Flags.string({ description: 'Client asset CDN base URL used when generating runtime HTML', }), @@ -96,19 +96,19 @@ export default class ProxyNginxGenerate extends Command { if (manual) { const name = flags.name?.trim() || undefined; - const requestedAppPort = flags['app-port']?.trim() || undefined; - const appPort = normalizeProxyListenPort(requestedAppPort); + const requestedUpstreamPort = flags['upstream-port']?.trim() || undefined; + const upstreamPort = normalizeProxyListenPort(requestedUpstreamPort); const storagePath = flags['storage-path']?.trim() || undefined; const distRootPath = flags['dist-root-path']?.trim() || undefined; const runtimeVersion = flags['runtime-version']?.trim() || undefined; - if (requestedAppPort && !appPort) { - this.error(`Invalid manual app port "${requestedAppPort}". Use an integer between 1 and 65535.`); + if (requestedUpstreamPort && !upstreamPort) { + this.error(`Invalid manual upstream port "${requestedUpstreamPort}". Use an integer between 1 and 65535.`); } - if (!name || !appPort || !storagePath || !distRootPath || !runtimeVersion) { + if (!name || !upstreamPort || !storagePath || !distRootPath || !runtimeVersion) { this.error( - 'Manual mode requires `--name`, `--app-port`, `--storage-path`, `--dist-root-path`, and `--runtime-version`.', + 'Manual mode requires `--name`, `--upstream-port`, `--storage-path`, `--dist-root-path`, and `--runtime-version`.', ); } @@ -121,12 +121,12 @@ export default class ProxyNginxGenerate extends Command { const { bundle, status } = await writeManualNginxProxyBundle( { name, - appPort, storagePath, distRootPath, runtimeVersion, appPublicPath: flags['app-public-path']?.trim() || undefined, upstreamHost: flags['upstream-host']?.trim() || undefined, + upstreamPort, cdnBaseUrl: flags['cdn-base-url']?.trim() || undefined, }, { diff --git a/packages/core/cli/src/commands/source/download.ts b/packages/core/cli/src/commands/source/download.ts index ce5f3d0e846..1ff1d0768cc 100644 --- a/packages/core/cli/src/commands/source/download.ts +++ b/packages/core/cli/src/commands/source/download.ts @@ -29,10 +29,12 @@ import { import { DEFAULT_DOCKER_REGISTRY, DEFAULT_DOCKER_REGISTRY_ZH_CN, + resolveOfficialDockerRegistry, resolveDockerImageRef, } from '../../lib/docker-image.ts'; import { getEnv } from '../../lib/auth-store.js'; import { resolveDefaultConfigScope } from '../../lib/cli-home.js'; +import { getCliConfigValue } from '../../lib/cli-config.js'; import { buildBeforeDependencyInstallHookContext, runBeforeDependencyInstallHook, @@ -578,9 +580,9 @@ export default class SourceDownload extends Command { return outputAbs; } - private dockerTarPath(flags: DownloadResolvedFlags, outputAbs: string): string { + private async dockerTarPath(flags: DownloadResolvedFlags, outputAbs: string): Promise { const imageRef = resolveDockerImageRef(flags['docker-registry'], flags.version, { - defaultRegistry: defaultDockerRegistryForLang(process.env.NB_LOCALE), + defaultRegistry: await this.resolveConfiguredDockerRegistryDefault(), defaultVersion: 'latest', }); const safeBase = imageRef.replace(/[\\/:]/g, '-'); @@ -591,9 +593,16 @@ export default class SourceDownload extends Command { * Defaults for prompts only. Keys present in **`preset`** are omitted so `runPromptCatalog` uses * **`values`** (preset) alone for those steps — no duplicate prefill for skipped prompts. */ - private buildInitialValuesFromParsed(flags: DownloadParsedFlags, preset: PromptInitialValues): PromptInitialValues { + private async resolveConfiguredDockerRegistryDefault(): Promise { + return resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry')); + } + + private buildInitialValuesFromParsed( + flags: DownloadParsedFlags, + preset: PromptInitialValues, + defaultDockerRegistry: string, + ): PromptInitialValues { const initialValues: PromptInitialValues = {}; - const localeDefaultDockerRegistry = defaultDockerRegistryForLang(flags.locale ?? process.env.NB_LOCALE); const source = flags.source?.trim(); if (source) { @@ -622,7 +631,7 @@ export default class SourceDownload extends Command { if (flags['docker-registry'] !== undefined) { initialValues.dockerRegistry = String(flags['docker-registry'] ?? '').trim(); } else { - initialValues.dockerRegistry = localeDefaultDockerRegistry; + initialValues.dockerRegistry = defaultDockerRegistry; } initialValues.dockerPlatform = normalizeDockerPlatform(flags['docker-platform']); @@ -731,6 +740,7 @@ export default class SourceDownload extends Command { private mapCatalogResultsToResolved( results: Record, flags: DownloadParsedFlags, + defaultDockerRegistry: string, ): DownloadResolvedFlags { const source = String(results.source) as DownloadSource; const version = resolveVersionFromResults(results, flags.version) || 'latest'; @@ -754,7 +764,7 @@ export default class SourceDownload extends Command { source === 'docker' ? results.dockerRegistry !== undefined ? String(results.dockerRegistry).trim() || undefined - : flags['docker-registry']?.trim() || defaultDockerRegistryForLang(flags.locale ?? process.env.NB_LOCALE) + : flags['docker-registry']?.trim() || defaultDockerRegistry : undefined; const dockerPlatform = @@ -813,7 +823,8 @@ export default class SourceDownload extends Command { } const presetValues = this.buildPresetValuesFromFlags(flags); - const initialValues = this.buildInitialValuesFromParsed(flags, presetValues); + const defaultDockerRegistry = await this.resolveConfiguredDockerRegistryDefault(); + const initialValues = this.buildInitialValuesFromParsed(flags, presetValues, defaultDockerRegistry); const results = await runPromptCatalog(SourceDownload.prompts, { initialValues, @@ -844,7 +855,7 @@ export default class SourceDownload extends Command { this.error('--docker-save is only available when --source docker is selected.'); } - return this.mapCatalogResultsToResolved(results, flags); + return this.mapCatalogResultsToResolved(results, flags, defaultDockerRegistry); } private npmRegistryUrl(flags: DownloadResolvedFlags): string | undefined { @@ -1005,7 +1016,7 @@ export default class SourceDownload extends Command { async downloadFromDocker(flags: DownloadResolvedFlags): Promise { const imageRef = resolveDockerImageRef(flags['docker-registry'], flags.version, { - defaultRegistry: defaultDockerRegistryForLang(process.env.NB_LOCALE), + defaultRegistry: await this.resolveConfiguredDockerRegistryDefault(), defaultVersion: 'latest', }); const platform = dockerPlatformArg(flags['docker-platform']); @@ -1034,7 +1045,7 @@ export default class SourceDownload extends Command { await fsp.rm(outAbs, { recursive: true, force: true }); } await fsp.mkdir(outAbs, { recursive: true }); - const tarPath = this.dockerTarPath(flags, outAbs); + const tarPath = await this.dockerTarPath(flags, outAbs); this.log(`Saving Docker image tarball to ${tarPath}`); await this.runExternalCommand('docker', ['save', '-o', tarPath, imageRef], { errorName: 'docker save', diff --git a/packages/core/cli/src/lib/app-managed-resources.ts b/packages/core/cli/src/lib/app-managed-resources.ts index b75bd0f4615..800b0b61b57 100644 --- a/packages/core/cli/src/lib/app-managed-resources.ts +++ b/packages/core/cli/src/lib/app-managed-resources.ts @@ -24,6 +24,7 @@ import { resolveDockerEnvFileArg } from './docker-env-file.ts'; import { DEFAULT_DOCKER_REGISTRY, DEFAULT_DOCKER_VERSION, + resolveDockerImageContainerPort, resolveDockerImageRef, } from './docker-image.ts'; import { resolveHookScriptPath, type HookCommand, type HookPhase } from './hook-script.js'; @@ -250,6 +251,7 @@ export async function buildSavedDockerRunArgs( defaultRegistry: DEFAULT_DOCKER_REGISTRY, defaultVersion: DEFAULT_DOCKER_VERSION, }); + const containerPort = resolveDockerImageContainerPort(imageRef); const missing: string[] = []; if (!storagePath) { @@ -296,7 +298,7 @@ export async function buildSavedDockerRunArgs( } if (appPort) { - args.push('-p', `${appPort}:80`); + args.push('-p', `${appPort}:${containerPort}`); } if (envFile) { diff --git a/packages/core/cli/src/lib/auth-store.ts b/packages/core/cli/src/lib/auth-store.ts index 47365a3aefc..49199f01c17 100644 --- a/packages/core/cli/src/lib/auth-store.ts +++ b/packages/core/cli/src/lib/auth-store.ts @@ -139,6 +139,8 @@ export interface AuthConfig { docker?: { network?: string; containerPrefix?: string; + nbImageRegistry?: string; + nbImageVariant?: string; }; bin?: { docker?: string; @@ -316,12 +318,19 @@ function normalizeAuthConfig(config: AuthConfig & { dockerResourcePrefix?: strin ...(updatePolicy ? { update: { policy: updatePolicy } } : {}), ...(settings.license?.pkgUrl ? { license: { pkgUrl: normalizeOptionalString(settings.license.pkgUrl) } } : {}), ...(settings.docker?.network || settings.docker?.containerPrefix + || settings.docker?.nbImageRegistry || settings.docker?.nbImageVariant ? { docker: { ...(settings.docker?.network ? { network: normalizeOptionalString(settings.docker.network) } : {}), ...(settings.docker?.containerPrefix ? { containerPrefix: normalizeOptionalString(settings.docker.containerPrefix) } : {}), + ...(settings.docker?.nbImageRegistry + ? { nbImageRegistry: normalizeOptionalString(settings.docker.nbImageRegistry) } + : {}), + ...(settings.docker?.nbImageVariant + ? { nbImageVariant: normalizeOptionalString(settings.docker.nbImageVariant) } + : {}), }, } : {}), diff --git a/packages/core/cli/src/lib/cli-config.ts b/packages/core/cli/src/lib/cli-config.ts index a7f2879ec8e..a827a056a6c 100644 --- a/packages/core/cli/src/lib/cli-config.ts +++ b/packages/core/cli/src/lib/cli-config.ts @@ -11,6 +11,16 @@ import type { AuthConfig, AuthStoreOptions } from './auth-store.js'; import { loadExactAuthConfig, saveAuthConfig } from './auth-store.js'; import { resolveCliHomeRoot, resolveDefaultConfigScope } from './cli-home.js'; import { CLI_LOCALE_FLAG_OPTIONS, normalizeCliLocale, resolveCliLocale } from './cli-locale.js'; +import { + DEFAULT_NB_IMAGE_REGISTRY, + DEFAULT_NB_IMAGE_VARIANT, + NB_IMAGE_REGISTRY_OPTIONS, + NB_IMAGE_VARIANT_OPTIONS, + normalizeNbImageRegistry, + normalizeNbImageVariant, + type NbImageRegistry, + type NbImageVariant, +} from './docker-image.js'; export const DEFAULT_LICENSE_PKG_URL = 'https://pkg.nocobase.com/'; export const DEFAULT_DOCKER_NETWORK = 'nocobase'; @@ -45,6 +55,8 @@ export const SUPPORTED_CLI_CONFIG_KEYS = [ 'license.pkg-url', 'docker.network', 'docker.container-prefix', + 'nb-image-registry', + 'nb-image-variant', 'bin.docker', 'bin.caddy', 'bin.git', @@ -159,7 +171,13 @@ function pruneSettings(config: AuthConfig): void { } const docker = config.settings?.docker; - if (docker && !trimValue(docker.network) && !trimValue(docker.containerPrefix)) { + if ( + docker && + !trimValue(docker.network) && + !trimValue(docker.containerPrefix) && + !trimValue(docker.nbImageRegistry) && + !trimValue(docker.nbImageVariant) + ) { delete config.settings?.docker; } @@ -223,6 +241,10 @@ export function getExplicitCliConfigValue(config: AuthConfig, key: SupportedCliC return trimValue(config.settings?.docker?.network); case 'docker.container-prefix': return trimValue(config.settings?.docker?.containerPrefix); + case 'nb-image-registry': + return normalizeNbImageRegistry(config.settings?.docker?.nbImageRegistry); + case 'nb-image-variant': + return normalizeNbImageVariant(config.settings?.docker?.nbImageVariant); case 'bin.docker': return trimValue(config.settings?.bin?.docker); case 'bin.caddy': @@ -273,6 +295,10 @@ export function getEffectiveCliConfigValue(config: AuthConfig, key: SupportedCli return trimValue(config.name) || DEFAULT_DOCKER_NETWORK; case 'docker.container-prefix': return trimValue(config.name) || DEFAULT_DOCKER_CONTAINER_PREFIX; + case 'nb-image-registry': + return explicit ?? DEFAULT_NB_IMAGE_REGISTRY; + case 'nb-image-variant': + return explicit ?? DEFAULT_NB_IMAGE_VARIANT; case 'bin.docker': return DEFAULT_DOCKER_BIN; case 'bin.caddy': @@ -363,6 +389,24 @@ export function normalizeCliConfigValue(key: SupportedCliConfigKey, value: strin return driver; } + if (key === 'nb-image-registry') { + const registry = normalizeNbImageRegistry(normalized); + if (!registry) { + throw new Error(`Config key "${key}" must be one of: ${NB_IMAGE_REGISTRY_OPTIONS.join(', ')}`); + } + + return registry; + } + + if (key === 'nb-image-variant') { + const variant = normalizeNbImageVariant(normalized); + if (!variant) { + throw new Error(`Config key "${key}" must be one of: ${NB_IMAGE_VARIANT_OPTIONS.join(', ')}`); + } + + return variant; + } + return normalized; } @@ -441,6 +485,18 @@ export async function setCliConfigValue( containerPrefix: normalized, }; break; + case 'nb-image-registry': + config.settings.docker = { + ...(config.settings.docker ?? {}), + nbImageRegistry: normalized as NbImageRegistry, + }; + break; + case 'nb-image-variant': + config.settings.docker = { + ...(config.settings.docker ?? {}), + nbImageVariant: normalized as NbImageVariant, + }; + break; case 'bin.docker': config.settings.bin = { ...(config.settings.bin ?? {}), @@ -567,6 +623,16 @@ export async function deleteCliConfigValue( delete config.settings.docker.containerPrefix; } break; + case 'nb-image-registry': + if (config.settings.docker) { + delete config.settings.docker.nbImageRegistry; + } + break; + case 'nb-image-variant': + if (config.settings.docker) { + delete config.settings.docker.nbImageVariant; + } + break; case 'bin.docker': if (config.settings.bin) { delete config.settings.bin.docker; diff --git a/packages/core/cli/src/lib/docker-image.ts b/packages/core/cli/src/lib/docker-image.ts index 6324ba8d6dc..92b35546cf8 100644 --- a/packages/core/cli/src/lib/docker-image.ts +++ b/packages/core/cli/src/lib/docker-image.ts @@ -10,7 +10,36 @@ export const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase'; export const DEFAULT_DOCKER_REGISTRY_ZH_CN = 'registry.cn-shanghai.aliyuncs.com/nocobase/nocobase'; export const DEFAULT_DOCKER_VERSION = 'alpha'; +export const NB_IMAGE_REGISTRY_OPTIONS = ['dockerhub', 'aliyun'] as const; +export type NbImageRegistry = (typeof NB_IMAGE_REGISTRY_OPTIONS)[number]; +export const DEFAULT_NB_IMAGE_REGISTRY: NbImageRegistry = 'dockerhub'; +export const NB_IMAGE_VARIANT_OPTIONS = ['standard', 'no-nginx', 'full', 'full-no-nginx'] as const; +export type NbImageVariant = (typeof NB_IMAGE_VARIANT_OPTIONS)[number]; +export const DEFAULT_NB_IMAGE_VARIANT: NbImageVariant = 'full'; export const DOCKER_IMAGE_FULL_SUFFIX = '-full'; +export const DOCKER_IMAGE_NO_NGINX_SUFFIX = '-no-nginx'; +export const DOCKER_IMAGE_FULL_NO_NGINX_SUFFIX = '-full-no-nginx'; +export const DEFAULT_KINGBASE_IMAGE = + 'registry.cn-shanghai.aliyuncs.com/nocobase/kingbase:v009r001c001b0030_single_x86'; + +const OFFICIAL_DOCKER_REGISTRY_REPOSITORIES: Record = { + dockerhub: DEFAULT_DOCKER_REGISTRY, + aliyun: DEFAULT_DOCKER_REGISTRY_ZH_CN, +}; + +const DEFAULT_BUILTIN_DB_IMAGES: Record = { + postgres: 'postgres:16', + mysql: 'mysql:8', + mariadb: 'mariadb:11', + kingbase: DEFAULT_KINGBASE_IMAGE, +}; + +const ALIYUN_BUILTIN_DB_IMAGES: Record = { + postgres: 'registry.cn-shanghai.aliyuncs.com/nocobase/postgres:16', + mysql: 'registry.cn-shanghai.aliyuncs.com/nocobase/mysql:8', + mariadb: 'registry.cn-shanghai.aliyuncs.com/nocobase/mariadb:11', + kingbase: DEFAULT_KINGBASE_IMAGE, +}; const OFFICIAL_FULL_IMAGE_REGISTRIES = new Set([ DEFAULT_DOCKER_REGISTRY, @@ -21,27 +50,118 @@ function trimValue(value: unknown): string { return String(value ?? '').trim(); } +export function normalizeNbImageRegistry(value: unknown): NbImageRegistry | undefined { + const normalized = trimValue(value); + if (!normalized) { + return undefined; + } + + return (NB_IMAGE_REGISTRY_OPTIONS as readonly string[]).includes(normalized) + ? (normalized as NbImageRegistry) + : undefined; +} + +export function normalizeNbImageVariant(value: unknown): NbImageVariant | undefined { + const normalized = trimValue(value); + if (!normalized) { + return undefined; + } + + return (NB_IMAGE_VARIANT_OPTIONS as readonly string[]).includes(normalized) + ? (normalized as NbImageVariant) + : undefined; +} + +export function resolveOfficialDockerRegistry(value?: unknown): string { + const registry = normalizeNbImageRegistry(value) ?? DEFAULT_NB_IMAGE_REGISTRY; + return OFFICIAL_DOCKER_REGISTRY_REPOSITORIES[registry]; +} + +export function inferNbImageRegistryFromRepository(value: unknown): NbImageRegistry | undefined { + const repository = trimValue(value); + return (Object.entries(OFFICIAL_DOCKER_REGISTRY_REPOSITORIES) as Array<[NbImageRegistry, string]>).find( + ([, candidate]) => candidate === repository, + )?.[0]; +} + +function hasKnownVariantSuffix(tag: string): boolean { + return ( + tag.endsWith(DOCKER_IMAGE_FULL_NO_NGINX_SUFFIX) || + tag.endsWith(DOCKER_IMAGE_NO_NGINX_SUFFIX) || + tag.endsWith(DOCKER_IMAGE_FULL_SUFFIX) + ); +} + export function shouldUseFullDockerImageTag(registry: unknown): boolean { return OFFICIAL_FULL_IMAGE_REGISTRIES.has(trimValue(registry)); } -export function normalizeDockerImageTag(registry: unknown, version: unknown): string { +export function normalizeDockerImageTag( + registry: unknown, + version: unknown, + options?: { variant?: NbImageVariant; defaultVariant?: NbImageVariant }, +): string { const tag = trimValue(version) || DEFAULT_DOCKER_VERSION; - if (!shouldUseFullDockerImageTag(registry)) { + if (hasKnownVariantSuffix(tag)) { return tag; } - return tag.endsWith(DOCKER_IMAGE_FULL_SUFFIX) - ? tag - : `${tag}${DOCKER_IMAGE_FULL_SUFFIX}`; + + const explicitVariant = normalizeNbImageVariant(options?.variant) ?? normalizeNbImageVariant(options?.defaultVariant); + const inferredVariant = shouldUseFullDockerImageTag(registry) ? DEFAULT_NB_IMAGE_VARIANT : 'standard'; + const variant = explicitVariant ?? inferredVariant; + + switch (variant) { + case 'standard': + return tag; + case 'no-nginx': + return `${tag}${DOCKER_IMAGE_NO_NGINX_SUFFIX}`; + case 'full': + return `${tag}${DOCKER_IMAGE_FULL_SUFFIX}`; + case 'full-no-nginx': + return `${tag}${DOCKER_IMAGE_FULL_NO_NGINX_SUFFIX}`; + } } export function resolveDockerImageRef( registry: unknown, version: unknown, - options?: { defaultRegistry?: string; defaultVersion?: string }, + options?: { + defaultRegistry?: string; + defaultVersion?: string; + variant?: NbImageVariant; + defaultVariant?: NbImageVariant; + }, ): string { const resolvedRegistry = trimValue(registry) || options?.defaultRegistry || DEFAULT_DOCKER_REGISTRY; const rawVersion = trimValue(version) || options?.defaultVersion || DEFAULT_DOCKER_VERSION; - const normalizedTag = normalizeDockerImageTag(resolvedRegistry, rawVersion); + const normalizedTag = normalizeDockerImageTag(resolvedRegistry, rawVersion, { + variant: options?.variant, + defaultVariant: options?.defaultVariant, + }); return `${resolvedRegistry}:${normalizedTag}`; } + +function extractDockerImageTag(imageRef: unknown): string | undefined { + const ref = trimValue(imageRef); + const lastSlashIndex = ref.lastIndexOf('/'); + const lastColonIndex = ref.lastIndexOf(':'); + if (lastColonIndex <= lastSlashIndex) { + return undefined; + } + return ref.slice(lastColonIndex + 1) || undefined; +} + +export function resolveDockerImageContainerPort(imageRef: unknown): '80' | '13000' { + const tag = extractDockerImageTag(imageRef); + return tag?.endsWith(DOCKER_IMAGE_NO_NGINX_SUFFIX) ? '13000' : '80'; +} + +export function resolveBuiltinDbImage(dbDialect: unknown, options?: { registry?: NbImageRegistry | string }): string { + const dialect = trimValue(dbDialect) || 'postgres'; + const configuredRegistry = + normalizeNbImageRegistry(options?.registry) ?? + inferNbImageRegistryFromRepository(options?.registry) ?? + DEFAULT_NB_IMAGE_REGISTRY; + const defaults = configuredRegistry === 'aliyun' ? ALIYUN_BUILTIN_DB_IMAGES : DEFAULT_BUILTIN_DB_IMAGES; + return defaults[dialect] ?? defaults.postgres; +} diff --git a/packages/core/cli/src/lib/env-proxy.ts b/packages/core/cli/src/lib/env-proxy.ts index 0e6482f5546..af698737c0a 100644 --- a/packages/core/cli/src/lib/env-proxy.ts +++ b/packages/core/cli/src/lib/env-proxy.ts @@ -122,12 +122,13 @@ export type EnvProxyNginxBundle = { export type ManualEnvProxyNginxInput = { name: string; - appPort: string; storagePath: string; distRootPath: string; runtimeVersion: string; appPublicPath?: string; upstreamHost?: string; + upstreamPort?: string; + appPort?: string; cdnBaseUrl?: string; }; @@ -189,6 +190,7 @@ type EnvProxyProviderOptions = { provider?: ProxyProvider; runtimeCliRoot?: string; upstreamHost?: string; + upstreamPort?: string; cdnBaseUrl?: string; }; @@ -536,18 +538,35 @@ function createManualProxyEnvSettings(input: ManualEnvProxyNginxInput): ProxyEnv } function normalizeManualNginxInput(input: ManualEnvProxyNginxInput): ManualEnvProxyNginxInput { + const upstreamPort = trimValue(input.upstreamPort) ?? trimValue(input.appPort); + return { name: String(input.name).trim(), - appPort: String(input.appPort).trim(), storagePath: String(input.storagePath).trim(), distRootPath: String(input.distRootPath).trim(), runtimeVersion: String(input.runtimeVersion).trim(), appPublicPath: trimValue(input.appPublicPath), upstreamHost: trimValue(input.upstreamHost), + upstreamPort, + appPort: trimValue(input.appPort), cdnBaseUrl: trimValue(input.cdnBaseUrl), }; } +function normalizeProxyPort(value?: string): string | undefined { + const normalized = trimValue(value); + if (!normalized || !/^\d+$/.test(normalized)) { + return undefined; + } + + const port = Number(normalized); + if (!Number.isInteger(port) || port < 1 || port > 65535) { + return undefined; + } + + return normalized; +} + async function parseVersionFromPackageJson(content: string, sourceLabel: string): Promise { let parsed: { version?: unknown }; try { @@ -871,7 +890,8 @@ async function buildEnvProxyNginxRenderContext( options?: EnvProxyProviderOptions, ): Promise { const proxyHost = await resolveProxyUpstreamHost(options); - const backendUrl = `http://${proxyHost}:${source.apiPort}`; + const upstreamPort = normalizeProxyPort(options?.upstreamPort) ?? source.apiPort; + const backendUrl = `http://${proxyHost}:${upstreamPort}`; const cdnBaseUrl = source.settings.cdnBaseUrl ?? buildDefaultCdnBaseUrl(source.settings.appPublicPath, source.activeVersion); const entryDir = resolveEnvProxyEntryDir(source.envName, { scope: options?.scope }); const publicDir = resolveEnvProxyNginxPublicOutputDir(source.envName, { scope: options?.scope }); @@ -959,7 +979,7 @@ async function resolveManualNginxBundleSource(input: ManualEnvProxyNginxInput): storagePath: normalized.storagePath, distRootPath: normalized.distRootPath, settings: createManualProxyEnvSettings(normalized), - apiPort: normalized.appPort, + apiPort: normalized.upstreamPort, activeVersion: normalized.runtimeVersion, }; } @@ -1067,6 +1087,7 @@ export async function buildManualEnvProxyNginxBundle( return await buildNginxBundleFromSource(await resolveManualNginxBundleSource(input), { ...options, upstreamHost: trimValue(input.upstreamHost) ?? options?.upstreamHost, + upstreamPort: normalizeProxyPort(input.upstreamPort) ?? options?.upstreamPort, }); } @@ -1156,6 +1177,7 @@ export async function buildManualEnvProxyCaddyBundle( return await buildCaddyBundleFromSource(await resolveManualNginxBundleSource(input), { ...options, upstreamHost: trimValue(input.upstreamHost) ?? options?.upstreamHost, + upstreamPort: normalizeProxyPort(input.upstreamPort) ?? options?.upstreamPort, }); }