feat(milvus): add Milvus 3.0.2 app

Add the official Milvus v3.0.2 standalone topology for issue #6881, with persistent etcd, MinIO, and Milvus data paths.

Move the upstream one-shot volume ownership initialization into the root lifecycle script so 1Panel does not mark a successful exited sidecar unhealthy.
This commit is contained in:
okxlin
2026-09-21 17:19:49 +08:00
parent 9c6ce86512
commit fdcd100897
8 changed files with 520 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
CONTAINER_NAME=milvus-compose-check
PANEL_APP_PORT_GRPC=19530
PANEL_APP_PORT_HTTP=9091
PANEL_APP_PORT_MINIO_API=9000
PANEL_APP_PORT_MINIO_CONSOLE=9001
+86
View File
@@ -0,0 +1,86 @@
additionalProperties:
formFields:
- default: 19530
edit: true
envKey: PANEL_APP_PORT_GRPC
labelEn: Milvus gRPC Port
labelZh: Milvus gRPC 端口
label:
en: Milvus gRPC Port
zh: Milvus gRPC 端口
zh-hant: Milvus gRPC 連接埠
ja: Milvus gRPC ポート
ko: Milvus gRPC 포트
ru: Порт gRPC Milvus
ms: Port gRPC Milvus
pt-br: Porta gRPC do Milvus
tr: Milvus gRPC Portu
es-es: Puerto gRPC de Milvus
fa: پورت gRPC میلووس
lo: ພອດ gRPC ຂອງ Milvus
required: true
rule: paramPort
type: number
- default: 9091
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: Milvus HTTP/WebUI Port
labelZh: Milvus HTTP/WebUI 端口
label:
en: Milvus HTTP/WebUI Port
zh: Milvus HTTP/WebUI 端口
zh-hant: Milvus HTTP/WebUI 連接埠
ja: Milvus HTTP/WebUI ポート
ko: Milvus HTTP/WebUI 포트
ru: Порт HTTP/WebUI Milvus
ms: Port HTTP/WebUI Milvus
pt-br: Porta HTTP/WebUI do Milvus
tr: Milvus HTTP/WebUI Portu
es-es: Puerto HTTP/WebUI de Milvus
fa: پورت HTTP/WebUI میلووس
lo: ພອດ HTTP/WebUI ຂອງ Milvus
required: true
rule: paramPort
type: number
- default: 9000
edit: true
envKey: PANEL_APP_PORT_MINIO_API
labelEn: MinIO API Port
labelZh: MinIO API 端口
label:
en: MinIO API Port
zh: MinIO API 端口
zh-hant: MinIO API 連接埠
ja: MinIO API ポート
ko: MinIO API 포트
ru: Порт API MinIO
ms: Port API MinIO
pt-br: Porta da API MinIO
tr: MinIO API Portu
es-es: Puerto de API de MinIO
fa: پورت API مین‌آی‌او
lo: ພອດ API MinIO
required: true
rule: paramPort
type: number
- default: 9001
edit: true
envKey: PANEL_APP_PORT_MINIO_CONSOLE
labelEn: MinIO Console Port
labelZh: MinIO 控制台端口
label:
en: MinIO Console Port
zh: MinIO 控制台端口
zh-hant: MinIO 主控台連接埠
ja: MinIO コンソールポート
ko: MinIO 콘솔 포트
ru: Порт консоли MinIO
ms: Port Konsol MinIO
pt-br: Porta do console MinIO
tr: MinIO Konsol Portu
es-es: Puerto de consola de MinIO
fa: پورت کنسول مین‌آی‌او
lo: ພອດ console MinIO
required: true
rule: paramPort
type: number
+81
View File
@@ -0,0 +1,81 @@
services:
milvus-etcd:
image: "quay.io/coreos/etcd:v3.5.25"
container_name: ${CONTAINER_NAME}-etcd
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
- ETCD_SNAPSHOT_COUNT=50000
volumes:
- ./etcd-data:/etcd
command: etcd -advertise-client-urls=http://milvus-etcd:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 30s
timeout: 20s
retries: 3
networks:
- milvus-internal
labels:
createdBy: "Apps"
milvus-minio:
image: "quay.io/minio/minio:RELEASE.2024-05-28T17-19-04Z"
container_name: ${CONTAINER_NAME}-minio
environment:
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
ports:
- "${PANEL_APP_PORT_MINIO_CONSOLE}:9001"
- "${PANEL_APP_PORT_MINIO_API}:9000"
volumes:
- ./minio-data:/minio_data
command: ["minio", "server", "/minio_data", "--console-address", ":9001"]
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
timeout: 20s
retries: 3
networks:
- milvus-internal
labels:
createdBy: "Apps"
standalone:
image: "milvusdb/milvus:v3.0.2"
container_name: ${CONTAINER_NAME}-standalone
command: ["milvus", "run", "standalone"]
security_opt:
- "seccomp:unconfined"
environment:
- MINIO_REGION=us-east-1
- ETCD_ENDPOINTS=milvus-etcd:2379
- MINIO_ADDRESS=milvus-minio:9000
volumes:
- ./milvus-data:/var/lib/milvus
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 30s
start_period: 90s
timeout: 20s
retries: 3
ports:
- "${PANEL_APP_PORT_GRPC}:19530"
- "${PANEL_APP_PORT_HTTP}:9091"
depends_on:
milvus-etcd:
condition: service_started
milvus-minio:
condition: service_started
networks:
- milvus-internal
- 1panel-network
labels:
createdBy: "Apps"
networks:
milvus-internal:
internal: true
1panel-network:
external: true
+192
View File
@@ -0,0 +1,192 @@
#!/usr/bin/env bash
set -euo pipefail
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
read_env_value() {
local key="$1"
[[ -f "$ENV_FILE" ]] || return 0
local value
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
case "$value" in
\"*\") value="${value#\"}"; value="${value%\"}" ;;
\'*\') value="${value#\'}"; value="${value%\'}" ;;
esac
printf '%s\n' "$value"
}
configured_value() {
local key="$1"
local default_value="$2"
local value
value="${!key:-}"
if [[ -z "$value" ]]; then
value="$(read_env_value "$key")"
fi
printf '%s\n' "${value:-$default_value}"
}
resolve_app_path() {
local key="$1"
local raw="$2"
local clean candidate resolved current part
local -a parts=()
case "$raw" in
""|/*|.|..|../*|*/../*|*/..) echo "unsafe ${key} path" >&2; return 1 ;;
esac
if [[ "$raw" =~ [[:cntrl:]] ]]; then
echo "unsafe ${key} path" >&2
return 1
fi
clean="${raw#./}"
[[ -n "$clean" ]] || { echo "unsafe ${key} path" >&2; return 1; }
command -v realpath >/dev/null 2>&1 || { echo "realpath is required" >&2; return 1; }
candidate="$ROOT_DIR/$clean"
resolved="$(realpath -m -- "$candidate")" || { echo "unsafe ${key} path" >&2; return 1; }
case "$resolved" in
"$ROOT_DIR"/*) ;;
*) echo "unsafe ${key} path" >&2; return 1 ;;
esac
current="$ROOT_DIR"
IFS='/' read -r -a parts <<< "$clean"
for part in "${parts[@]}"; do
[[ -z "$part" || "$part" == "." ]] && continue
current="$current/$part"
if [[ -L "$current" ]]; then
echo "unsafe ${key} path" >&2
return 1
fi
done
printf '%s\n' "$resolved"
}
ensure_dir() {
local key="$1"
local raw
local path
raw="$(configured_value "$key" "$2")"
path="$(resolve_app_path "$key" "$raw")"
mkdir -p -- "$path"
[[ "$(resolve_app_path "$key" "$raw")" == "$path" ]] || { echo "unsafe ${key} path" >&2; return 1; }
}
resolve_direct_child() {
local key="$1"
local raw="$2"
local clean path
clean="${raw#./}"
if [[ -z "$clean" || "$clean" == */* ]]; then
echo "unsafe ${key} path: lifecycle directories must be direct children of the version root" >&2
return 1
fi
path="$(resolve_app_path "$key" "$raw")"
[[ "$path" == "$ROOT_DIR/$clean" ]] || { echo "unsafe ${key} path" >&2; return 1; }
printf '%s\n' "$path"
}
verify_trusted_root_chain() {
local current owner mode
[[ "$(id -u)" == "0" ]] || { echo "directory ownership initialization must run as root" >&2; return 1; }
command -v stat >/dev/null 2>&1 || { echo "stat is required" >&2; return 1; }
current="$ROOT_DIR"
while [[ "$current" != "/" ]]; do
[[ -d "$current" && ! -L "$current" ]] || { echo "unsafe version root chain: $current" >&2; return 1; }
IFS=':' read -r owner mode < <(stat -c '%u:%a' -- "$current")
[[ "$mode" =~ ^[0-7]{3,4}$ ]] || { echo "unsafe version root chain mode: $current" >&2; return 1; }
if [[ "$current" == "$ROOT_DIR" ]]; then
(( (8#$mode & 0022) == 0 )) || { echo "unsafe version root chain permissions: $current" >&2; return 1; }
else
[[ "$owner" == "0" ]] || { echo "unsafe version root chain owner: $current" >&2; return 1; }
(( (8#$mode & 0022) == 0 || (8#$mode & 01000) != 0 )) || { echo "unsafe version root chain permissions: $current" >&2; return 1; }
fi
current="$(dirname -- "$current")"
done
}
declare -A OWNED_PATHS=()
declare -A OWNED_KEYS_BY_PATH=()
register_owned_dir() {
local key="$1"
local raw="$2"
local path previous_key
path="$(resolve_direct_child "$key" "$raw")"
if [[ -n "${OWNED_KEYS_BY_PATH[$path]+x}" ]]; then
previous_key="${OWNED_KEYS_BY_PATH[$path]}"
echo "duplicate directory ownership target: $path ($previous_key and $key)" >&2
return 1
fi
OWNED_KEYS_BY_PATH["$path"]="$key"
OWNED_PATHS["$key"]="$path"
}
register_configured_owned_dir() {
local key="$1"
local default_value="$2"
local raw
raw="$(configured_value "$key" "$default_value")"
register_owned_dir "$key" "$raw"
}
register_fixed_owned_dir() {
local source="$1"
register_owned_dir "fixed directory $source" "$source"
}
apply_owned_dir() {
local key="$1"
local uid="$2"
local gid="$3"
local mode="$4"
local path actual expected_mode
[[ -n "${OWNED_PATHS[$key]+x}" ]] || { echo "missing directory ownership preflight: $key" >&2; return 1; }
path="${OWNED_PATHS[$key]}"
verify_trusted_root_chain
if [[ -e "$path" || -L "$path" ]]; then
[[ -d "$path" && ! -L "$path" ]] || { echo "unsafe ${key} path" >&2; return 1; }
else
mkdir -- "$path"
fi
chmod "$mode" -- "$path"
[[ -d "$path" && ! -L "$path" ]] || { echo "unsafe ${key} path" >&2; return 1; }
chown --no-dereference "$uid:$gid" -- "$path"
expected_mode="${mode#0}"
actual="$(stat -c '%u:%g:%a' -- "$path")"
[[ "$actual" == "$uid:$gid:$expected_mode" ]] || { echo "${key} ownership/mode mismatch: expected ${uid}:${gid}:${expected_mode}, got ${actual}" >&2; return 1; }
}
ensure_owned_dir() {
local key="$1"
local default_value="$2"
[[ -n "$default_value" ]] || { echo "missing directory ownership default: $key" >&2; return 1; }
apply_owned_dir "$key" "$3" "$4" "$5"
}
ensure_fixed_owned_dir() {
local source="$1"
apply_owned_dir "fixed directory $source" "$2" "$3" "$4"
}
initialize_milvus_data() {
# 1Panel treats a successful one-shot Compose helper as unhealthy; keep the
# official marker and ownership initialization in the root lifecycle hook.
local path="$1"
local marker="$path/.milvus-volume-owner-999-999"
if [[ ! -e "$marker" ]]; then
echo "Preparing $path for 999:999"
chown -R --no-dereference "999:999" -- "$path"
touch -- "$marker"
chown --no-dereference "999:999" -- "$marker"
fi
}
register_fixed_owned_dir "./milvus-data"
register_fixed_owned_dir "./etcd-data"
register_fixed_owned_dir "./minio-data"
ensure_fixed_owned_dir "./milvus-data" "999" "999" "0750"
ensure_fixed_owned_dir "./etcd-data" "0" "0" "0755"
ensure_fixed_owned_dir "./minio-data" "0" "0" "0755"
initialize_milvus_data "${OWNED_PATHS["fixed directory ./milvus-data"]}"
+73
View File
@@ -0,0 +1,73 @@
# Milvus
## 产品介绍
Milvus 是面向向量检索和数据分析的开源向量数据库,支持通过 gRPC、HTTP 和 WebUI 使用向量数据服务。
本应用包采用 Milvus 官方 v3.0.2 standalone Docker Compose 发布文件,包含 Milvus、etcd 元数据服务和 MinIO 对象存储。消息队列使用 Milvus 镜像内置的默认实现,不需要额外安装 1Panel 数据库或 Redis 服务。
## 主要功能
- 提供向量数据写入、查询、检索和索引能力
- 提供 Milvus gRPC API、HTTP/WebUI 访问端口
- 使用 etcd 保存元数据、MinIO 保存对象数据
- 使用独立数据目录保存 Milvus、etcd 和 MinIO 状态
## 访问说明
- Milvus gRPC API:默认 `19530`
- Milvus HTTP/WebUI:默认 `9091`,WebUI 地址为 `http://<主机地址>:9091/webui/`
- MinIO API:默认 `9000`
- MinIO 控制台:默认 `9001`
MinIO 端口和上游 Compose 一样默认发布,但 MinIO 账号密码是官方 Compose 中固定的 `minioadmin` / `minioadmin`,应将这两个端口视为内部管理端口,不要直接暴露到不受信任的公网。需要对外提供服务时,请先按官方文档配置凭据和网络访问策略。
Milvus standalone 官方要求至少 4 个 CPU 核心和 8 GB 内存,并要求 CPU 支持 SSE4.2、AVX、AVX2 或 AVX-512 中的至少一种指令集。实际资源需求取决于数据量和索引类型。
## 数据与生命周期
本应用使用应用实例目录下的相对路径 bind mount,不创建 Docker 命名卷。相对路径以部署后的 `docker-compose.yml` 所在目录为基准:
| 宿主机相对路径 | 容器路径 | 用途 |
| --- | --- | --- |
| `./milvus-data` | `/var/lib/milvus` | Milvus 数据和本地 WAL |
| `./etcd-data` | `/etcd` | etcd 元数据 |
| `./minio-data` | `/minio_data` | MinIO 对象数据 |
容器重启、重建或升级时,只要应用实例目录仍被保留,上述目录中的数据就会继续使用。升级、迁移或卸载前请备份这三个目录以及当前 Compose 配置;不要把它们当作卸载后一定保留的 Docker 命名卷,删除应用实例目录会同时删除这些 bind mount 数据。官方升级说明要求保留现有 etcd、对象存储、消息队列和数据目录,不能在升级时切换消息队列;发生异常时不要直接回滚镜像,先按备份恢复方案处理。
官方 Compose 使用一次性的卷权限初始化服务;为兼容 1Panel 对已退出 sidecar 的状态判断,应用包把同等的 marker 与递归权限初始化放入 root `scripts/init.sh`,Compose 中只保留长期运行的 etcd、MinIO 和 Milvus 服务。Milvus 服务仍保留上游的 `seccomp:unconfined` 安全选项。
## 相关链接
- [官方网站](https://milvus.io/)
- [Docker Compose 配置文档](https://milvus.io/docs/configure-docker.md)
- [Docker 安装要求](https://milvus.io/docs/prerequisite-docker.md)
- [官方 v3.0.2 standalone Compose](https://github.com/milvus-io/milvus/releases/download/v3.0.2/milvus-standalone-docker-compose.yaml)
- [升级说明](https://milvus.io/docs/upgrade_milvus_standalone-docker.md)
- [源码仓库](https://github.com/milvus-io/milvus)
<details>
<summary>默认图标许可 / Fallback icon license (MIT)</summary>
Copyright (c) 2026 okxlin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</details>
+48
View File
@@ -0,0 +1,48 @@
# Milvus
## Introduction
Milvus is an open-source vector database for vector search and data analytics. It exposes vector data services through gRPC, HTTP, and WebUI interfaces.
This package follows the official Milvus v3.0.2 standalone Docker Compose release. It includes Milvus, etcd for metadata, and MinIO for object storage. The default message queue is provided by the Milvus image, so no 1Panel database or Redis service is required.
## Features
- Vector data insertion, query, search, and index management
- Milvus gRPC API and HTTP/WebUI endpoints
- etcd-backed metadata and MinIO-backed object storage
- Separate persistent directories for Milvus, etcd, and MinIO
## Access
- Milvus gRPC API: `19530` by default
- Milvus HTTP/WebUI: `9091` by default; open `http://<host>:9091/webui/`
- MinIO API: `9000` by default
- MinIO console: `9001` by default
The MinIO ports are published as in the upstream Compose file, but its credentials are fixed by that file at `minioadmin` / `minioadmin`. Treat these ports as internal management endpoints and do not expose them directly to an untrusted public network. Configure credentials and network access according to the upstream documentation before making them public.
Milvus standalone officially requires at least 4 CPU cores and 8 GB of RAM. The CPU must support at least one of SSE4.2, AVX, AVX2, or AVX-512. Actual requirements depend on the dataset and index types.
## Data and lifecycle
This package uses relative bind mounts under the application instance directory; it does not declare Docker named volumes. Relative paths are resolved from the deployed directory containing `docker-compose.yml`:
| Relative host path | Container path | Purpose |
| --- | --- | --- |
| `./milvus-data` | `/var/lib/milvus` | Milvus data and local WAL |
| `./etcd-data` | `/etcd` | etcd metadata |
| `./minio-data` | `/minio_data` | MinIO object data |
The data remains available across container restarts, rebuilds, and upgrades as long as the application instance directory is retained. Back up all three directories and the Compose configuration before an upgrade, migration, or uninstall. Do not assume they behave like Docker named volumes that survive uninstall: removing the application instance directory removes these bind-mounted data directories. The official upgrade procedure keeps the existing etcd, object storage, message queue, and data directories; do not switch message-queue systems during an upgrade. Do not perform an image-only rollback after Milvus has written upgraded state; use a tested backup recovery plan instead.
The official Compose file uses a one-shot volume-permission initializer. To remain compatible with 1Panel's status handling for exited sidecars, this package performs the same marker and recursive ownership initialization in the root `scripts/init.sh`; Compose keeps only the long-running etcd, MinIO, and Milvus services. The Milvus service retains the upstream `seccomp:unconfined` setting.
## Links
- [Website](https://milvus.io/)
- [Docker Compose configuration](https://milvus.io/docs/configure-docker.md)
- [Docker prerequisites](https://milvus.io/docs/prerequisite-docker.md)
- [Official v3.0.2 standalone Compose](https://github.com/milvus-io/milvus/releases/download/v3.0.2/milvus-standalone-docker-compose.yaml)
- [Upgrade guide](https://milvus.io/docs/upgrade_milvus_standalone-docker.md)
- [Source repository](https://github.com/milvus-io/milvus)
+35
View File
@@ -0,0 +1,35 @@
name: Milvus
tags:
- Database
title: Milvus
description: 面向高性能向量检索与数据分析的开源向量数据库
additionalProperties:
key: milvus
name: Milvus
tags:
- Database
shortDescZh: 面向高性能向量检索与数据分析的开源向量数据库
shortDescEn: An open-source vector database for high-performance vector search and data analytics
description:
en: An open-source vector database for high-performance vector search and data analytics
zh: 面向高性能向量检索与数据分析的开源向量数据库
zh-hant: 面向高效能向量搜尋與資料分析的開源向量資料庫
ja: 高性能なベクトル検索とデータ分析のためのオープンソースベクトルデータベース
ko: 고성능 벡터 검색과 데이터 분석을 위한 오픈 소스 벡터 데이터베이스
ru: Векторная база данных с открытым исходным кодом для высокопроизводительного поиска и аналитики
ms: Pangkalan data vektor sumber terbuka untuk carian vektor berprestasi tinggi dan analisis data
pt-br: Banco de dados vetorial de código aberto para pesquisa vetorial de alto desempenho e análise de dados
tr: Yüksek performanslı vektör arama ve veri analizi için açık kaynaklı vektör veritabanı
es-es: Base de datos vectorial de código abierto para búsquedas vectoriales de alto rendimiento y análisis de datos
fa: پایگاه داده برداری متن‌باز برای جست‌وجوی برداری پربازده و تحلیل داده
lo: ຖານຂໍ້ມູນ vector ແບບ open-source ສຳລັບການຄົ້ນຫາ vector ປະສິດທິພາບສູງ ແລະ ວິເຄາະຂໍ້ມູນ
type: tool
crossVersionUpdate: true
limit: 0
recommend: 0
website: https://milvus.io/
github: https://github.com/milvus-io/milvus
document: https://milvus.io/docs/
architectures:
- amd64
- arm64
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB