Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .github/workflows/build-offline-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,16 @@ jobs:
--include-source "${{ inputs.include_source }}" \
--image-source "${{ inputs.image_source }}" \
--components "${{ inputs.components }}" \
--target "${{ inputs.target }}"
--target "${{ inputs.target }}" \
--compress true



- name: Create zip package
- name: Show zip package
run: |
PACKAGE_NAME="${{ steps.set-vars.outputs.package-name }}"

(cd offline-output && zip -r "../${PACKAGE_NAME}.zip" .)

echo "Package created: ${PACKAGE_NAME}.zip"
echo "Package created by build script: ${PACKAGE_NAME}.zip"

ls -lh "${PACKAGE_NAME}.zip"

Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ cd nexent
bash deploy.sh docker
```

The root `deploy.sh` only forwards to the target deploy script; the native Docker implementation is `bash deploy/docker/deploy.sh`. The Docker and Kubernetes deploy scripts share the same deployment configuration model. Interactive runs show Bash TUI menus for component selection, port policy, and image source. `infrastructure` is required; `application` is selected by default but can be disabled. Use `b`/Backspace to return to the previous TUI step and `q` to quit. Non-interactive runs can pass the same choices with `--version`, `--components`, `--port-policy development|production`, and `--image-source general|mainland|local-latest`. Successful deployments save non-sensitive choices to each deploy directory's `deploy.options` for reuse on the next run.
The root `deploy.sh` only forwards to the target deploy script; the native Docker implementation is `bash deploy/docker/deploy.sh`. The Docker and Kubernetes deploy scripts share the same deployment configuration model. Interactive runs show Bash TUI menus for component selection, port policy, and image source. `infrastructure` is required; `application`, `data-process`, and `supabase` are selected by default and can be disabled when you want a smaller deployment. Use `b`/Backspace to return to the previous TUI step and `q` to quit. Non-interactive runs can pass the same choices with `--version`, `--components`, `--port-policy development|production`, and `--image-source general|mainland|local-latest`. Successful deployments save non-sensitive choices to each deploy directory's `deploy.options` for reuse on the next run.

Docker and Kubernetes both use the project root `.env` as the runtime configuration file. If it does not exist, the deploy scripts create it from `.env.example` or migrate an existing `docker/.env` once.
Docker and Kubernetes both use the project root `.env` as the runtime configuration file. Existing `.env` is kept as-is. If it does not exist, the deploy scripts first reuse an existing `docker/.env`, then fall back to `.env.example` or `docker/.env.example`.

Docker uninstall is handled by `bash uninstall.sh docker`. It can preserve or delete data volumes: run it interactively, pass `--delete-volumes true|false`, or use `bash uninstall.sh docker delete-all` to remove containers and persistent data.

Offline image packages can be built with `bash deploy/offline/build_offline_package.sh --target docker --compress true`. The package includes image tar files, `load-images.sh`, root deploy/uninstall entrypoints, deployment scripts, SQL files, `manifest.yaml`, and `checksums.txt`; deploy it with `bash deploy.sh --load-images docker ...` on the target host.

For detailed deployment instructions, see [Docker Installation](https://modelengine-group.github.io/nexent/en/quick-start/installation.html).

### Kubernetes Deployment (For Enterprise Production)
Expand All @@ -68,10 +70,12 @@ cd nexent
bash deploy.sh k8s
```

The native Kubernetes implementation is `bash deploy/k8s/deploy.sh`. It reads the same project root `.env` as Docker and renders explicit values into Helm ConfigMap and Secret overrides. Use `--persistence-mode local|dynamic|existing`, `--storage-class`, `--local-path`, `--local-node-name`, and `--existing-claim-prefix` to control PVC behavior.
The native Kubernetes implementation is `bash deploy/k8s/deploy.sh`. It reads the same project root `.env` as Docker and renders explicit values into Helm ConfigMap and Secret overrides. Use `--persistence-mode local|dynamic|existing`, `--storage-class`/`--sc`, `--local-path`, `--local-node-name`, and `--existing-claim-prefix` to control PVC behavior. Local mode renders `hostPath` PVs and does not require node affinity.

Kubernetes uninstall is handled by `bash uninstall.sh k8s`. It removes the Helm release first, then can optionally delete the namespace and local PV data. Use `--delete-namespace true|false`, `--delete-local-data true|false`, or `bash uninstall.sh k8s delete-all`; pass `--keep-local-data` with `delete-all` to preserve local volume contents.

Kubernetes offline packages use the same builder with `--target k8s` or `--target all`. Run `load-images.sh` on every cluster node that needs the images, or push the loaded images to an internal registry before deploying with the same version and image-source options used during packaging.

For detailed deployment instructions, see [Kubernetes Installation](https://modelengine-group.github.io/nexent/en/quick-start/kubernetes-installation.html).

# ✨ Core Features
Expand Down
12 changes: 9 additions & 3 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ cd nexent
bash deploy.sh docker
```

根目录 `deploy.sh` 只负责转发到目标部署脚本;Docker 真实实现为 `bash deploy/docker/deploy.sh`。非交互部署可传入 `--version`、`--components`、`--port-policy development|production`、`--image-source general|mainland|local-latest`。
根目录 `deploy.sh` 只负责转发到目标部署脚本;Docker 真实实现为 `bash deploy/docker/deploy.sh`。Docker 和 Kubernetes 使用同一套部署配置模型;交互式运行会通过 Bash TUI 选择组件、端口策略和镜像源。`infrastructure` 必选,`application`、`data-process`、`supabase` 默认选中,也可以取消以部署更小的组合。非交互部署可传入 `--version`、`--components`、`--port-policy development|production`、`--image-source general|mainland|local-latest`。

Docker 与 Kubernetes 统一使用项目根目录 `.env` 作为运行配置文件;如果不存在,部署脚本会从 `.env.example` 创建,或首次自动迁移已有的 `docker/.env`。
Docker 与 Kubernetes 统一使用项目根目录 `.env` 作为运行配置文件;已有 `.env` 会原样保留。如果根目录 `.env` 不存在,部署脚本会优先复用已有的 `docker/.env`,再回退到 `.env.example` 或 `docker/.env.example`。

Docker 卸载入口为 `bash uninstall.sh docker`,默认交互确认是否删除持久化数据;也可以通过 `--delete-volumes true|false` 控制,或使用 `bash uninstall.sh docker delete-all` 同时删除容器和持久化数据。

离线镜像包可通过 `bash deploy/offline/build_offline_package.sh --target docker --compress true` 构建。包内包含镜像 tar、`load-images.sh`、根目录部署/卸载入口、部署脚本、SQL 文件、`manifest.yaml` 和 `checksums.txt`;在目标机器上使用 `bash deploy.sh --load-images docker ...` 加载镜像并部署。

详细部署指南请参考 [Docker 安装部署](https://modelengine-group.github.io/nexent/zh/quick-start/installation.html)。

Expand All @@ -66,10 +70,12 @@ cd nexent
bash deploy.sh k8s
```

Kubernetes 真实实现为 `bash deploy/k8s/deploy.sh`。它会读取同一个根目录 `.env`,并显式渲染为 Helm ConfigMap 和 Secret 覆盖值。PVC 可通过 `--persistence-mode local|dynamic|existing`、`--storage-class`、`--local-path`、`--local-node-name`、`--existing-claim-prefix` 控制。
Kubernetes 真实实现为 `bash deploy/k8s/deploy.sh`。它会读取同一个根目录 `.env`,并显式渲染为 Helm ConfigMap 和 Secret 覆盖值。PVC 可通过 `--persistence-mode local|dynamic|existing`、`--storage-class`/`--sc`、`--local-path`、`--local-node-name`、`--existing-claim-prefix` 控制。local 模式会渲染 `hostPath` PV,不再需要 nodeAffinity

根目录卸载入口为 `bash uninstall.sh docker ...` 或 `bash uninstall.sh k8s ...`,具体实现仍分别在 `deploy/docker/uninstall.sh` 和 `deploy/k8s/uninstall.sh`。

Kubernetes 离线包使用同一个构建脚本,传入 `--target k8s` 或 `--target all`。部署前需要在每个需要运行 Pod 的节点上执行 `load-images.sh`,或将镜像推送到集群可访问的内部镜像仓库,再使用与打包时一致的版本和镜像源参数部署。

详细部署指南请参考 [Kubernetes 安装部署](https://modelengine-group.github.io/nexent/zh/quick-start/kubernetes-installation.html)。

# ✨ 核心特性
Expand Down
40 changes: 37 additions & 3 deletions deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@
usage() {
cat <<'USAGE'
Usage:
bash deploy.sh docker [docker deploy options]
bash deploy.sh k8s [k8s deploy options]
bash deploy.sh [--load-images] docker [docker deploy options]
bash deploy.sh [--load-images] k8s [k8s deploy options]

This root entrypoint only forwards to the target-specific deploy script.
Implementation: deploy/deploy.sh

Options:
--load-images Load Docker image tar files from ./images before deploying.
Defaults to off.
USAGE
}

Expand All @@ -20,4 +24,34 @@
exit 0
fi

exec bash "$SCRIPT_DIR/deploy/deploy.sh" "$@"
LOAD_IMAGES="false"
FORWARD_ARGS=()

while [ $# -gt 0 ]; do

Check failure on line 30 in deploy.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8CojfudU8WZgScIfAn&open=AZ8CojfudU8WZgScIfAn&pullRequest=3306
case "$1" in
--load-images)
LOAD_IMAGES="true"
shift
;;
*)
FORWARD_ARGS+=("$1")
shift
;;
esac
done

if [ "${#FORWARD_ARGS[@]}" -eq 0 ]; then

Check failure on line 43 in deploy.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8CojfudU8WZgScIfAo&open=AZ8CojfudU8WZgScIfAo&pullRequest=3306
usage
exit 0
fi

if [ "$LOAD_IMAGES" = "true" ]; then

Check failure on line 48 in deploy.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8CojfudU8WZgScIfAp&open=AZ8CojfudU8WZgScIfAp&pullRequest=3306
LOAD_SCRIPT="$SCRIPT_DIR/load-images.sh"
if [ ! -f "$LOAD_SCRIPT" ]; then

Check failure on line 50 in deploy.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8CojfudU8WZgScIfAq&open=AZ8CojfudU8WZgScIfAq&pullRequest=3306
echo "Error: --load-images requires $LOAD_SCRIPT" >&2
exit 1
fi
bash "$LOAD_SCRIPT"
fi

exec bash "$SCRIPT_DIR/deploy/deploy.sh" "${FORWARD_ARGS[@]}"
15 changes: 12 additions & 3 deletions deploy/docker/generate_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
ENV_FILE="${DEPLOYMENT_ROOT_ENV:-$PROJECT_ROOT/.env}"
ENV_EXAMPLE="$PROJECT_ROOT/.env.example"
LEGACY_ENV="$PROJECT_ROOT/docker/.env"
LEGACY_ENV_EXAMPLE="$PROJECT_ROOT/docker/.env.example"

echo " 📁 Target .env location: $ENV_FILE"
if [ "${NEXENT_GENERATE_ENV_SKIP_MAIN:-false}" != "true" ]; then

Check failure on line 14 in deploy/docker/generate_env.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8Cojb_dU8WZgScIfAe&open=AZ8Cojb_dU8WZgScIfAe&pullRequest=3306
echo " 📁 Target .env location: $ENV_FILE"
fi

update_env_var() {
local key="$1"
Expand Down Expand Up @@ -41,6 +44,10 @@

if [ -f "$ENV_FILE" ]; then
echo " ✅ Using existing root .env"
elif [ -f "$LEGACY_ENV" ]; then

Check failure on line 47 in deploy/docker/generate_env.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8CojcAdU8WZgScIfAf&open=AZ8CojcAdU8WZgScIfAf&pullRequest=3306
echo " root .env not found, copying docker/.env..."
cp "$LEGACY_ENV" "$ENV_FILE"
echo " Created root .env from docker/.env"
elif [ -f "$ENV_EXAMPLE" ]; then
echo " 📋 root .env not found, copying .env.example..."
cp "$ENV_EXAMPLE" "$ENV_FILE"
Expand All @@ -50,7 +57,7 @@
cp "$LEGACY_ENV_EXAMPLE" "$ENV_FILE"
echo " ✅ Created root .env from docker/.env.example"
else
echo " ERROR Neither root .env nor .env.example exists"
echo " ERROR Neither root .env nor docker/.env nor .env.example exists"

Check warning on line 60 in deploy/docker/generate_env.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Redirect this error message to stderr (>&2).

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8CojcAdU8WZgScIfAg&open=AZ8CojcAdU8WZgScIfAg&pullRequest=3306
ERROR_OCCURRED=1
return 1
fi
Expand Down Expand Up @@ -167,4 +174,6 @@
}

# Run main function
main "$@"
if [ "${NEXENT_GENERATE_ENV_SKIP_MAIN:-false}" != "true" ]; then

Check failure on line 177 in deploy/docker/generate_env.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8CojcAdU8WZgScIfAh&open=AZ8CojcAdU8WZgScIfAh&pullRequest=3306
main "$@"
fi
28 changes: 28 additions & 0 deletions deploy/docker/uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,30 @@
[[ "$answer" =~ ^[Yy]$ ]]
}

remove_docker_named_volumes() {
command -v docker >/dev/null 2>&1 || return 0

local volume_names
volume_names="$(docker volume ls --format '{{.Name}}' 2>/dev/null || true)"
[ -n "$volume_names" ] || return 0

Check failure on line 173 in deploy/docker/uninstall.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8Coje2dU8WZgScIfAi&open=AZ8Coje2dU8WZgScIfAi&pullRequest=3306

local volumes_to_remove=()
local volume
while IFS= read -r volume; do
[ -n "$volume" ] || continue

Check failure on line 178 in deploy/docker/uninstall.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8Coje2dU8WZgScIfAj&open=AZ8Coje2dU8WZgScIfAj&pullRequest=3306
case "$volume" in

Check failure on line 179 in deploy/docker/uninstall.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a default case (*) to handle unexpected values.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8Coje2dU8WZgScIfAk&open=AZ8Coje2dU8WZgScIfAk&pullRequest=3306
nexent_*|nexent-*|monitor_*)
volumes_to_remove+=("$volume")
;;
esac
done <<< "$volume_names"

if [ "${#volumes_to_remove[@]}" -gt 0 ]; then

Check failure on line 186 in deploy/docker/uninstall.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=ModelEngine-Group_nexent&issues=AZ8Coje2dU8WZgScIfAl&open=AZ8Coje2dU8WZgScIfAl&pullRequest=3306
echo "🧹 Removing Docker volumes: ${volumes_to_remove[*]}"
docker volume rm -f "${volumes_to_remove[@]}" >/dev/null 2>&1 || true
fi
}

docker_compose_down_file() {
local compose_file="$1"
local use_project_name="$2"
Expand All @@ -190,6 +214,7 @@

remove_nexent_data_dirs() {
local root_dir="${ROOT_DIR:-$HOME/nexent-data}"
local work_dir="$HOME/nexent"
root_dir="${root_dir%/}"

if [ -z "$root_dir" ] || [ "$root_dir" = "/" ]; then
Expand All @@ -205,6 +230,8 @@
"$root_dir/volumes"
"$root_dir/openssh-server"
"$root_dir/scripts"
"$root_dir/skills"
"$work_dir"
)

local dir
Expand Down Expand Up @@ -238,6 +265,7 @@
docker_compose_down_file "$COMPOSE_DIR/docker-compose.yml" true "$remove_volumes"

if [ "$remove_volumes" = "true" ]; then
remove_docker_named_volumes
remove_nexent_data_dirs
fi

Expand Down
Loading
Loading