From d07b10283da120666e8398388e8fd200cba6fe3f Mon Sep 17 00:00:00 2001 From: Yongzao <532741407@qq.com> Date: Wed, 11 Mar 2026 13:53:56 +0800 Subject: [PATCH 1/2] ready 4 test --- docker/src/main/Dockerfile-1.0.0-ainode | 66 ------- docker/src/main/Dockerfile-2.0.7-ainode | 88 +++++++++ docker/src/main/ainode-entrypoint.sh | 150 ++++++++++++++++ docker/src/main/build-ainode.sh | 229 ++++++++++++++++++++++++ 4 files changed, 467 insertions(+), 66 deletions(-) delete mode 100644 docker/src/main/Dockerfile-1.0.0-ainode create mode 100644 docker/src/main/Dockerfile-2.0.7-ainode create mode 100644 docker/src/main/ainode-entrypoint.sh create mode 100644 docker/src/main/build-ainode.sh diff --git a/docker/src/main/Dockerfile-1.0.0-ainode b/docker/src/main/Dockerfile-1.0.0-ainode deleted file mode 100644 index 7e315c6493927..0000000000000 --- a/docker/src/main/Dockerfile-1.0.0-ainode +++ /dev/null @@ -1,66 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -FROM python:3.12-slim-bullseye -ARG version=2.0.5-SNAPSHOT -ARG target=apache-iotdb-${version}-ainode-bin - -# replace deb source when necessary -# RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \ -# sed -i 's|security.debian.org/debian-security|mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list - -# replace pip source when necessary -# RUN pip config set global.index-url https://mirrors.ustc.edu.cn/pypi/web/simple - -RUN apt update \ - && apt install lsof dos2unix procps unzip dumb-init wget inetutils-ping libopenblas-dev liblapack-dev gfortran gcc g++ -y \ - && apt autoremove -y \ - && apt purge --auto-remove -y \ - && apt clean -y - -COPY target/${target}.zip / -RUN cd / && unzip ${target}.zip \ - && rm ${target}.zip \ - && mv ${target} ainode - -ENV IOTDB_AINODE_HOME=/ainode VERSION=${version} -WORKDIR ${IOTDB_AINODE_HOME}/sbin - -COPY DockerCompose/replace-conf-from-env.sh . -COPY DockerCompose/entrypoint.sh . - -RUN chmod +x *.sh && dos2unix *.sh \ - && dos2unix ${IOTDB_AINODE_HOME}/conf/*.sh - -# use huggingface mirrors when necessary -ARG hf_web=huggingface.co -# ARG hf_web=hf-mirror.com -RUN mkdir -p ${IOTDB_AINODE_HOME}/data/ainode/models/weights/sundial && \ - mkdir -p ${IOTDB_AINODE_HOME}/data/ainode/models/weights/timer_xl -RUN wget -O ${IOTDB_AINODE_HOME}/data/ainode/models/weights/sundial/config.json https://${hf_web}/thuml/sundial-base-128m/resolve/main/config.json && \ - wget -O ${IOTDB_AINODE_HOME}/data/ainode/models/weights/sundial/model.safetensors https://${hf_web}/thuml/sundial-base-128m/resolve/main/model.safetensors -RUN wget -O ${IOTDB_AINODE_HOME}/data/ainode/models/weights/timer_xl/config.json https://${hf_web}/thuml/timer-base-84m/resolve/main/config.json && \ - wget -O ${IOTDB_AINODE_HOME}/data/ainode/models/weights/timer_xl/model.safetensors https://${hf_web}/thuml/timer-base-84m/resolve/main/model.safetensors - - -ENV PATH="${IOTDB_AINODE_HOME}/sbin/:${IOTDB_AINODE_HOME}/tools/:${PATH}" -RUN bash start-ainode.sh || true -RUN rm -r ${IOTDB_AINODE_HOME}/logs/* - -ENTRYPOINT ["/usr/bin/dumb-init", "--"] -CMD ["bash", "-c", "entrypoint.sh ainode"] diff --git a/docker/src/main/Dockerfile-2.0.7-ainode b/docker/src/main/Dockerfile-2.0.7-ainode new file mode 100644 index 0000000000000..8e89e2a13b4ab --- /dev/null +++ b/docker/src/main/Dockerfile-2.0.7-ainode @@ -0,0 +1,88 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +FROM python:3.11-slim-bullseye + +# Build argument: Version number (required) +ARG VERSION + +# Fail build if VERSION is not provided +RUN if [ -z "$VERSION" ]; then echo "ERROR: VERSION build argument is required" && exit 1; fi + +# Set environment variables +ENV IOTDB_HOME=/ainode \ + PATH=$PATH:/ainode/sbin \ + DEBIAN_FRONTEND=noninteractive + +# Install system dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + unzip \ + procps \ + netcat-openbsd \ + curl \ + vim \ + tzdata \ + && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ + && echo $TZ > /etc/timezone \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Set working directory +WORKDIR /tmp + +# Copy and extract the distribution package +# Note: Build context is project root (../../.. relative to this Dockerfile) +COPY distribution/target/apache-iotdb-${VERSION}-ainode-bin.zip /tmp/ + +# Extract and rename directory +RUN unzip -q apache-iotdb-${VERSION}-ainode-bin.zip \ + && mv apache-iotdb-${VERSION}-ainode-bin /ainode \ + && rm -f apache-iotdb-${VERSION}-ainode-bin.zip \ + && mkdir -p /ainode/logs /ainode/data/ainode + +# Copy data directory from build server to image +# The build script will copy /data/ainode to tmp-data/ before build +COPY docker/src/main/tmp-data/ /ainode/data/ainode/ + +# Set directory permissions +RUN chmod -R 755 /ainode/sbin \ + && chmod +x /ainode/sbin/*.sh \ + && chmod -R 777 /ainode/data /ainode/logs + +# Health check configuration +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD curl -f http://localhost:8080/health || exit 1 + +# Expose ports +# 10810: AINode RPC port (ain_inference_rpc_port) +# 8080: Health check / management port +EXPOSE 10810 8080 + +# Copy entrypoint script (relative to project root) +COPY docker/src/main/ainode-entrypoint.sh /ainode/sbin/ +RUN chmod +x /ainode/sbin/ainode-entrypoint.sh + +# Set working directory +WORKDIR /ainode + +# Use entrypoint script as startup command +ENTRYPOINT ["/ainode/sbin/ainode-entrypoint.sh"] + +# Default command (can be overridden) +CMD ["start"] \ No newline at end of file diff --git a/docker/src/main/ainode-entrypoint.sh b/docker/src/main/ainode-entrypoint.sh new file mode 100644 index 0000000000000..cf1fc3f19d41a --- /dev/null +++ b/docker/src/main/ainode-entrypoint.sh @@ -0,0 +1,150 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# +# AINode Docker Entrypoint Script +# Supports configuration via environment variables for iotdb-ainode.properties +# + +set -e + +IOTDB_HOME="/ainode" +CONF_FILE="${IOTDB_HOME}/conf/iotdb-ainode.properties" + +# Logging function +log() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" +} + +# Initialize configuration file +init_config() { + if [ ! -f "${CONF_FILE}" ]; then + log "ERROR: Configuration file not found: ${CONF_FILE}" + exit 1 + fi + + log "Initializing AINode configuration..." + + # Backup original configuration + if [ ! -f "${CONF_FILE}.original" ]; then + cp "${CONF_FILE}" "${CONF_FILE}.original" + fi + + # Update configuration based on environment variables + # Cluster configuration + update_config "cluster_name" "${CLUSTER_NAME:-defaultCluster}" + update_config "ain_seed_config_node" "${SEED_CONFIG_NODE:-127.0.0.1:10710}" + + # DataNode connection configuration + update_config "ain_cluster_ingress_address" "${DATA_NODE_ADDRESS:-127.0.0.1}" + update_config "ain_cluster_ingress_port" "${DATA_NODE_PORT:-6667}" + update_config "ain_cluster_ingress_username" "${DATA_NODE_USERNAME:-root}" + update_config "ain_cluster_ingress_password" "${DATA_NODE_PASSWORD:-root}" + + # AINode service configuration + update_config "ain_rpc_address" "${AINODE_RPC_ADDRESS:-0.0.0.0}" + update_config "ain_rpc_port" "${AINODE_RPC_PORT:-10810}" + + # Storage paths configuration + update_config "ain_system_dir" "${SYSTEM_DIR:-data/ainode/system}" + update_config "ain_models_dir" "${MODELS_DIR:-data/ainode/models}" + + # Thrift compression configuration + update_config "ain_thrift_compression_enabled" "${THRIFT_COMPRESSION:-0}" + + log "Configuration initialized successfully" +} + +# Update configuration item in properties file +update_config() { + local key=$1 + local value=$2 + + if grep -q "^${key}=" "${CONF_FILE}"; then + # Update existing configuration + sed -i "s|^${key}=.*|${key}=${value}|g" "${CONF_FILE}" + else + # Append new configuration + echo "${key}=${value}" >> "${CONF_FILE}" + fi +} + +# Start AINode +start_ainode() { + log "Starting AINode..." + + # Check if already running + if [ -f "${IOTDB_HOME}/data/ainode.pid" ]; then + local pid=$(cat "${IOTDB_HOME}/data/ainode.pid") + if ps -p ${pid} > /dev/null 2>&1; then + log "AINode is already running with PID ${pid}" + return 0 + fi + fi + + # Use exec to replace current process and ensure proper signal handling + exec ${IOTDB_HOME}/sbin/start-ainode.sh +} + +# Stop AINode +stop_ainode() { + log "Stopping AINode..." + if [ -f "${IOTDB_HOME}/sbin/stop-ainode.sh" ]; then + ${IOTDB_HOME}/sbin/stop-ainode.sh + else + log "Stop script not found" + fi +} + +# Handle signals for graceful shutdown +trap stop_ainode SIGTERM SIGINT + +# Main logic +case "${1:-start}" in + start) + init_config + start_ainode + ;; + stop) + stop_ainode + ;; + restart) + stop_ainode + sleep 10 + init_config + start_ainode + ;; + status) + if [ -f "${IOTDB_HOME}/data/ainode.pid" ]; then + cat "${IOTDB_HOME}/data/ainode.pid" + else + echo "AINode is not running" + exit 1 + fi + ;; + config) + # Only generate configuration without starting (for debugging) + init_config + cat "${CONF_FILE}" + ;; + *) + # Execute other commands directly + exec "$@" + ;; +esac \ No newline at end of file diff --git a/docker/src/main/build-ainode.sh b/docker/src/main/build-ainode.sh new file mode 100644 index 0000000000000..bf95d2942ef21 --- /dev/null +++ b/docker/src/main/build-ainode.sh @@ -0,0 +1,229 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# +# AINode Docker Image Build Script +# Run this script from docker/src/main directory +# Usage: ./build.sh -v [options] +# + +set -e + +# Get script directory (should be docker/src/main) +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +# Project root is 3 levels up from docker/src/main +PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" + +# Default configuration +VERSION="" +IMAGE_NAME="apache/iotdb" +IMAGE_TAG_SUFFIX="ainode" +PUSH_IMAGE=false +NO_CACHE=false +DATA_DIR="/data/ainode" +REGISTRY_PREFIX="" + +# Usage information +usage() { + cat << EOF +Usage: $0 -v [options] + +Required: + -v, --version Specify IoTDB version (e.g., 1.0.0, 2.0.1) + +Options: + -p, --push Push image to registry after build + -n, --no-cache Build without Docker cache + -t, --tag Custom image tag (default: -ainode) + -d, --data-dir Data directory path (default: /data/ainode) + -r, --registry Registry prefix (e.g., registry.example.com) + -h, --help Show this help message + +Examples: + # Build version 1.0.0 + $0 -v 1.0.0 + + # Build and push + $0 -v 1.0.0 --push + + # Build with custom data directory + $0 -v 1.0.0 --data-dir /mnt/data/ainode + + # Build for private registry + $0 -v 2.0.1 --registry registry.example.com/apache --push +EOF +} + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + -v|--version) + VERSION="$2" + shift 2 + ;; + -p|--push) + PUSH_IMAGE=true + shift + ;; + -n|--no-cache) + NO_CACHE=true + shift + ;; + -t|--tag) + CUSTOM_TAG="$2" + shift 2 + ;; + -d|--data-dir) + DATA_DIR="$2" + shift 2 + ;; + -r|--registry) + REGISTRY_PREFIX="$2" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" + usage + exit 1 + ;; + esac +done + +# Validate version +if [ -z "$VERSION" ]; then + echo "Error: Version is required. Use -v to specify." + usage + exit 1 +fi + +# Check if distribution package exists (relative to project root) +DIST_FILE="${PROJECT_ROOT}/distribution/target/apache-iotdb-${VERSION}-ainode-bin.zip" +if [ ! -f "$DIST_FILE" ]; then + echo "Error: Distribution file not found: $DIST_FILE" + echo "Please build the project first: mvn clean package -DskipTests" + exit 1 +fi + +# Check if data directory exists +if [ ! -d "$DATA_DIR" ]; then + echo "Warning: Data directory does not exist: $DATA_DIR" + echo "Creating empty directory..." + mkdir -p "$DATA_DIR" +fi + +# Determine image tag +if [ -n "$CUSTOM_TAG" ]; then + IMAGE_TAG="${CUSTOM_TAG}" +else + IMAGE_TAG="${VERSION}-${IMAGE_TAG_SUFFIX}" +fi + +# Construct full image name +if [ -n "$REGISTRY_PREFIX" ]; then + FULL_IMAGE_NAME="${REGISTRY_PREFIX}/${IMAGE_NAME}:${IMAGE_TAG}" +else + FULL_IMAGE_NAME="${IMAGE_NAME}:${IMAGE_TAG}" +fi + +echo "============================================" +echo "Building AINode Docker Image" +echo "============================================" +echo "Version: ${VERSION}" +echo "Distribution: ${DIST_FILE}" +echo "Data Directory: ${DATA_DIR}" +echo "Dockerfile: ${SCRIPT_DIR}/Dockerfile-2.0.7-ainode" +echo "Image Name: ${FULL_IMAGE_NAME}" +echo "Build Context: ${PROJECT_ROOT}" +echo "============================================" + +# Prepare temporary data directory for Docker build context +# Docker cannot COPY files from absolute paths outside build context +TMP_DATA_DIR="${SCRIPT_DIR}/tmp-data" +echo "Preparing data directory for build context..." + +# Clean up old temp data if exists +if [ -d "$TMP_DATA_DIR" ]; then + rm -rf "$TMP_DATA_DIR" +fi + +# Copy data to temporary location within build context +mkdir -p "$TMP_DATA_DIR" +if [ -d "$DATA_DIR" ] && [ "$(ls -A $DATA_DIR)" ]; then + cp -r "$DATA_DIR"/* "$TMP_DATA_DIR/" + echo "Copied data from ${DATA_DIR} to ${TMP_DATA_DIR}" +else + echo "No data to copy, creating empty directory" +fi + +# Ensure cleanup on exit +cleanup() { + echo "Cleaning up temporary data directory..." + rm -rf "$TMP_DATA_DIR" +} +trap cleanup EXIT + +# Build Docker image +# Build context is PROJECT_ROOT (3 levels up from current script) +BUILD_CMD="docker build" +BUILD_CMD+=" --file ${SCRIPT_DIR}/Dockerfile-2.0.7-ainode" +BUILD_CMD+=" --build-arg VERSION=${VERSION}" +BUILD_CMD+=" --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" +BUILD_CMD+=" --build-arg VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" + +if [ "$NO_CACHE" = true ]; then + BUILD_CMD+=" --no-cache" +fi + +BUILD_CMD+=" --tag ${FULL_IMAGE_NAME}" +BUILD_CMD+=" ${PROJECT_ROOT}" + +echo "Executing: ${BUILD_CMD}" +${BUILD_CMD} || { + echo "Error: Docker build failed" + exit 1 +} + +echo "" +echo "Build completed successfully: ${FULL_IMAGE_NAME}" + +# Push image if requested +if [ "$PUSH_IMAGE" = true ]; then + echo "Pushing image to registry..." + docker push "${FULL_IMAGE_NAME}" + + # Also push latest tag for release versions + if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + LATEST_TAG="latest-${IMAGE_TAG_SUFFIX}" + if [ -n "$REGISTRY_PREFIX" ]; then + LATEST_NAME="${REGISTRY_PREFIX}/${IMAGE_NAME}:${LATEST_TAG}" + else + LATEST_NAME="${IMAGE_NAME}:${LATEST_TAG}" + fi + echo "Tagging and pushing: ${LATEST_NAME}" + docker tag "${FULL_IMAGE_NAME}" "${LATEST_NAME}" + docker push "${LATEST_NAME}" + fi +fi + +echo "" +echo "Done!" \ No newline at end of file From 5331248af1456cee368a2913253d7008073a94f0 Mon Sep 17 00:00:00 2001 From: Yongzao <532741407@qq.com> Date: Thu, 12 Mar 2026 10:12:11 +0800 Subject: [PATCH 2/2] finish --- .dockerignore | 2 + docker/ReadMe.md | 20 +++++ .../DockerCompose/docker-compose-ainode.yml | 3 + ...e-2.0.7-ainode => Dockerfile-2.0.x-ainode} | 8 +- docker/src/main/ainode-entrypoint.sh | 24 +++--- docker/src/main/build-ainode.sh | 85 ++++++++++++++----- 6 files changed, 104 insertions(+), 38 deletions(-) rename docker/src/main/{Dockerfile-2.0.7-ainode => Dockerfile-2.0.x-ainode} (91%) diff --git a/.dockerignore b/.dockerignore index 288d980b3f235..ecb881d8d3d4d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -20,3 +20,5 @@ * !distribution !docker/src/main/DockerCompose/start-1c1d.sh +!docker/src/main/ainode-build-data/ +!docker/src/main/ainode-entrypoint.sh \ No newline at end of file diff --git a/docker/ReadMe.md b/docker/ReadMe.md index 1574099c3749f..f674364626b78 100644 --- a/docker/ReadMe.md +++ b/docker/ReadMe.md @@ -53,6 +53,9 @@ e.g. ./do-docker-build.sh -t standalone -v 1.0.0 # for ainode, start from 2.0.5 ./do-docker-build.sh -t ainode -v 2.0.5-SNAPSHOT +# for ainode, start from 2.0.8 +cd src/main +./build-ainode.sh -v 2.0.8-SNAPSHOT -d /data/ainode ``` Notice: Make directory of src/main/target and put the zip file downloading from the official download page. @@ -91,6 +94,23 @@ Please download `docker-compose-ainode.yml` in `docker/src/main/DockerCompose` f docker compose -f docker-compose-ainode.yml up -d ``` +Start from v2.0.7, run +```shell +docker run -d \ + --name iotdb-ainode \ + --network host \ + -p 10810:10810 \ + -p 8080:8080 \ + -e AIN_SEED_CONFIG_NODE=127.0.0.1:10710 \ + -e AIN_RPC_ADDRESS=127.0.0.1 \ + -e AIN_RPC_PORT=10810 \ + -e AIN_CLUSTER_INGRESS_ADDRESS=127.0.0.1 \ + -e AIN_CLUSTER_INGRESS_PORT=6667 \ + -e AIN_CLUSTER_INGRESS_USERNAME=root \ + -e AIN_CLUSTER_INGRESS_PASSWORD=root \ + apache/iotdb:2.0.7-SNAPSHOT-ainode +``` + ## Quick start We provide `docker-compose-cluster-1c1d1a.yml` in `docker/src/main/DockerCompose`. Downloading this yaml file, both standalone and ainode docker first. Subsequently, you can easily obtain a IoTDB cluster, which consists of a ConfigNode, a DataNode and a AINode, in your local machine. diff --git a/docker/src/main/DockerCompose/docker-compose-ainode.yml b/docker/src/main/DockerCompose/docker-compose-ainode.yml index e393d9ccffec5..c61567aeca257 100644 --- a/docker/src/main/DockerCompose/docker-compose-ainode.yml +++ b/docker/src/main/DockerCompose/docker-compose-ainode.yml @@ -40,9 +40,12 @@ services: - ain_cluster_ingress_username=root - ain_cluster_ingress_password=root - ain_cluster_ingress_time_zone=UTC+8 + ports: + - "10810:10810" volumes: - ainode-data:/ainode/data - ./logs/ainode:/ainode/logs + restart: unless-stopped # - ./lib/ainode:/ainode/lib # Uncomment for rolling upgrade # Note: Some environments set an extremely high container nofile limit (~2^30 = 1073741824). # This can make the startup step "Checking whether the ports are already occupied..." appear to hang (lsof slow). diff --git a/docker/src/main/Dockerfile-2.0.7-ainode b/docker/src/main/Dockerfile-2.0.x-ainode similarity index 91% rename from docker/src/main/Dockerfile-2.0.7-ainode rename to docker/src/main/Dockerfile-2.0.x-ainode index 8e89e2a13b4ab..57965f6014dc9 100644 --- a/docker/src/main/Dockerfile-2.0.7-ainode +++ b/docker/src/main/Dockerfile-2.0.x-ainode @@ -38,8 +38,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ vim \ tzdata \ - && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ - && echo $TZ > /etc/timezone \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* @@ -57,8 +55,10 @@ RUN unzip -q apache-iotdb-${VERSION}-ainode-bin.zip \ && mkdir -p /ainode/logs /ainode/data/ainode # Copy data directory from build server to image -# The build script will copy /data/ainode to tmp-data/ before build -COPY docker/src/main/tmp-data/ /ainode/data/ainode/ +# The build script copies /data/ainode to docker/src/main/ainode-build-data/ before build +# Note: The trailing slash is important - it copies contents not the directory itself +COPY docker/src/main/ainode-build-data/ /ainode/data/ainode/ + # Set directory permissions RUN chmod -R 755 /ainode/sbin \ diff --git a/docker/src/main/ainode-entrypoint.sh b/docker/src/main/ainode-entrypoint.sh index cf1fc3f19d41a..bf60a6ce76009 100644 --- a/docker/src/main/ainode-entrypoint.sh +++ b/docker/src/main/ainode-entrypoint.sh @@ -49,24 +49,24 @@ init_config() { # Update configuration based on environment variables # Cluster configuration update_config "cluster_name" "${CLUSTER_NAME:-defaultCluster}" - update_config "ain_seed_config_node" "${SEED_CONFIG_NODE:-127.0.0.1:10710}" - - # DataNode connection configuration - update_config "ain_cluster_ingress_address" "${DATA_NODE_ADDRESS:-127.0.0.1}" - update_config "ain_cluster_ingress_port" "${DATA_NODE_PORT:-6667}" - update_config "ain_cluster_ingress_username" "${DATA_NODE_USERNAME:-root}" - update_config "ain_cluster_ingress_password" "${DATA_NODE_PASSWORD:-root}" + update_config "ain_seed_config_node" "${AIN_SEED_CONFIG_NODE:-127.0.0.1:10710}" # AINode service configuration - update_config "ain_rpc_address" "${AINODE_RPC_ADDRESS:-0.0.0.0}" - update_config "ain_rpc_port" "${AINODE_RPC_PORT:-10810}" + update_config "ain_rpc_address" "${AIN_RPC_ADDRESS:-0.0.0.0}" + update_config "ain_rpc_port" "${AIN_RPC_PORT:-10810}" + + # DataNode connection configuration + update_config "ain_cluster_ingress_address" "${AIN_CLUSTER_INGRESS_ADDRESS:-127.0.0.1}" + update_config "ain_cluster_ingress_port" "${AIN_CLUSTER_INGRESS_PORT:-6667}" + update_config "ain_cluster_ingress_username" "${AIN_CLUSTER_INGRESS_USERNAME:-root}" + update_config "ain_cluster_ingress_password" "${AIN_CLUSTER_INGRESS_PASSWORD:-root}" # Storage paths configuration - update_config "ain_system_dir" "${SYSTEM_DIR:-data/ainode/system}" - update_config "ain_models_dir" "${MODELS_DIR:-data/ainode/models}" + update_config "ain_system_dir" "${AIN_SYSTEM_DIR:-data/ainode/system}" + update_config "ain_models_dir" "${AIN_MODELS_DIR:-data/ainode/models}" # Thrift compression configuration - update_config "ain_thrift_compression_enabled" "${THRIFT_COMPRESSION:-0}" + update_config "ain_thrift_compression_enabled" "${AIN_THRIFT_COMPRESSION_ENABLED:-0}" log "Configuration initialized successfully" } diff --git a/docker/src/main/build-ainode.sh b/docker/src/main/build-ainode.sh index bf95d2942ef21..44a5439c54c13 100644 --- a/docker/src/main/build-ainode.sh +++ b/docker/src/main/build-ainode.sh @@ -45,7 +45,7 @@ usage() { Usage: $0 -v [options] Required: - -v, --version Specify IoTDB version (e.g., 1.0.0, 2.0.1) + -v, --version Specify IoTDB version (e.g., 2.0.8) Options: -p, --push Push image to registry after build @@ -56,17 +56,14 @@ Options: -h, --help Show this help message Examples: - # Build version 1.0.0 - $0 -v 1.0.0 + # Build version 2.0.8 + $0 -v 2.0.8 # Build and push - $0 -v 1.0.0 --push + $0 -v 2.0.8 --push # Build with custom data directory - $0 -v 1.0.0 --data-dir /mnt/data/ainode - - # Build for private registry - $0 -v 2.0.1 --registry registry.example.com/apache --push + $0 -v 2.0.8 --data-dir /mnt/data/ainode EOF } @@ -151,41 +148,75 @@ echo "============================================" echo "Version: ${VERSION}" echo "Distribution: ${DIST_FILE}" echo "Data Directory: ${DATA_DIR}" -echo "Dockerfile: ${SCRIPT_DIR}/Dockerfile-2.0.7-ainode" +echo "Dockerfile: ${SCRIPT_DIR}/Dockerfile-2.0.x-ainode" echo "Image Name: ${FULL_IMAGE_NAME}" echo "Build Context: ${PROJECT_ROOT}" +echo "Script Dir: ${SCRIPT_DIR}" echo "============================================" -# Prepare temporary data directory for Docker build context -# Docker cannot COPY files from absolute paths outside build context -TMP_DATA_DIR="${SCRIPT_DIR}/tmp-data" -echo "Preparing data directory for build context..." +# Prepare data directory for Docker build context +# Use a unique name to avoid .dockerignore conflicts with common patterns like 'tmp*' +BUILD_DATA_DIR_NAME="ainode-build-data" +TMP_DATA_DIR="${SCRIPT_DIR}/${BUILD_DATA_DIR_NAME}" + +echo "Preparing data directory for build context at: ${TMP_DATA_DIR}" -# Clean up old temp data if exists +# Clean up old data if exists if [ -d "$TMP_DATA_DIR" ]; then + echo "Cleaning up existing build data directory..." rm -rf "$TMP_DATA_DIR" fi -# Copy data to temporary location within build context +# Create directory and copy data mkdir -p "$TMP_DATA_DIR" -if [ -d "$DATA_DIR" ] && [ "$(ls -A $DATA_DIR)" ]; then +if [ -d "$DATA_DIR" ] && [ "$(ls -A $DATA_DIR 2>/dev/null)" ]; then + echo "Copying data from ${DATA_DIR} to ${TMP_DATA_DIR}..." cp -r "$DATA_DIR"/* "$TMP_DATA_DIR/" - echo "Copied data from ${DATA_DIR} to ${TMP_DATA_DIR}" + echo "Copied $(ls -1 "$TMP_DATA_DIR" | wc -l) items" else - echo "No data to copy, creating empty directory" + echo "No data to copy, created empty directory" +fi + +# Verify the directory exists and show contents +if [ ! -d "$TMP_DATA_DIR" ]; then + echo "Error: Failed to create temporary data directory: ${TMP_DATA_DIR}" + exit 1 fi -# Ensure cleanup on exit +echo "Build data directory contents:" +ls -la "$TMP_DATA_DIR" || echo "(empty directory)" + +# Check if .dockerignore exists and might exclude our directory +DOCKERIGNORE_FILE="${PROJECT_ROOT}/.dockerignore" +if [ -f "$DOCKERIGNORE_FILE" ]; then + if grep -q "ainode-build-data" "$DOCKERIGNORE_FILE" || grep -qE "^\*|^tmp|^data" "$DOCKERIGNORE_FILE"; then + echo "" + echo "WARNING: .dockerignore file detected at ${DOCKERIGNORE_FILE}" + echo "It may exclude the '${BUILD_DATA_DIR_NAME}' directory from build context." + echo "If build fails with 'COPY failed', add exception to .dockerignore:" + echo " !docker/src/main/${BUILD_DATA_DIR_NAME}/" + echo "" + fi +fi + +# Cleanup function cleanup() { - echo "Cleaning up temporary data directory..." + echo "Cleaning up temporary data directory: ${TMP_DATA_DIR}" rm -rf "$TMP_DATA_DIR" } trap cleanup EXIT +# Verify Dockerfile exists +DOCKERFILE="${SCRIPT_DIR}/Dockerfile-2.0.x-ainode" +if [ ! -f "$DOCKERFILE" ]; then + echo "Error: Dockerfile not found at: ${DOCKERFILE}" + exit 1 +fi + # Build Docker image # Build context is PROJECT_ROOT (3 levels up from current script) BUILD_CMD="docker build" -BUILD_CMD+=" --file ${SCRIPT_DIR}/Dockerfile-2.0.7-ainode" +BUILD_CMD+=" --file ${DOCKERFILE}" BUILD_CMD+=" --build-arg VERSION=${VERSION}" BUILD_CMD+=" --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" BUILD_CMD+=" --build-arg VCS_REF=$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" @@ -197,9 +228,19 @@ fi BUILD_CMD+=" --tag ${FULL_IMAGE_NAME}" BUILD_CMD+=" ${PROJECT_ROOT}" -echo "Executing: ${BUILD_CMD}" +echo "" +echo "Executing Docker build..." +echo "Command: ${BUILD_CMD}" +echo "" + ${BUILD_CMD} || { + echo "" echo "Error: Docker build failed" + echo "" + echo "Troubleshooting tips:" + echo "1. If error is 'COPY failed: no such file or directory', check if .dockerignore excludes 'docker/src/main/${BUILD_DATA_DIR_NAME}/'" + echo "2. Ensure Docker daemon is running" + echo "3. Try running with --no-cache option" exit 1 }