diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 00000000000..fa5e3e35089
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,288 @@
+# Apache Ambari Docker Setup
+
+This directory contains Docker configurations for Apache Ambari, providing containerized environments for development, testing, and production deployment.
+
+## Quick Start
+
+### Prerequisites
+- Docker 20.10+
+- Docker Compose 2.0+
+- At least 8GB RAM available for Docker
+
+### Development Environment
+```bash
+# Clone and build Ambari
+git clone https://github.com/apache/ambari.git
+cd ambari
+
+# Start development environment
+docker-compose -f docker/docker-compose.dev.yml up -d
+
+# Access Ambari Web UI
+open http://localhost:8080
+# Default credentials: admin/admin
+```
+
+### Production Deployment
+```bash
+# Start production stack
+docker-compose -f docker/docker-compose.prod.yml up -d
+
+# Scale agents
+docker-compose -f docker/docker-compose.prod.yml up -d --scale ambari-agent=3
+```
+
+## Available Images
+
+### Base Images
+- `apache/ambari-base`: Common runtime dependencies
+- `apache/ambari-build`: Build environment with Maven, JDK, Node.js
+
+### Service Images
+- `apache/ambari-server`: Ambari Server
+- `apache/ambari-agent`: Ambari Agent
+- `apache/ambari-metrics`: Metrics Collector with embedded HBase
+- `apache/ambari-dev`: Development environment
+
+### Supporting Images
+- `apache/ambari-database`: PostgreSQL with Ambari schema
+- `apache/ambari-grafana`: Grafana with Ambari Metrics datasource
+
+## Build Instructions
+
+### Build All Images
+```bash
+# Build all images
+./docker/build.sh
+
+# Build specific image
+./docker/build.sh ambari-server
+
+# Build with custom tag
+./docker/build.sh ambari-server --tag myregistry/ambari-server:latest
+```
+
+### Development Build
+```bash
+# Build development image with current source
+docker build -f docker/Dockerfile.dev -t ambari-dev .
+
+# Run development container
+docker run -it --rm \
+ -v $(pwd):/workspace \
+ -p 8080:8080 \
+ -p 8441:8441 \
+ ambari-dev
+```
+
+## Configuration
+
+### Environment Variables
+
+#### Ambari Server
+- `AMBARI_DB_HOST`: Database hostname (default: ambari-db)
+- `AMBARI_DB_PORT`: Database port (default: 5432)
+- `AMBARI_DB_NAME`: Database name (default: ambari)
+- `AMBARI_DB_USER`: Database user (default: ambari)
+- `AMBARI_DB_PASSWORD`: Database password (default: bigdata)
+- `AMBARI_SERVER_HTTPS`: Enable HTTPS (default: false)
+- `JAVA_OPTS`: JVM options
+
+#### Ambari Agent
+- `AMBARI_SERVER_HOST`: Ambari Server hostname (default: ambari-server)
+- `AMBARI_SERVER_PORT`: Ambari Server port (default: 8080)
+- `AGENT_HOSTNAME`: Agent hostname (auto-detected if not set)
+
+#### Ambari Metrics
+- `AMS_HBASE_ROOTDIR`: HBase root directory (default: /var/lib/ambari-metrics-collector/hbase)
+- `AMS_COLLECTOR_PORT`: Collector port (default: 6188)
+- `AMS_GRAFANA_ENABLED`: Enable Grafana (default: true)
+
+### Volume Mounts
+
+#### Persistent Data
+- `/var/lib/ambari-server`: Server data and configurations
+- `/var/lib/ambari-agent`: Agent data and logs
+- `/var/lib/ambari-metrics-collector`: Metrics data
+- `/var/log/ambari-*`: Log directories
+
+#### Development
+- `/workspace`: Source code mount point
+- `/root/.m2`: Maven repository cache
+
+## Docker Compose Configurations
+
+### Development (docker-compose.dev.yml)
+- Single-node setup with all services
+- Source code mounted for live development
+- Debug ports exposed
+- Automatic rebuilding enabled
+
+### Production (docker-compose.prod.yml)
+- Multi-container production setup
+- Separate database container
+- Health checks and restart policies
+- Resource limits configured
+
+### Testing (docker-compose.test.yml)
+- Automated testing environment
+- Includes test databases and mock services
+- CI/CD friendly configuration
+
+## Networking
+
+### Default Network
+- Network: `ambari-network` (bridge)
+- Subnet: `172.20.0.0/16`
+
+### Service Discovery
+Services are accessible by their container names:
+- `ambari-server`: Ambari Server
+- `ambari-db`: PostgreSQL Database
+- `ambari-metrics`: Metrics Collector
+- `ambari-grafana`: Grafana Dashboard
+
+## Health Checks
+
+All services include health checks:
+- **Server**: HTTP check on `/api/v1/clusters`
+- **Agent**: Process and heartbeat check
+- **Metrics**: HTTP check on `/ws/v1/timeline/metrics`
+- **Database**: Connection check
+
+## Troubleshooting
+
+### Common Issues
+
+#### Container Won't Start
+```bash
+# Check logs
+docker-compose logs ambari-server
+
+# Check container status
+docker-compose ps
+
+# Restart specific service
+docker-compose restart ambari-server
+```
+
+#### Database Connection Issues
+```bash
+# Verify database is running
+docker-compose exec ambari-db pg_isready
+
+# Check database logs
+docker-compose logs ambari-db
+
+# Reset database
+docker-compose down -v
+docker-compose up -d ambari-db
+```
+
+#### Memory Issues
+```bash
+# Check resource usage
+docker stats
+
+# Increase memory limits in docker-compose.yml
+services:
+ ambari-server:
+ mem_limit: 4g
+```
+
+### Debug Mode
+
+#### Enable Debug Logging
+```bash
+# Set environment variable
+export AMBARI_DEBUG=true
+docker-compose up -d
+
+# Or in docker-compose.yml
+environment:
+ - AMBARI_DEBUG=true
+```
+
+#### Remote Debugging
+```bash
+# Server debug port: 5005
+# Agent debug port: 5006
+
+# Connect with IDE to localhost:5005
+```
+
+## Security Considerations
+
+### Production Deployment
+1. Change default passwords
+2. Use external database with proper credentials
+3. Enable HTTPS/TLS
+4. Configure firewall rules
+5. Use secrets management
+6. Regular security updates
+
+### Network Security
+```yaml
+# Example secure configuration
+services:
+ ambari-server:
+ environment:
+ - AMBARI_DB_PASSWORD_FILE=/run/secrets/db_password
+ secrets:
+ - db_password
+
+secrets:
+ db_password:
+ external: true
+```
+
+## Performance Tuning
+
+### Resource Allocation
+```yaml
+# Recommended production resources
+services:
+ ambari-server:
+ mem_limit: 4g
+ cpus: 2.0
+
+ ambari-metrics:
+ mem_limit: 2g
+ cpus: 1.0
+```
+
+### JVM Tuning
+```bash
+# Server JVM options
+JAVA_OPTS="-Xmx2g -Xms1g -XX:+UseG1GC"
+
+# Metrics JVM options
+AMS_JAVA_OPTS="-Xmx1g -Xms512m"
+```
+
+## Contributing
+
+### Adding New Services
+1. Create Dockerfile in `docker/services/`
+2. Add to appropriate docker-compose file
+3. Update documentation
+4. Add health checks
+5. Test thoroughly
+
+### Testing Changes
+```bash
+# Run test suite
+./docker/test.sh
+
+# Specific test
+./docker/test.sh integration
+
+# Clean test environment
+./docker/test.sh clean
+```
+
+## Support
+
+- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/)
+- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues)
+- **Community**: [Apache Ambari Mailing Lists](https://ambari.apache.org/mail-lists.html)
diff --git a/docker/build.sh b/docker/build.sh
new file mode 100755
index 00000000000..3f47132d53d
--- /dev/null
+++ b/docker/build.sh
@@ -0,0 +1,558 @@
+#!/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.
+#
+
+# Apache Ambari Docker Build Script
+# This script builds Docker images for Apache Ambari components
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Default configuration
+DEFAULT_REGISTRY="apache"
+DEFAULT_TAG="latest"
+DEFAULT_UBUNTU_VERSION="22.04"
+DEFAULT_JAVA_VERSION="11"
+DEFAULT_MAVEN_VERSION="3.9.6"
+DEFAULT_NODE_VERSION="18"
+
+# Script directory
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
+
+# Available images
+AVAILABLE_IMAGES=(
+ "base"
+ "server"
+ "agent"
+ "metrics"
+ "dev"
+ "all"
+)
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_debug() {
+ if [[ "${DEBUG:-false}" == "true" ]]; then
+ echo -e "${BLUE}[DEBUG]${NC} $1"
+ fi
+}
+
+# Function to show usage
+show_usage() {
+ cat << EOF
+Apache Ambari Docker Build Script
+
+Usage: $0 [OPTIONS] [IMAGE_NAME]
+
+Available Images:
+ base - Base image with common dependencies
+ server - Ambari Server image
+ agent - Ambari Agent image
+ metrics - Ambari Metrics Collector image
+ dev - Development environment image
+ all - Build all images
+
+Options:
+ -r, --registry REGISTRY Docker registry prefix (default: $DEFAULT_REGISTRY)
+ -t, --tag TAG Image tag (default: $DEFAULT_TAG)
+ --ubuntu-version VERSION Ubuntu base image version (default: $DEFAULT_UBUNTU_VERSION)
+ --java-version VERSION Java version (default: $DEFAULT_JAVA_VERSION)
+ --maven-version VERSION Maven version (default: $DEFAULT_MAVEN_VERSION)
+ --node-version VERSION Node.js version (default: $DEFAULT_NODE_VERSION)
+ --no-cache Build without using cache
+ --push Push images to registry after building
+ --parallel Build images in parallel (when building all)
+ --target TARGET Build specific target (runtime, build, development)
+ --platform PLATFORM Target platform (e.g., linux/amd64,linux/arm64)
+ -v, --verbose Enable verbose output
+ -h, --help Show this help message
+
+Examples:
+ $0 base # Build base image
+ $0 server --tag 3.0.0 # Build server image with custom tag
+ $0 all --registry myregistry --push # Build and push all images
+ $0 dev --no-cache --verbose # Build dev image without cache
+ $0 server --platform linux/amd64,linux/arm64 # Multi-platform build
+
+Environment Variables:
+ DOCKER_REGISTRY Default registry (overrides -r)
+ DOCKER_TAG Default tag (overrides -t)
+ DOCKER_BUILDKIT Enable BuildKit (recommended: 1)
+ DEBUG Enable debug output (true/false)
+
+EOF
+}
+
+# Function to parse command line arguments
+parse_args() {
+ REGISTRY="${DOCKER_REGISTRY:-$DEFAULT_REGISTRY}"
+ TAG="${DOCKER_TAG:-$DEFAULT_TAG}"
+ UBUNTU_VERSION="$DEFAULT_UBUNTU_VERSION"
+ JAVA_VERSION="$DEFAULT_JAVA_VERSION"
+ MAVEN_VERSION="$DEFAULT_MAVEN_VERSION"
+ NODE_VERSION="$DEFAULT_NODE_VERSION"
+ NO_CACHE=""
+ PUSH=false
+ PARALLEL=false
+ TARGET=""
+ PLATFORM=""
+ VERBOSE=false
+ IMAGE_NAME=""
+
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ -r|--registry)
+ REGISTRY="$2"
+ shift 2
+ ;;
+ -t|--tag)
+ TAG="$2"
+ shift 2
+ ;;
+ --ubuntu-version)
+ UBUNTU_VERSION="$2"
+ shift 2
+ ;;
+ --java-version)
+ JAVA_VERSION="$2"
+ shift 2
+ ;;
+ --maven-version)
+ MAVEN_VERSION="$2"
+ shift 2
+ ;;
+ --node-version)
+ NODE_VERSION="$2"
+ shift 2
+ ;;
+ --no-cache)
+ NO_CACHE="--no-cache"
+ shift
+ ;;
+ --push)
+ PUSH=true
+ shift
+ ;;
+ --parallel)
+ PARALLEL=true
+ shift
+ ;;
+ --target)
+ TARGET="$2"
+ shift 2
+ ;;
+ --platform)
+ PLATFORM="$2"
+ shift 2
+ ;;
+ -v|--verbose)
+ VERBOSE=true
+ DEBUG=true
+ shift
+ ;;
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ -*)
+ log_error "Unknown option: $1"
+ show_usage
+ exit 1
+ ;;
+ *)
+ if [[ -z "$IMAGE_NAME" ]]; then
+ IMAGE_NAME="$1"
+ else
+ log_error "Multiple image names specified: $IMAGE_NAME and $1"
+ exit 1
+ fi
+ shift
+ ;;
+ esac
+ done
+
+ # Validate image name
+ if [[ -z "$IMAGE_NAME" ]]; then
+ log_error "No image name specified"
+ show_usage
+ exit 1
+ fi
+
+ if [[ ! " ${AVAILABLE_IMAGES[@]} " =~ " ${IMAGE_NAME} " ]]; then
+ log_error "Invalid image name: $IMAGE_NAME"
+ log_error "Available images: ${AVAILABLE_IMAGES[*]}"
+ exit 1
+ fi
+}
+
+# Function to build Docker image
+build_image() {
+ local image_name=$1
+ local dockerfile=$2
+ local context=${3:-$PROJECT_ROOT}
+ local extra_args=("${@:4}")
+
+ local full_image_name="${REGISTRY}/ambari-${image_name}:${TAG}"
+
+ log_info "Building image: $full_image_name"
+ log_debug "Dockerfile: $dockerfile"
+ log_debug "Context: $context"
+
+ # Prepare build arguments
+ local build_args=(
+ "--build-arg" "UBUNTU_VERSION=$UBUNTU_VERSION"
+ "--build-arg" "JAVA_VERSION=$JAVA_VERSION"
+ "--build-arg" "MAVEN_VERSION=$MAVEN_VERSION"
+ "--build-arg" "NODE_VERSION=$NODE_VERSION"
+ )
+
+ # Add target if specified
+ if [[ -n "$TARGET" ]]; then
+ build_args+=("--target" "$TARGET")
+ fi
+
+ # Add platform if specified
+ if [[ -n "$PLATFORM" ]]; then
+ build_args+=("--platform" "$PLATFORM")
+ fi
+
+ # Add no-cache if specified
+ if [[ -n "$NO_CACHE" ]]; then
+ build_args+=("$NO_CACHE")
+ fi
+
+ # Add extra arguments
+ build_args+=("${extra_args[@]}")
+
+ # Build command
+ local build_cmd=(
+ "docker" "build"
+ "${build_args[@]}"
+ "-f" "$dockerfile"
+ "-t" "$full_image_name"
+ "$context"
+ )
+
+ if [[ "$VERBOSE" == "true" ]]; then
+ log_debug "Build command: ${build_cmd[*]}"
+ fi
+
+ # Execute build
+ if "${build_cmd[@]}"; then
+ log_info "Successfully built: $full_image_name"
+
+ # Push if requested
+ if [[ "$PUSH" == "true" ]]; then
+ log_info "Pushing image: $full_image_name"
+ if docker push "$full_image_name"; then
+ log_info "Successfully pushed: $full_image_name"
+ else
+ log_error "Failed to push: $full_image_name"
+ return 1
+ fi
+ fi
+
+ return 0
+ else
+ log_error "Failed to build: $full_image_name"
+ return 1
+ fi
+}
+
+# Function to build base image
+build_base() {
+ log_info "Building Ambari base image..."
+ build_image "base" "$SCRIPT_DIR/Dockerfile.base"
+}
+
+# Function to build server image
+build_server() {
+ log_info "Building Ambari server image..."
+
+ # Create server Dockerfile if it doesn't exist
+ local server_dockerfile="$SCRIPT_DIR/Dockerfile.server"
+ if [[ ! -f "$server_dockerfile" ]]; then
+ log_info "Creating server Dockerfile..."
+ cat > "$server_dockerfile" << 'EOF'
+# Apache Ambari Server Image
+FROM apache/ambari-base:latest as base
+
+# Switch to root for installation
+USER root
+
+# Install Ambari Server
+COPY ambari-server/target/rpm/ambari-server/RPMS/x86_64/*.rpm /tmp/
+RUN yum install -y /tmp/ambari-server-*.rpm && \
+ rm -f /tmp/*.rpm
+
+# Server configuration
+COPY docker/config/server/ /etc/ambari-server/conf/
+
+# Switch back to ambari user
+USER ambari
+
+# Expose server ports
+EXPOSE 8080 8441
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
+ CMD /usr/local/bin/health-check.sh
+
+# Default command
+CMD ["ambari-server", "start"]
+EOF
+ fi
+
+ build_image "server" "$server_dockerfile"
+}
+
+# Function to build agent image
+build_agent() {
+ log_info "Building Ambari agent image..."
+
+ # Create agent Dockerfile if it doesn't exist
+ local agent_dockerfile="$SCRIPT_DIR/Dockerfile.agent"
+ if [[ ! -f "$agent_dockerfile" ]]; then
+ log_info "Creating agent Dockerfile..."
+ cat > "$agent_dockerfile" << 'EOF'
+# Apache Ambari Agent Image
+FROM apache/ambari-base:latest as base
+
+# Switch to root for installation
+USER root
+
+# Install Ambari Agent
+COPY ambari-agent/target/rpm/ambari-agent/RPMS/x86_64/*.rpm /tmp/
+RUN yum install -y /tmp/ambari-agent-*.rpm && \
+ rm -f /tmp/*.rpm
+
+# Agent configuration
+COPY docker/config/agent/ /etc/ambari-agent/conf/
+
+# Switch back to ambari user
+USER ambari
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
+ CMD /usr/local/bin/health-check.sh
+
+# Default command
+CMD ["ambari-agent", "start"]
+EOF
+ fi
+
+ build_image "agent" "$agent_dockerfile"
+}
+
+# Function to build metrics image
+build_metrics() {
+ log_info "Building Ambari metrics image..."
+
+ # Create metrics Dockerfile if it doesn't exist
+ local metrics_dockerfile="$SCRIPT_DIR/Dockerfile.metrics"
+ if [[ ! -f "$metrics_dockerfile" ]]; then
+ log_info "Creating metrics Dockerfile..."
+ cat > "$metrics_dockerfile" << 'EOF'
+# Apache Ambari Metrics Image
+FROM apache/ambari-base:latest as base
+
+# Switch to root for installation
+USER root
+
+# Install Ambari Metrics packages
+COPY ambari-metrics/ambari-metrics-assembly/target/ambari-metrics-assembly-*.tar.gz /tmp/
+RUN cd /tmp && \
+ tar -xzf ambari-metrics-assembly-*.tar.gz && \
+ mv ambari-metrics-assembly-* /opt/ambari-metrics && \
+ rm -f /tmp/*.tar.gz
+
+# Metrics configuration
+COPY docker/config/metrics/ /etc/ambari-metrics-collector/conf/
+
+# Switch back to ambari user
+USER ambari
+
+# Expose metrics ports
+EXPOSE 6188 61888
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
+ CMD /usr/local/bin/health-check.sh
+
+# Default command
+CMD ["ambari-metrics-collector", "start"]
+EOF
+ fi
+
+ build_image "metrics" "$metrics_dockerfile"
+}
+
+# Function to build development image
+build_dev() {
+ log_info "Building Ambari development image..."
+ build_image "dev" "$SCRIPT_DIR/Dockerfile.base" "$PROJECT_ROOT" "--target" "build"
+}
+
+# Function to build all images
+build_all() {
+ log_info "Building all Ambari images..."
+
+ local images=("base" "server" "agent" "metrics" "dev")
+ local failed_images=()
+
+ if [[ "$PARALLEL" == "true" ]]; then
+ log_info "Building images in parallel..."
+ local pids=()
+
+ for image in "${images[@]}"; do
+ (
+ case $image in
+ "base") build_base ;;
+ "server") build_server ;;
+ "agent") build_agent ;;
+ "metrics") build_metrics ;;
+ "dev") build_dev ;;
+ esac
+ ) &
+ pids+=($!)
+ done
+
+ # Wait for all builds to complete
+ for i in "${!pids[@]}"; do
+ if ! wait "${pids[$i]}"; then
+ failed_images+=("${images[$i]}")
+ fi
+ done
+ else
+ log_info "Building images sequentially..."
+ for image in "${images[@]}"; do
+ case $image in
+ "base") build_base || failed_images+=("$image") ;;
+ "server") build_server || failed_images+=("$image") ;;
+ "agent") build_agent || failed_images+=("$image") ;;
+ "metrics") build_metrics || failed_images+=("$image") ;;
+ "dev") build_dev || failed_images+=("$image") ;;
+ esac
+ done
+ fi
+
+ # Report results
+ if [[ ${#failed_images[@]} -eq 0 ]]; then
+ log_info "All images built successfully!"
+ else
+ log_error "Failed to build images: ${failed_images[*]}"
+ return 1
+ fi
+}
+
+# Function to check prerequisites
+check_prerequisites() {
+ log_info "Checking prerequisites..."
+
+ # Check Docker
+ if ! command -v docker >/dev/null 2>&1; then
+ log_error "Docker is not installed or not in PATH"
+ exit 1
+ fi
+
+ # Check Docker daemon
+ if ! docker info >/dev/null 2>&1; then
+ log_error "Docker daemon is not running"
+ exit 1
+ fi
+
+ # Check BuildKit (recommended)
+ if [[ "${DOCKER_BUILDKIT:-}" != "1" ]]; then
+ log_warn "DOCKER_BUILDKIT is not enabled. Consider setting DOCKER_BUILDKIT=1 for better performance"
+ fi
+
+ # Check project structure
+ if [[ ! -f "$PROJECT_ROOT/pom.xml" ]]; then
+ log_error "Not in Ambari project root directory"
+ exit 1
+ fi
+
+ log_info "Prerequisites check passed"
+}
+
+# Main function
+main() {
+ log_info "Apache Ambari Docker Build Script"
+ log_info "================================"
+
+ # Parse arguments
+ parse_args "$@"
+
+ # Check prerequisites
+ check_prerequisites
+
+ # Show configuration
+ log_info "Configuration:"
+ log_info " Registry: $REGISTRY"
+ log_info " Tag: $TAG"
+ log_info " Ubuntu Version: $UBUNTU_VERSION"
+ log_info " Java Version: $JAVA_VERSION"
+ log_info " Maven Version: $MAVEN_VERSION"
+ log_info " Node.js Version: $NODE_VERSION"
+ log_info " Image: $IMAGE_NAME"
+ if [[ -n "$TARGET" ]]; then
+ log_info " Target: $TARGET"
+ fi
+ if [[ -n "$PLATFORM" ]]; then
+ log_info " Platform: $PLATFORM"
+ fi
+ log_info ""
+
+ # Build image(s)
+ case $IMAGE_NAME in
+ "base") build_base ;;
+ "server") build_server ;;
+ "agent") build_agent ;;
+ "metrics") build_metrics ;;
+ "dev") build_dev ;;
+ "all") build_all ;;
+ *)
+ log_error "Unknown image: $IMAGE_NAME"
+ exit 1
+ ;;
+ esac
+
+ log_info "Build completed successfully!"
+}
+
+# Run main function
+main "$@"
diff --git a/docker/config/agent/ambari-agent.ini b/docker/config/agent/ambari-agent.ini
new file mode 100644
index 00000000000..96420480154
--- /dev/null
+++ b/docker/config/agent/ambari-agent.ini
@@ -0,0 +1,24 @@
+[server]
+hostname=ambari-server
+url_port=8080
+secured_url_port=8441
+
+[agent]
+prefix=/var/lib/ambari-agent/data
+cache_dir=/var/lib/ambari-agent/cache
+log_dir=/var/log/ambari-agent
+pidfile=/var/run/ambari-agent/ambari-agent.pid
+hostname_script=/var/lib/ambari-agent/hostname.sh
+
+[security]
+keysdir=/var/lib/ambari-agent/keys
+server_crt=ca.crt
+passphrase_env_var_name=AMBARI_PASSPHRASE
+
+[heartbeat]
+state_interval=6
+dirs=/etc/hadoop,/etc/hadoop/conf,/etc/hbase,/etc/hcatalog,/etc/hive,/etc/oozie,/etc/sqloop,/var/run/hadoop,/var/run/zookeeper,/var/run/hbase,/var/run/hive,/var/run/oozie,/var/log/hadoop,/var/log/zookeeper,/var/log/hbase,/var/log/hive,/var/log/oozie
+rpms=hadoop,zookeeper,hbase,hive
+
+[logging]
+syslog_enabled=0
diff --git a/docker/config/metrics/ams-site.xml b/docker/config/metrics/ams-site.xml
new file mode 100644
index 00000000000..8a3dba92ce6
--- /dev/null
+++ b/docker/config/metrics/ams-site.xml
@@ -0,0 +1,62 @@
+
+
+
+ timeline.service.address
+ 0.0.0.0:6188
+ Timeline service address
+
+
+
+ timeline.service.webapp.address
+ 0.0.0.0:6188
+ Timeline service webapp address
+
+
+
+ timeline.service.webapp.https.address
+ 0.0.0.0:61889
+ Timeline service webapp https address
+
+
+
+ timeline.metrics.service.default.result.limit
+ 15840
+ Default limit of number of result rows
+
+
+
+ timeline.metrics.service.checkpointDelay
+ 60
+ Time in seconds to sleep on the first run or when the checkpoint directory is empty
+
+
+
+ timeline.metrics.service.resultset.fetchSize
+ 2000
+ JDBC resultset fetch size
+
+
+
+ timeline.metrics.cluster.aggregator.hourly.interval
+ 3600
+ Time in seconds to aggregate hourly data
+
+
+
+ timeline.metrics.cluster.aggregator.daily.interval
+ 86400
+ Time in seconds to aggregate daily data
+
+
+
+ timeline.metrics.host.aggregator.hourly.interval
+ 3600
+ Time in seconds to aggregate hourly host data
+
+
+
+ timeline.metrics.host.aggregator.daily.interval
+ 86400
+ Time in seconds to aggregate daily host data
+
+
diff --git a/docker/config/server/ambari.properties b/docker/config/server/ambari.properties
new file mode 100644
index 00000000000..7c9572cdde1
--- /dev/null
+++ b/docker/config/server/ambari.properties
@@ -0,0 +1,37 @@
+# Apache Ambari Server Configuration
+# This file contains default configuration for Ambari Server in Docker
+
+# Database Configuration
+server.jdbc.driver=org.postgresql.Driver
+server.jdbc.url=jdbc:postgresql://ambari-db:5432/ambari
+server.jdbc.user.name=ambari
+server.jdbc.user.passwd=bigdata
+
+# Server Configuration
+server.persistence.type=remote
+server.connection.max.idle.millis=900000
+
+# Security Configuration
+security.server.two_way_ssl=false
+security.server.cert_name=ca.crt
+security.server.key_name=ca.key
+
+# API Configuration
+api.authenticated.user=admin
+api.ssl=false
+
+# Views Configuration
+views.dir=/var/lib/ambari-server/resources/views
+views.validate=false
+
+# Logging Configuration
+logging.level.root=INFO
+logging.level.org.apache.ambari=INFO
+
+# Cluster Configuration
+cluster.monitoring.enabled=true
+cluster.secured.state=UNSECURED
+
+# Agent Configuration
+agent.package.install.task.timeout=1800
+agent.task.timeout=900
diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml
new file mode 100644
index 00000000000..3bef09a5897
--- /dev/null
+++ b/docker/docker-compose.dev.yml
@@ -0,0 +1,303 @@
+# Apache Ambari Development Docker Compose Configuration
+# This configuration provides a complete development environment for Ambari
+
+version: '3.8'
+
+services:
+ # PostgreSQL Database for Ambari
+ ambari-db:
+ image: postgres:15-alpine
+ container_name: ambari-db
+ hostname: ambari-db
+ environment:
+ POSTGRES_DB: ambari
+ POSTGRES_USER: ambari
+ POSTGRES_PASSWORD: bigdata
+ POSTGRES_INITDB_ARGS: "--encoding=UTF8"
+ volumes:
+ - ambari-db-data:/var/lib/postgresql/data
+ - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
+ ports:
+ - "5432:5432"
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ restart: unless-stopped
+
+ # Ambari Server
+ ambari-server:
+ build:
+ context: ..
+ dockerfile: docker/images/ambari/Dockerfile.server
+ target: development
+ args:
+ - UBUNTU_VERSION=22.04
+ - JAVA_VERSION=8
+ - MAVEN_VERSION=3.9.6
+ container_name: ambari-server
+ hostname: ambari-server
+ environment:
+ # Database configuration
+ - AMBARI_DB_HOST=ambari-db
+ - AMBARI_DB_PORT=5432
+ - AMBARI_DB_NAME=ambari
+ - AMBARI_DB_USER=ambari
+ - AMBARI_DB_PASSWORD=bigdata
+
+ # Server configuration
+ - AMBARI_SERVER_HTTPS=false
+ - AMBARI_COMPONENT=server
+
+ # Development settings
+ - AMBARI_DEBUG=true
+ - MAVEN_OPTS=-Xmx2g -XX:+UseG1GC
+ - JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
+ volumes:
+ # Source code mount for live development
+ - ../:/workspace:cached
+ - ambari-server-data:/var/lib/ambari-server
+ - ambari-server-logs:/var/log/ambari-server
+ - ambari-server-conf:/etc/ambari-server/conf
+ # Maven cache for faster builds
+ - maven-cache:/home/ambari/.m2
+ # SSH keys for multi-node communication
+ - ssh-keys:/home/ambari/.ssh
+ ports:
+ - "8080:8080" # Ambari Web UI
+ - "8441:8441" # Ambari HTTPS
+ - "5005:5005" # Java Debug Port
+ networks:
+ - ambari-network
+ depends_on:
+ ambari-db:
+ condition: service_healthy
+ healthcheck:
+ test: ["CMD", "/usr/local/bin/health-check.sh"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 120s
+ restart: unless-stopped
+ stdin_open: true
+ tty: true
+
+ # Ambari Agent (can be scaled)
+ ambari-agent:
+ build:
+ context: ..
+ dockerfile: docker/images/ambari/Dockerfile.agent
+ target: development
+ args:
+ - UBUNTU_VERSION=22.04
+ - JAVA_VERSION=8
+ container_name: ambari-agent-1
+ hostname: ambari-agent-1
+ environment:
+ # Server connection
+ - AMBARI_SERVER_HOST=ambari-server
+ - AMBARI_SERVER_PORT=8080
+ - AMBARI_COMPONENT=agent
+
+ # Agent configuration
+ - AGENT_HOSTNAME=ambari-agent-1
+
+ # Development settings
+ - AMBARI_DEBUG=true
+ - JAVA_OPTS=-Xmx1g -Xms512m -XX:+UseG1GC -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006
+ volumes:
+ # Source code mount for development
+ - ../:/workspace:cached
+ - ambari-agent-data:/var/lib/ambari-agent
+ - ambari-agent-logs:/var/log/ambari-agent
+ - ambari-agent-conf:/etc/ambari-agent/conf
+ # Shared SSH keys
+ - ssh-keys:/home/ambari/.ssh:ro
+ ports:
+ - "5006:5006" # Java Debug Port
+ networks:
+ - ambari-network
+ depends_on:
+ - ambari-server
+ healthcheck:
+ test: ["CMD", "/usr/local/bin/health-check.sh"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+ privileged: true # Required for some agent operations
+ stdin_open: true
+ tty: true
+
+ # Ambari Metrics Collector (Optional - controlled by METRICS_ENABLED)
+ ambari-metrics:
+ build:
+ context: ..
+ dockerfile: docker/images/ambari-metrics/Dockerfile
+ target: development
+ args:
+ - UBUNTU_VERSION=22.04
+ - JAVA_VERSION=8
+ container_name: ambari-metrics
+ hostname: ambari-metrics
+ environment:
+ # Metrics configuration
+ - AMS_HBASE_ROOTDIR=/var/lib/ambari-metrics-collector/hbase
+ - AMS_COLLECTOR_PORT=6188
+ - AMS_GRAFANA_ENABLED=true
+ - AMBARI_COMPONENT=metrics
+
+ # Development settings
+ - AMBARI_DEBUG=true
+ - AMS_JAVA_OPTS=-Xmx1g -Xms512m -XX:+UseG1GC
+ volumes:
+ # Source code mount for development
+ - ../:/workspace:cached
+ - ambari-metrics-data:/var/lib/ambari-metrics-collector
+ - ambari-metrics-logs:/var/log/ambari-metrics-collector
+ - ambari-metrics-conf:/etc/ambari-metrics-collector/conf
+ ports:
+ - "6188:6188" # Metrics Collector API
+ - "61888:61888" # Metrics aggregation port
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD", "/usr/local/bin/health-check.sh"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 90s
+ restart: unless-stopped
+ stdin_open: true
+ tty: true
+ profiles:
+ - metrics
+ deploy:
+ replicas: ${METRICS_ENABLED:-0} # Default to 0, meaning metrics won't start unless METRICS_ENABLED is set
+
+ # Grafana for Metrics Visualization (Optional - controlled by GRAFANA_ENABLED)
+ grafana:
+ image: grafana/grafana:10.2.0
+ container_name: ambari-grafana
+ hostname: grafana
+ environment:
+ - GF_SECURITY_ADMIN_PASSWORD=admin
+ - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
+ - GF_USERS_ALLOW_SIGN_UP=false
+ - GF_SERVER_ROOT_URL=http://localhost:3000
+ volumes:
+ - grafana-data:/var/lib/grafana
+ - ./config/grafana/provisioning:/etc/grafana/provisioning:ro
+ - ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro
+ ports:
+ - "3000:3000" # Grafana Web UI
+ networks:
+ - ambari-network
+ depends_on:
+ - ambari-metrics
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 30s
+ restart: unless-stopped
+ profiles:
+ - metrics
+ deploy:
+ replicas: ${GRAFANA_ENABLED:-0} # Default to 0, controlled by GRAFANA_ENABLED
+
+ # Development Tools Container
+ dev-tools:
+ build:
+ context: ..
+ dockerfile: docker/images/ambari-base/Dockerfile
+ target: build
+ container_name: ambari-dev-tools
+ hostname: dev-tools
+ environment:
+ - AMBARI_DEBUG=true
+ volumes:
+ # Source code mount
+ - ../:/workspace:cached
+ # Maven cache
+ - maven-cache:/home/ambari/.m2
+ # Build artifacts
+ - build-cache:/workspace/target
+ working_dir: /workspace
+ networks:
+ - ambari-network
+ profiles:
+ - dev-tools
+ stdin_open: true
+ tty: true
+ command: ["bash"]
+
+# Networks
+networks:
+ ambari-network:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.20.0.0/16
+
+# Volumes
+volumes:
+ # Database
+ ambari-db-data:
+ driver: local
+
+ # Ambari Server
+ ambari-server-data:
+ driver: local
+ ambari-server-logs:
+ driver: local
+ ambari-server-conf:
+ driver: local
+
+ # Ambari Agent
+ ambari-agent-data:
+ driver: local
+ ambari-agent-logs:
+ driver: local
+ ambari-agent-conf:
+ driver: local
+
+ # Ambari Metrics
+ ambari-metrics-data:
+ driver: local
+ ambari-metrics-logs:
+ driver: local
+ ambari-metrics-conf:
+ driver: local
+
+ # Grafana
+ grafana-data:
+ driver: local
+
+ # Shared volumes
+ maven-cache:
+ driver: local
+ ssh-keys:
+ driver: local
+ build-cache:
+ driver: local
+
+# Development specific configurations
+x-development-overrides:
+ # Common development settings
+ &dev-common
+ restart: "no" # Don't restart automatically in dev
+
+ # Volume mount for live development
+ &source-mount
+ - ../:/workspace:cached
+
+ # Debug port configuration
+ &debug-ports
+ - "5005:5005" # Server debug
+ - "5006:5006" # Agent debug
diff --git a/docker/docker-compose.minimal.yml b/docker/docker-compose.minimal.yml
new file mode 100644
index 00000000000..3d01f1e7104
--- /dev/null
+++ b/docker/docker-compose.minimal.yml
@@ -0,0 +1,102 @@
+# Minimal Apache Ambari Docker Compose Configuration
+# This setup focuses on core infrastructure that works on ARM64 Macs
+
+version: '3.8'
+
+services:
+ # PostgreSQL Database for Ambari
+ ambari-db:
+ image: postgres:15-alpine
+ container_name: ambari-database
+ hostname: ambari-db
+ environment:
+ POSTGRES_DB: ambari
+ POSTGRES_USER: ambari
+ POSTGRES_PASSWORD: bigdata
+ POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
+ volumes:
+ - ambari-db-data:/var/lib/postgresql/data
+ - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
+ ports:
+ - "5433:5432" # Changed port to avoid conflicts
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_period: 30s
+ restart: unless-stopped
+
+ # Zookeeper for coordination
+ zookeeper:
+ image: confluentinc/cp-zookeeper:7.4.0
+ container_name: ambari-zookeeper
+ hostname: zookeeper
+ environment:
+ ZOOKEEPER_CLIENT_PORT: 2181
+ ZOOKEEPER_TICK_TIME: 2000
+ ZOOKEEPER_INIT_LIMIT: 5
+ ZOOKEEPER_SYNC_LIMIT: 2
+ volumes:
+ - zookeeper-data:/var/lib/zookeeper/data
+ - zookeeper-logs:/var/lib/zookeeper/log
+ ports:
+ - "2182:2181" # Changed port to avoid conflicts
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD", "nc", "-z", "localhost", "2181"]
+ interval: 10s
+ timeout: 5s
+ retries: 3
+ start_period: 30s
+ restart: unless-stopped
+
+ # Grafana for visualization
+ grafana:
+ image: grafana/grafana:10.2.0
+ container_name: ambari-grafana-test
+ hostname: grafana
+ environment:
+ - GF_SECURITY_ADMIN_PASSWORD=admin
+ - GF_USERS_ALLOW_SIGN_UP=false
+ - GF_SERVER_ROOT_URL=http://localhost:3002
+ volumes:
+ - grafana-data:/var/lib/grafana
+ ports:
+ - "3002:3000" # Changed port to avoid conflicts
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 30s
+ restart: unless-stopped
+
+# Networks
+networks:
+ ambari-network:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.21.0.0/16
+
+# Volumes
+volumes:
+ # Database
+ ambari-db-data:
+ driver: local
+
+ # Zookeeper
+ zookeeper-data:
+ driver: local
+ zookeeper-logs:
+ driver: local
+
+ # Grafana
+ grafana-data:
+ driver: local
diff --git a/docker/docker-compose.simple.yml b/docker/docker-compose.simple.yml
new file mode 100644
index 00000000000..d268710d0dd
--- /dev/null
+++ b/docker/docker-compose.simple.yml
@@ -0,0 +1,191 @@
+# Simplified Apache Ambari Docker Compose Configuration
+# This setup uses existing images and focuses on getting Ambari running quickly
+
+version: '3.8'
+
+services:
+ # PostgreSQL Database for Ambari
+ ambari-db:
+ image: postgres:15-alpine
+ container_name: ambari-database
+ hostname: ambari-db
+ environment:
+ POSTGRES_DB: ambari
+ POSTGRES_USER: ambari
+ POSTGRES_PASSWORD: bigdata
+ POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
+ volumes:
+ - ambari-db-data:/var/lib/postgresql/data
+ - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
+ ports:
+ - "5432:5432"
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_period: 30s
+ restart: unless-stopped
+
+ # Zookeeper for coordination
+ zookeeper:
+ image: confluentinc/cp-zookeeper:7.4.0
+ container_name: ambari-zookeeper
+ hostname: zookeeper
+ environment:
+ ZOOKEEPER_CLIENT_PORT: 2181
+ ZOOKEEPER_TICK_TIME: 2000
+ ZOOKEEPER_INIT_LIMIT: 5
+ ZOOKEEPER_SYNC_LIMIT: 2
+ volumes:
+ - zookeeper-data:/var/lib/zookeeper/data
+ - zookeeper-logs:/var/lib/zookeeper/log
+ ports:
+ - "2181:2181"
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD", "nc", "-z", "localhost", "2181"]
+ interval: 10s
+ timeout: 5s
+ retries: 3
+ start_period: 30s
+ restart: unless-stopped
+
+ # Hadoop NameNode
+ namenode:
+ image: apache/hadoop:3.3.6
+ container_name: hadoop-namenode
+ hostname: namenode
+ environment:
+ - CLUSTER_NAME=ambari-cluster
+ - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
+ - CORE_CONF_hadoop_http_staticuser_user=root
+ - HDFS_CONF_dfs_webhdfs_enabled=true
+ - HDFS_CONF_dfs_permissions_enabled=false
+ - HDFS_CONF_dfs_replication=1
+ volumes:
+ - namenode-data:/hadoop/dfs/name
+ ports:
+ - "9870:9870" # NameNode Web UI
+ - "9001:9000" # NameNode IPC (changed to avoid conflict)
+ networks:
+ - ambari-network
+ command: ["hdfs", "namenode"]
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:9870"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+
+ # Hadoop DataNode
+ datanode:
+ image: apache/hadoop:3.3.6
+ container_name: hadoop-datanode
+ hostname: datanode
+ depends_on:
+ namenode:
+ condition: service_healthy
+ environment:
+ - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
+ - HDFS_CONF_dfs_webhdfs_enabled=true
+ - HDFS_CONF_dfs_permissions_enabled=false
+ - HDFS_CONF_dfs_datanode_use_datanode_hostname=false
+ volumes:
+ - datanode-data:/hadoop/dfs/data
+ ports:
+ - "9864:9864" # DataNode Web UI
+ networks:
+ - ambari-network
+ command: ["hdfs", "datanode"]
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:9864"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+
+ # YARN ResourceManager
+ resourcemanager:
+ image: apache/hadoop:3.3.6
+ container_name: hadoop-resourcemanager
+ hostname: resourcemanager
+ depends_on:
+ namenode:
+ condition: service_healthy
+ environment:
+ - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
+ - YARN_CONF_yarn_resourcemanager_hostname=resourcemanager
+ - YARN_CONF_yarn_resourcemanager_address=resourcemanager:8032
+ - YARN_CONF_yarn_resourcemanager_webapp_address=resourcemanager:8088
+ ports:
+ - "8088:8088" # ResourceManager Web UI
+ - "8032:8032" # ResourceManager IPC
+ networks:
+ - ambari-network
+ command: ["yarn", "resourcemanager"]
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:8088"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+
+ # Grafana for visualization
+ grafana:
+ image: grafana/grafana:10.2.0
+ container_name: ambari-grafana
+ hostname: grafana
+ environment:
+ - GF_SECURITY_ADMIN_PASSWORD=admin
+ - GF_USERS_ALLOW_SIGN_UP=false
+ - GF_SERVER_ROOT_URL=http://localhost:3000
+ volumes:
+ - grafana-data:/var/lib/grafana
+ ports:
+ - "3001:3000" # Changed to avoid conflict with existing Grafana
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 30s
+ restart: unless-stopped
+
+# Networks
+networks:
+ ambari-network:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.20.0.0/16
+
+# Volumes
+volumes:
+ # Database
+ ambari-db-data:
+ driver: local
+
+ # Zookeeper
+ zookeeper-data:
+ driver: local
+ zookeeper-logs:
+ driver: local
+
+ # Hadoop
+ namenode-data:
+ driver: local
+ datanode-data:
+ driver: local
+
+ # Grafana
+ grafana-data:
+ driver: local
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
new file mode 100644
index 00000000000..d6c16a914a0
--- /dev/null
+++ b/docker/docker-compose.yml
@@ -0,0 +1,396 @@
+# Apache Ambari Production Docker Compose Configuration
+# Based on best practices from Apache Pinot and other Apache projects
+
+version: '3.8'
+
+services:
+ # Zookeeper for coordination (following Pinot pattern)
+ zookeeper:
+ image: confluentinc/cp-zookeeper:7.4.0
+ container_name: ambari-zookeeper
+ hostname: zookeeper
+ environment:
+ ZOOKEEPER_CLIENT_PORT: 2181
+ ZOOKEEPER_TICK_TIME: 2000
+ ZOOKEEPER_INIT_LIMIT: 5
+ ZOOKEEPER_SYNC_LIMIT: 2
+ ZOOKEEPER_MAX_CLIENT_CNXNS: 60
+ ZOOKEEPER_AUTOPURGE_SNAP_RETAIN_COUNT: 3
+ ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL: 24
+ volumes:
+ - zookeeper-data:/var/lib/zookeeper/data
+ - zookeeper-logs:/var/lib/zookeeper/log
+ ports:
+ - "2181:2181"
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD", "nc", "-z", "localhost", "2181"]
+ interval: 10s
+ timeout: 5s
+ retries: 3
+ start_period: 30s
+ restart: unless-stopped
+
+ # PostgreSQL Database for Ambari
+ ambari-db:
+ image: postgres:15-alpine
+ container_name: ambari-database
+ hostname: ambari-db
+ environment:
+ POSTGRES_DB: ambari
+ POSTGRES_USER: ambari
+ POSTGRES_PASSWORD: bigdata
+ POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
+ PGDATA: /var/lib/postgresql/data/pgdata
+ volumes:
+ - ambari-db-data:/var/lib/postgresql/data
+ - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
+ ports:
+ - "5432:5432"
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+ start_period: 30s
+ restart: unless-stopped
+ command: >
+ postgres
+ -c max_connections=200
+ -c shared_buffers=256MB
+ -c effective_cache_size=1GB
+ -c maintenance_work_mem=64MB
+ -c checkpoint_completion_target=0.9
+ -c wal_buffers=16MB
+ -c default_statistics_target=100
+
+ # Ambari Server
+ ambari-server:
+ build:
+ context: ..
+ dockerfile: docker/Dockerfile.server
+ target: runtime
+ args:
+ - UBUNTU_VERSION=22.04
+ - JAVA_VERSION=11
+ - MAVEN_VERSION=3.9.6
+ container_name: ambari-server
+ hostname: ambari-server
+ depends_on:
+ ambari-db:
+ condition: service_healthy
+ zookeeper:
+ condition: service_healthy
+ environment:
+ # Database configuration
+ - AMBARI_DB_HOST=ambari-db
+ - AMBARI_DB_PORT=5432
+ - AMBARI_DB_NAME=ambari
+ - AMBARI_DB_USER=ambari
+ - AMBARI_DB_PASSWORD=bigdata
+
+ # Server configuration
+ - AMBARI_SERVER_HTTPS=false
+ - AMBARI_COMPONENT=server
+
+ # JVM configuration (following Pinot pattern)
+ - JAVA_OPTS=-Xmx4G -Xms2G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+UseZGC
+
+ # Zookeeper configuration
+ - AMBARI_ZK_CONNECT=zookeeper:2181
+ volumes:
+ - ambari-server-data:/var/lib/ambari-server
+ - ambari-server-logs:/var/log/ambari-server
+ - ambari-server-conf:/etc/ambari-server/conf
+ ports:
+ - "8080:8080" # Ambari Web UI
+ - "8441:8441" # Ambari HTTPS
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD", "/usr/local/bin/health-check.sh", "server"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 120s
+ restart: unless-stopped
+ deploy:
+ resources:
+ limits:
+ memory: 6G
+ cpus: '2.0'
+ reservations:
+ memory: 4G
+ cpus: '1.0'
+
+ # Ambari Agent (scalable)
+ ambari-agent:
+ build:
+ context: ..
+ dockerfile: docker/Dockerfile.agent
+ target: runtime
+ args:
+ - UBUNTU_VERSION=22.04
+ - JAVA_VERSION=11
+ hostname: ambari-agent-{{.Task.Slot}}
+ depends_on:
+ ambari-server:
+ condition: service_healthy
+ environment:
+ # Server connection
+ - AMBARI_SERVER_HOST=ambari-server
+ - AMBARI_SERVER_PORT=8080
+ - AMBARI_COMPONENT=agent
+
+ # JVM configuration
+ - JAVA_OPTS=-Xmx2G -Xms1G -XX:+UseG1GC -XX:MaxGCPauseMillis=200
+ volumes:
+ - ambari-agent-data:/var/lib/ambari-agent
+ - ambari-agent-logs:/var/log/ambari-agent
+ - ambari-agent-conf:/etc/ambari-agent/conf
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD", "/usr/local/bin/health-check.sh", "agent"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+ privileged: true
+ deploy:
+ replicas: 1
+ resources:
+ limits:
+ memory: 3G
+ cpus: '1.0'
+ reservations:
+ memory: 2G
+ cpus: '0.5'
+
+ # Ambari Metrics Collector
+ ambari-metrics:
+ build:
+ context: ..
+ dockerfile: docker/Dockerfile.metrics
+ target: runtime
+ args:
+ - UBUNTU_VERSION=22.04
+ - JAVA_VERSION=11
+ container_name: ambari-metrics-collector
+ hostname: ambari-metrics
+ depends_on:
+ ambari-server:
+ condition: service_healthy
+ environment:
+ # Metrics configuration
+ - AMS_HBASE_ROOTDIR=/var/lib/ambari-metrics-collector/hbase
+ - AMS_COLLECTOR_PORT=6188
+ - AMBARI_COMPONENT=metrics
+
+ # JVM configuration (following Pinot pattern)
+ - AMS_JAVA_OPTS=-Xmx2G -Xms1G -XX:+UseG1GC -XX:MaxGCPauseMillis=200
+ - HBASE_HEAPSIZE=1024m
+ volumes:
+ - ambari-metrics-data:/var/lib/ambari-metrics-collector
+ - ambari-metrics-logs:/var/log/ambari-metrics-collector
+ - ambari-metrics-conf:/etc/ambari-metrics-collector/conf
+ ports:
+ - "6188:6188" # Metrics Collector API
+ - "61888:61888" # Metrics aggregation port
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD", "/usr/local/bin/health-check.sh", "metrics"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 90s
+ restart: unless-stopped
+ deploy:
+ resources:
+ limits:
+ memory: 3G
+ cpus: '1.0'
+ reservations:
+ memory: 2G
+ cpus: '0.5'
+
+ # Grafana for Metrics Visualization (following Pinot pattern)
+ grafana:
+ image: grafana/grafana:10.2.0
+ container_name: ambari-grafana
+ hostname: grafana
+ depends_on:
+ - ambari-metrics
+ environment:
+ - GF_SECURITY_ADMIN_PASSWORD=admin
+ - GF_USERS_ALLOW_SIGN_UP=false
+ - GF_SERVER_ROOT_URL=http://localhost:3000
+ - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
+ - GF_SECURITY_ALLOW_EMBEDDING=true
+ volumes:
+ - grafana-data:/var/lib/grafana
+ - ./config/grafana/provisioning:/etc/grafana/provisioning:ro
+ - ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro
+ ports:
+ - "3000:3000"
+ networks:
+ - ambari-network
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 30s
+ restart: unless-stopped
+
+ # Hadoop NameNode (for cluster setup)
+ namenode:
+ image: apache/hadoop:3.3.6
+ container_name: hadoop-namenode
+ hostname: namenode
+ environment:
+ - CLUSTER_NAME=ambari-cluster
+ - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
+ - CORE_CONF_hadoop_http_staticuser_user=root
+ - CORE_CONF_hadoop_proxyuser_hue_hosts=*
+ - CORE_CONF_hadoop_proxyuser_hue_groups=*
+ - HDFS_CONF_dfs_webhdfs_enabled=true
+ - HDFS_CONF_dfs_permissions_enabled=false
+ - HDFS_CONF_dfs_nameservices=mycluster
+ - HDFS_CONF_dfs_replication=2
+ volumes:
+ - namenode-data:/hadoop/dfs/name
+ ports:
+ - "9870:9870" # NameNode Web UI
+ - "9001:9000" # NameNode IPC (changed to avoid conflict)
+ networks:
+ - ambari-network
+ command: ["hdfs", "namenode"]
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:9870"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+
+ # Hadoop DataNode (scalable)
+ datanode:
+ image: apache/hadoop:3.3.6
+ hostname: datanode-{{.Task.Slot}}
+ depends_on:
+ namenode:
+ condition: service_healthy
+ environment:
+ - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
+ - CORE_CONF_hadoop_http_staticuser_user=root
+ - HDFS_CONF_dfs_webhdfs_enabled=true
+ - HDFS_CONF_dfs_permissions_enabled=false
+ - HDFS_CONF_dfs_datanode_use_datanode_hostname=false
+ - HDFS_CONF_dfs_client_use_datanode_hostname=false
+ - HDFS_CONF_dfs_datanode_data_dir=/hadoop/dfs/data
+ volumes:
+ - datanode-data:/hadoop/dfs/data
+ ports:
+ - "9864" # DataNode Web UI (dynamic port)
+ networks:
+ - ambari-network
+ command: ["hdfs", "datanode"]
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:9864"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+ deploy:
+ replicas: 2
+
+ # YARN ResourceManager
+ resourcemanager:
+ image: apache/hadoop:3.3.6
+ container_name: hadoop-resourcemanager
+ hostname: resourcemanager
+ depends_on:
+ namenode:
+ condition: service_healthy
+ environment:
+ - CORE_CONF_fs_defaultFS=hdfs://namenode:9000
+ - YARN_CONF_yarn_resourcemanager_hostname=resourcemanager
+ - YARN_CONF_yarn_resourcemanager_address=resourcemanager:8032
+ - YARN_CONF_yarn_resourcemanager_scheduler_address=resourcemanager:8030
+ - YARN_CONF_yarn_resourcemanager_resource_tracker_address=resourcemanager:8031
+ - YARN_CONF_yarn_resourcemanager_admin_address=resourcemanager:8033
+ - YARN_CONF_yarn_resourcemanager_webapp_address=resourcemanager:8088
+ ports:
+ - "8088:8088" # ResourceManager Web UI
+ - "8032:8032" # ResourceManager IPC
+ networks:
+ - ambari-network
+ command: ["yarn", "resourcemanager"]
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:8088"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ restart: unless-stopped
+
+# Networks
+networks:
+ ambari-network:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.20.0.0/16
+
+# Volumes
+volumes:
+ # Zookeeper
+ zookeeper-data:
+ driver: local
+ zookeeper-logs:
+ driver: local
+
+ # Database
+ ambari-db-data:
+ driver: local
+
+ # Ambari Server
+ ambari-server-data:
+ driver: local
+ ambari-server-logs:
+ driver: local
+ ambari-server-conf:
+ driver: local
+
+ # Ambari Agent
+ ambari-agent-data:
+ driver: local
+ ambari-agent-logs:
+ driver: local
+ ambari-agent-conf:
+ driver: local
+
+ # Ambari Metrics
+ ambari-metrics-data:
+ driver: local
+ ambari-metrics-logs:
+ driver: local
+ ambari-metrics-conf:
+ driver: local
+
+ # Grafana
+ grafana-data:
+ driver: local
+
+ # Hadoop
+ namenode-data:
+ driver: local
+ datanode-data:
+ driver: local
diff --git a/docker/images/ambari-base/Dockerfile b/docker/images/ambari-base/Dockerfile
new file mode 100644
index 00000000000..42f4d6e7578
--- /dev/null
+++ b/docker/images/ambari-base/Dockerfile
@@ -0,0 +1,249 @@
+# Apache Ambari Base Image
+# Multi-stage build for optimized production image
+
+ARG UBUNTU_VERSION=22.04
+FROM ubuntu:${UBUNTU_VERSION} AS base
+
+# Metadata
+LABEL maintainer="Apache Ambari Community "
+LABEL org.apache.ambari.version="3.0.0-SNAPSHOT"
+LABEL org.apache.ambari.component="base"
+LABEL org.opencontainers.image.source="https://github.com/apache/ambari"
+LABEL org.opencontainers.image.description="Apache Ambari Base Runtime Image"
+LABEL org.opencontainers.image.licenses="Apache-2.0"
+
+# Build arguments
+ARG JAVA_VERSION=11
+ARG MAVEN_VERSION=3.9.6
+ARG NODE_VERSION=18
+ARG PYTHON_VERSION=3.10
+
+# Environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV TZ=UTC
+ENV LANG=C.UTF-8
+ENV LC_ALL=C.UTF-8
+
+# Create ambari user and group
+RUN groupadd -r ambari --gid=1000 && \
+ useradd -r -g ambari --uid=1000 --home-dir=/opt/ambari --shell=/bin/bash ambari && \
+ mkdir -p /opt/ambari && \
+ chown -R ambari:ambari /opt/ambari
+
+# Install system dependencies
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ # Basic utilities
+ curl \
+ wget \
+ unzip \
+ zip \
+ tar \
+ gzip \
+ ca-certificates \
+ gnupg \
+ lsb-release \
+ # Network tools
+ net-tools \
+ netcat \
+ telnet \
+ openssh-client \
+ # System tools
+ sudo \
+ vim \
+ less \
+ htop \
+ procps \
+ psmisc \
+ # Build tools (for native dependencies)
+ build-essential \
+ gcc \
+ g++ \
+ make \
+ # Python and pip
+ python3 \
+ python3-pip \
+ python3-dev \
+ python3-setuptools \
+ python3-wheel \
+ # Git for source management
+ git \
+ # Database clients
+ postgresql-client \
+ mysql-client \
+ # SSL/TLS support
+ openssl \
+ # Time synchronization
+ ntp \
+ ntpdate \
+ # Process management
+ supervisor && \
+ # Clean up
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Install OpenJDK
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends openjdk-${JAVA_VERSION}-jdk && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+# Set JAVA_HOME
+ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64
+ENV PATH=${JAVA_HOME}/bin:${PATH}
+
+# Install Maven using apt package manager (more reliable)
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends maven && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+# Set Maven environment (Ubuntu package installs to /usr/share/maven)
+ENV MAVEN_HOME=/usr/share/maven
+ENV PATH=${MAVEN_HOME}/bin:${PATH}
+
+# Install Node.js and npm using apt package manager (more reliable)
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends nodejs npm && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+# Install Python packages
+RUN pip3 install --no-cache-dir \
+ setuptools \
+ wheel \
+ requests \
+ pyyaml \
+ jinja2 \
+ psutil \
+ six
+
+# Create directory structure
+RUN mkdir -p \
+ /var/log/ambari-server \
+ /var/log/ambari-agent \
+ /var/log/ambari-metrics-collector \
+ /var/log/ambari-metrics-monitor \
+ /var/run/ambari-server \
+ /var/run/ambari-agent \
+ /var/run/ambari-metrics-collector \
+ /var/run/ambari-metrics-monitor \
+ /var/lib/ambari-server \
+ /var/lib/ambari-agent \
+ /var/lib/ambari-metrics-collector \
+ /etc/ambari-server/conf \
+ /etc/ambari-agent/conf \
+ /etc/ambari-metrics-collector/conf \
+ /etc/ambari-metrics-monitor/conf && \
+ chown -R ambari:ambari \
+ /var/log/ambari-* \
+ /var/run/ambari-* \
+ /var/lib/ambari-* \
+ /etc/ambari-*
+
+# Configure sudo for ambari user
+RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ambari && \
+ chmod 0440 /etc/sudoers.d/ambari
+
+# SSH configuration for multi-node setups
+RUN mkdir -p /home/ambari/.ssh && \
+ ssh-keygen -t rsa -N '' -f /home/ambari/.ssh/id_rsa && \
+ cat /home/ambari/.ssh/id_rsa.pub >> /home/ambari/.ssh/authorized_keys && \
+ chmod 600 /home/ambari/.ssh/authorized_keys && \
+ chmod 700 /home/ambari/.ssh && \
+ chown -R ambari:ambari /home/ambari/.ssh
+
+# Configure SSH daemon
+RUN apt-get update && apt-get install -y openssh-server && \
+ mkdir -p /var/run/sshd && \
+ sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
+ sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
+ sed -i 's/UsePAM yes/UsePAM no/' /etc/ssh/sshd_config
+
+# Set up Maven repository cache
+RUN mkdir -p /home/ambari/.m2 && \
+ chown -R ambari:ambari /home/ambari/.m2
+
+# Health check script
+COPY scripts/health-check.sh /usr/local/bin/health-check.sh
+RUN chmod +x /usr/local/bin/health-check.sh
+
+# Entrypoint script
+COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
+RUN chmod +x /usr/local/bin/entrypoint.sh
+
+# Set working directory
+WORKDIR /opt/ambari
+
+# Switch to ambari user
+USER ambari
+
+# Default command
+ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
+CMD ["bash"]
+
+# Build stage for development
+FROM base AS build
+
+# Switch back to root for build tools
+USER root
+
+# Install additional build dependencies
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ # Additional build tools
+ cmake \
+ autoconf \
+ automake \
+ libtool \
+ pkg-config \
+ # Development headers
+ libssl-dev \
+ libffi-dev \
+ libxml2-dev \
+ libxslt1-dev \
+ zlib1g-dev \
+ # RPM building tools
+ rpm \
+ rpmbuild \
+ # Debugging tools
+ gdb \
+ strace \
+ tcpdump && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+# Install additional Python development packages
+RUN pip3 install --no-cache-dir \
+ pytest \
+ mock \
+ coverage \
+ flake8 \
+ pylint
+
+# Pre-download Maven dependencies for faster builds
+COPY pom.xml /tmp/pom.xml
+RUN cd /tmp && \
+ mvn dependency:go-offline -B -q && \
+ rm -rf /tmp/*
+
+# Switch back to ambari user
+USER ambari
+
+# Runtime stage for production
+FROM base AS runtime
+
+# Copy only necessary files from build stage
+# This keeps the runtime image smaller
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
+ CMD /usr/local/bin/health-check.sh
+
+# Expose common ports
+EXPOSE 8080 8441 8440 6188 61888
+
+# Default volumes
+VOLUME ["/var/log/ambari-server", "/var/log/ambari-agent", "/var/log/ambari-metrics-collector"]
+VOLUME ["/var/lib/ambari-server", "/var/lib/ambari-agent", "/var/lib/ambari-metrics-collector"]
+VOLUME ["/etc/ambari-server/conf", "/etc/ambari-agent/conf", "/etc/ambari-metrics-collector/conf"]
diff --git a/docker/images/ambari-base/docker-build.sh b/docker/images/ambari-base/docker-build.sh
new file mode 100755
index 00000000000..acac7a1e334
--- /dev/null
+++ b/docker/images/ambari-base/docker-build.sh
@@ -0,0 +1,91 @@
+#!/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.
+#
+
+# Apache Ambari Base Image Build Script
+
+set -e
+
+# Default configuration
+DEFAULT_DOCKER_TAG="ambari-base:latest"
+DEFAULT_OPENJDK_IMAGE="openjdk"
+DEFAULT_JDK_VERSION="8"
+
+# Script directory
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+# Function to show usage
+show_usage() {
+ cat << EOF
+Apache Ambari Base Image Build Script
+
+Usage: $0 [Docker Tag] [JDK Version] [OpenJDK Image]
+
+Parameters:
+ Docker Tag Name and tag your docker image. Default is '$DEFAULT_DOCKER_TAG'.
+ JDK Version The JDK version to use. Default is '$DEFAULT_JDK_VERSION'
+ OpenJDK Image Base image to use. Default is '$DEFAULT_OPENJDK_IMAGE'.
+
+Examples:
+ $0 ambari-base:latest
+ $0 ambari-base:8 8 openjdk
+ $0 ambari-base:arm64 8 arm64v8/openjdk
+
+EOF
+}
+
+# Parse arguments
+DOCKER_TAG="${1:-$DEFAULT_DOCKER_TAG}"
+JDK_VERSION="${2:-$DEFAULT_JDK_VERSION}"
+OPENJDK_IMAGE="${3:-$DEFAULT_OPENJDK_IMAGE}"
+
+if [[ "$1" == "--help" || "$1" == "-h" ]]; then
+ show_usage
+ exit 0
+fi
+
+log_info "Building Ambari Base Image"
+log_info "Docker Tag: $DOCKER_TAG"
+log_info "JDK Version: $JDK_VERSION"
+log_info "OpenJDK Image: $OPENJDK_IMAGE"
+
+# Build the image from docker root directory to access scripts
+DOCKER_ROOT="$SCRIPT_DIR/../../"
+docker build \
+ --build-arg JDK_VERSION="$JDK_VERSION" \
+ --build-arg OPENJDK_IMAGE="$OPENJDK_IMAGE" \
+ -t "$DOCKER_TAG" \
+ -f "$SCRIPT_DIR/Dockerfile" \
+ "$DOCKER_ROOT"
+
+log_info "Successfully built: $DOCKER_TAG"
diff --git a/docker/images/ambari-metrics/Dockerfile b/docker/images/ambari-metrics/Dockerfile
new file mode 100644
index 00000000000..847aec93912
--- /dev/null
+++ b/docker/images/ambari-metrics/Dockerfile
@@ -0,0 +1,181 @@
+# Multi-stage Dockerfile for Apache Ambari Metrics Collector
+# Based on best practices from Apache Pinot and other Apache projects
+
+# Build stage
+FROM ubuntu:22.04 AS builder
+
+# Build arguments
+ARG MAVEN_VERSION=3.9.6
+ARG JAVA_VERSION=11
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64
+ENV MAVEN_HOME=/opt/maven
+ENV PATH=$PATH:$MAVEN_HOME/bin
+
+# Install build dependencies
+RUN apt-get update && apt-get install -y \
+ openjdk-${JAVA_VERSION}-jdk \
+ maven \
+ curl \
+ wget \
+ git \
+ build-essential \
+ python3 \
+ python3-pip \
+ python3-dev \
+ && rm -rf /var/lib/apt/lists/*
+
+# Set working directory
+WORKDIR /workspace
+
+# Copy source code
+COPY . .
+
+# Build Ambari Metrics
+RUN mvn clean install -pl ambari-metrics -DskipTests -Drat.skip=true \
+ && mvn clean package -pl ambari-metrics/ambari-metrics-assembly -DskipTests
+
+# Runtime stage
+FROM ubuntu:22.04 AS runtime
+
+# Runtime arguments
+ARG JAVA_VERSION=11
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64
+ENV AMBARI_METRICS_HOME=/opt/ambari-metrics
+ENV PATH=$PATH:$AMBARI_METRICS_HOME/bin
+
+# Create ambari user
+RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \
+ && mkdir -p /home/ambari \
+ && chown -R ambari:ambari /home/ambari
+
+# Install runtime dependencies
+RUN apt-get update && apt-get install -y \
+ openjdk-${JAVA_VERSION}-jre-headless \
+ python3 \
+ python3-pip \
+ curl \
+ wget \
+ netcat \
+ procps \
+ net-tools \
+ && rm -rf /var/lib/apt/lists/*
+
+# Copy built artifacts from builder stage
+COPY --from=builder /workspace/ambari-metrics/ambari-metrics-assembly/target/ambari-metrics-assembly-*.tar.gz /tmp/
+
+# Install Ambari Metrics
+RUN cd /tmp && \
+ tar -xzf ambari-metrics-assembly-*.tar.gz && \
+ mv ambari-metrics-assembly-* /opt/ambari-metrics && \
+ rm -f /tmp/*.tar.gz
+
+# Create necessary directories
+RUN mkdir -p /var/lib/ambari-metrics-collector \
+ /var/log/ambari-metrics-collector \
+ /etc/ambari-metrics-collector/conf \
+ && chown -R ambari:ambari /var/lib/ambari-metrics-collector \
+ /var/log/ambari-metrics-collector \
+ /etc/ambari-metrics-collector \
+ /opt/ambari-metrics
+
+# Copy configuration files and scripts
+COPY docker/config/metrics/ /etc/ambari-metrics-collector/conf/
+COPY docker/scripts/ /usr/local/bin/
+
+# Make scripts executable
+RUN chmod +x /usr/local/bin/*.sh
+
+# Create startup script
+RUN cat > /usr/local/bin/start-ambari-metrics.sh << 'EOF'
+#!/bin/bash
+set -e
+
+# Configure metrics collector
+echo "Configuring Ambari Metrics Collector..."
+
+# Set heap size
+export COLLECTOR_HEAPSIZE=${METRICS_COLLECTOR_HEAPSIZE:-1024m}
+
+# Create HBase configuration
+mkdir -p /var/lib/ambari-metrics-collector/hbase/conf
+
+# Configure HBase for embedded mode
+cat > /var/lib/ambari-metrics-collector/hbase/conf/hbase-site.xml << EOL
+
+
+
+ hbase.rootdir
+ file:///var/lib/ambari-metrics-collector/hbase
+
+
+ hbase.zookeeper.property.dataDir
+ /var/lib/ambari-metrics-collector/hbase/zookeeper
+
+
+ hbase.cluster.distributed
+ false
+
+
+ hbase.tmp.dir
+ /var/lib/ambari-metrics-collector/hbase/tmp
+
+
+EOL
+
+# Start Ambari Metrics Collector
+echo "Starting Ambari Metrics Collector..."
+cd /opt/ambari-metrics
+exec ./bin/ambari-metrics-collector start
+EOF
+
+RUN chmod +x /usr/local/bin/start-ambari-metrics.sh
+
+# Switch to ambari user
+USER ambari
+
+# Expose metrics ports
+EXPOSE 6188 61888
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
+ CMD /usr/local/bin/health-check.sh metrics
+
+# Set working directory
+WORKDIR /home/ambari
+
+# Default command
+CMD ["/usr/local/bin/start-ambari-metrics.sh"]
+
+# Development stage
+FROM runtime AS development
+
+# Switch back to root for development tools
+USER root
+
+# Install development dependencies
+RUN apt-get update && apt-get install -y \
+ maven \
+ git \
+ vim \
+ less \
+ htop \
+ && rm -rf /var/lib/apt/lists/*
+
+# Create Maven cache directory
+RUN mkdir -p /home/ambari/.m2 && \
+ chown -R ambari:ambari /home/ambari/.m2
+
+# Switch back to ambari user
+USER ambari
+
+# Mount point for source code
+VOLUME ["/workspace"]
+
+# Default command for development
+CMD ["bash"]
diff --git a/docker/images/ambari-metrics/docker-build.sh b/docker/images/ambari-metrics/docker-build.sh
new file mode 100755
index 00000000000..11b970330f5
--- /dev/null
+++ b/docker/images/ambari-metrics/docker-build.sh
@@ -0,0 +1,84 @@
+#!/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.
+#
+
+# Apache Ambari Metrics Image Build Script
+
+set -e
+
+# Default configuration
+DEFAULT_DOCKER_TAG="ambari-metrics:latest"
+DEFAULT_BASE_IMAGE="ambari-base:latest"
+
+# Script directory
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+# Function to show usage
+show_usage() {
+ cat << EOF
+Apache Ambari Metrics Image Build Script
+
+Usage: $0 [Docker Tag] [Base Image]
+
+Parameters:
+ Docker Tag Name and tag your docker image. Default is '$DEFAULT_DOCKER_TAG'.
+ Base Image Base image to use. Default is '$DEFAULT_BASE_IMAGE'.
+
+Examples:
+ $0 ambari-metrics:latest
+ $0 ambari-metrics:2.7.5 ambari-base:2.7.5
+
+EOF
+}
+
+# Parse arguments
+DOCKER_TAG="${1:-$DEFAULT_DOCKER_TAG}"
+BASE_IMAGE="${2:-$DEFAULT_BASE_IMAGE}"
+
+if [[ "$1" == "--help" || "$1" == "-h" ]]; then
+ show_usage
+ exit 0
+fi
+
+log_info "Building Ambari Metrics Image"
+log_info "Docker Tag: $DOCKER_TAG"
+log_info "Base Image: $BASE_IMAGE"
+
+# Build the image
+docker build \
+ --build-arg BASE_IMAGE="$BASE_IMAGE" \
+ -t "$DOCKER_TAG" \
+ -f "$SCRIPT_DIR/Dockerfile" \
+ "$SCRIPT_DIR"
+
+log_info "Successfully built: $DOCKER_TAG"
diff --git a/docker/images/ambari/Dockerfile b/docker/images/ambari/Dockerfile
new file mode 100644
index 00000000000..b91f37bd3fd
--- /dev/null
+++ b/docker/images/ambari/Dockerfile
@@ -0,0 +1,172 @@
+#
+# 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.
+#
+
+# Multi-stage Dockerfile for Apache Ambari
+# Based on Apache Pinot's Docker approach
+
+ARG OPENJDK_IMAGE=eclipse-temurin
+ARG JDK_VERSION=8
+ARG UBUNTU_VERSION=20.04
+
+# Build stage
+FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jdk AS builder
+
+# Build arguments
+ARG AMBARI_GIT_URL=https://github.com/apache/ambari.git
+ARG AMBARI_BRANCH=trunk
+ARG MAVEN_VERSION=3.6.3
+ARG NODE_VERSION=14
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/local/openjdk-${JDK_VERSION}
+ENV MAVEN_HOME=/opt/maven
+ENV NODE_HOME=/opt/node
+ENV PATH=$PATH:$MAVEN_HOME/bin:$NODE_HOME/bin
+
+# Install build dependencies
+RUN apt-get update && apt-get install -y \
+ curl \
+ wget \
+ git \
+ build-essential \
+ python3 \
+ python3-pip \
+ python3-dev \
+ rpm \
+ alien \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install Maven
+RUN wget -q https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
+ && tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt \
+ && mv /opt/apache-maven-${MAVEN_VERSION} /opt/maven \
+ && rm apache-maven-${MAVEN_VERSION}-bin.tar.gz
+
+# Install Node.js
+RUN wget -q https://nodejs.org/dist/v${NODE_VERSION}.20.1/node-v${NODE_VERSION}.20.1-linux-x64.tar.xz \
+ && tar -xJf node-v${NODE_VERSION}.20.1-linux-x64.tar.xz -C /opt \
+ && mv /opt/node-v${NODE_VERSION}.20.1-linux-x64 /opt/node \
+ && rm node-v${NODE_VERSION}.20.1-linux-x64.tar.xz
+
+# Set working directory
+WORKDIR /tmp/ambari-build
+
+# Clone and build Ambari
+RUN git clone ${AMBARI_GIT_URL} . \
+ && git checkout ${AMBARI_BRANCH} \
+ && mvn clean install -DskipTests -Drat.skip=true -Dfindbugs.skip=true \
+ && mvn clean package rpm:rpm -DskipTests -Drat.skip=true
+
+# Runtime stage
+FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jre AS runtime
+
+# Runtime arguments
+ARG OPENJDK_IMAGE=eclipse-temurin
+ARG JDK_VERSION=8
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/opt/java/openjdk
+ENV AMBARI_HOME=/opt/ambari
+ENV PATH=$PATH:$AMBARI_HOME/bin
+
+# Create ambari user
+RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \
+ && mkdir -p /home/ambari \
+ && chown -R ambari:ambari /home/ambari
+
+# Install runtime dependencies
+RUN apt-get update && apt-get install -y \
+ python3 \
+ python3-pip \
+ postgresql-client \
+ curl \
+ wget \
+ netcat-openbsd \
+ procps \
+ net-tools \
+ sudo \
+ openssh-server \
+ rsync \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies
+RUN pip3 install psycopg2-binary requests pyyaml
+
+# Copy built artifacts from builder stage
+COPY --from=builder /tmp/ambari-build/ambari-server/target/rpm/ambari-server/RPMS/noarch/*.rpm /tmp/
+COPY --from=builder /tmp/ambari-build/ambari-agent/target/rpm/ambari-agent/RPMS/noarch/*.rpm /tmp/
+
+# Convert and install RPM packages
+RUN cd /tmp && \
+ for rpm in *.rpm; do \
+ alien -d --scripts "$rpm"; \
+ done && \
+ dpkg -i *.deb && \
+ rm -f /tmp/*.rpm /tmp/*.deb
+
+# Create necessary directories
+RUN mkdir -p /var/lib/ambari-server \
+ /var/log/ambari-server \
+ /var/lib/ambari-agent \
+ /var/log/ambari-agent \
+ /etc/ambari-server/conf \
+ /etc/ambari-agent/conf \
+ /opt/ambari \
+ && chown -R ambari:ambari /var/lib/ambari-* \
+ /var/log/ambari-* \
+ /etc/ambari-* \
+ /opt/ambari
+
+# Copy configuration files and scripts
+COPY images/ambari/bin/ /opt/ambari/bin/
+COPY images/ambari/etc/ /etc/ambari/
+COPY scripts/ /usr/local/bin/
+
+# Make scripts executable
+RUN chmod +x /opt/ambari/bin/*.sh /usr/local/bin/*.sh
+
+# Configure SSH
+RUN apt-get update && apt-get install -y openssh-server && \
+ mkdir -p /var/run/sshd && \
+ sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
+ sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
+
+# Configure sudo for ambari user
+RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+
+# Switch to ambari user
+USER ambari
+
+# Expose ports
+EXPOSE 8080 8441 8440 6188 61888
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
+ CMD /usr/local/bin/health-check.sh
+
+# Set working directory
+WORKDIR /home/ambari
+
+# Entry point
+ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
+
+# Default command (Pinot-style - uses pinot-admin.sh equivalent)
+CMD ["ambari-admin.sh"]
diff --git a/docker/images/ambari/Dockerfile.agent b/docker/images/ambari/Dockerfile.agent
new file mode 100644
index 00000000000..2d610041701
--- /dev/null
+++ b/docker/images/ambari/Dockerfile.agent
@@ -0,0 +1,215 @@
+# Multi-stage Dockerfile for Apache Ambari Agent
+# Based on best practices from Apache Pinot and other Apache projects
+
+# Build stage
+FROM ubuntu:22.04 AS builder
+
+# Build arguments
+ARG MAVEN_VERSION=3.9.6
+ARG JAVA_VERSION=11
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64
+ENV MAVEN_HOME=/opt/maven
+ENV PATH=$PATH:$MAVEN_HOME/bin
+
+# Install build dependencies
+RUN apt-get update && apt-get install -y \
+ openjdk-${JAVA_VERSION}-jdk \
+ maven \
+ curl \
+ wget \
+ git \
+ build-essential \
+ python3 \
+ python3-pip \
+ python3-dev \
+ rpm \
+ alien \
+ && rm -rf /var/lib/apt/lists/*
+
+# Set working directory
+WORKDIR /workspace
+
+# Copy source code
+COPY . .
+
+# Build Ambari Agent
+RUN mvn clean install -pl ambari-agent -DskipTests -Drat.skip=true \
+ && mvn clean package rpm:rpm -pl ambari-agent -DskipTests
+
+# Runtime stage
+FROM ubuntu:22.04 AS runtime
+
+# Runtime arguments
+ARG JAVA_VERSION=11
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64
+ENV AMBARI_AGENT_HOME=/opt/ambari-agent
+ENV PATH=$PATH:$AMBARI_AGENT_HOME/bin
+
+# Create ambari user
+RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \
+ && mkdir -p /home/ambari \
+ && chown -R ambari:ambari /home/ambari
+
+# Install runtime dependencies
+RUN apt-get update && apt-get install -y \
+ openjdk-${JAVA_VERSION}-jre-headless \
+ python3 \
+ python3-pip \
+ curl \
+ wget \
+ netcat-openbsd \
+ procps \
+ net-tools \
+ sudo \
+ openssh-server \
+ rsync \
+ psmisc \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies
+RUN pip3 install requests psutil pyyaml
+
+# Copy built artifacts from builder stage
+COPY --from=builder /workspace/ambari-agent/target/rpm/ambari-agent/RPMS/x86_64/*.rpm /tmp/
+
+# Convert and install RPM packages
+RUN cd /tmp && \
+ for rpm in *.rpm; do \
+ alien -d --scripts "$rpm"; \
+ done && \
+ dpkg -i *.deb && \
+ rm -f /tmp/*.rpm /tmp/*.deb
+
+# Create necessary directories
+RUN mkdir -p /var/lib/ambari-agent \
+ /var/log/ambari-agent \
+ /etc/ambari-agent/conf \
+ /opt/ambari-agent \
+ && chown -R ambari:ambari /var/lib/ambari-agent \
+ /var/log/ambari-agent \
+ /etc/ambari-agent \
+ /opt/ambari-agent
+
+# Copy configuration files and scripts
+COPY docker/config/agent/ /etc/ambari-agent/conf/
+COPY docker/scripts/ /usr/local/bin/
+
+# Make scripts executable
+RUN chmod +x /usr/local/bin/*.sh
+
+# Create startup script
+RUN cat > /usr/local/bin/start-ambari-agent.sh << 'EOF'
+#!/bin/bash
+set -e
+
+# Wait for Ambari Server
+echo "Waiting for Ambari Server at ${AMBARI_SERVER_HOST:-ambari-server}:${AMBARI_SERVER_PORT:-8080}..."
+while ! nc -z ${AMBARI_SERVER_HOST:-ambari-server} ${AMBARI_SERVER_PORT:-8080}; do
+ echo "Ambari Server not ready, waiting..."
+ sleep 10
+done
+echo "Ambari Server is ready!"
+
+# Configure agent
+echo "Configuring Ambari Agent..."
+cat > /etc/ambari-agent/conf/ambari-agent.ini << EOL
+[server]
+hostname=${AMBARI_SERVER_HOST:-ambari-server}
+url_port=${AMBARI_SERVER_PORT:-8080}
+secured_url_port=8441
+
+[agent]
+prefix=/var/lib/ambari-agent/data
+cache_dir=/var/lib/ambari-agent/cache
+log_dir=/var/log/ambari-agent
+pidfile=/var/run/ambari-agent/ambari-agent.pid
+hostname_script=/var/lib/ambari-agent/hostname.sh
+
+[security]
+keysdir=/var/lib/ambari-agent/keys
+server_crt=ca.crt
+passphrase_env_var_name=AMBARI_PASSPHRASE
+
+[heartbeat]
+state_interval=6
+dirs=/etc/hadoop,/etc/hadoop/conf,/etc/hbase,/etc/hcatalog,/etc/hive,/etc/oozie,/etc/sqoop,/var/run/hadoop,/var/run/zookeeper,/var/run/hbase,/var/run/hive,/var/run/oozie,/var/log/hadoop,/var/log/zookeeper,/var/log/hbase,/var/log/hive,/var/log/oozie
+rpms=hadoop,zookeeper,hbase,hive
+EOL
+
+# Create hostname script
+cat > /var/lib/ambari-agent/hostname.sh << 'EOL'
+#!/bin/bash
+echo $(hostname -f)
+EOL
+chmod +x /var/lib/ambari-agent/hostname.sh
+
+# Start SSH daemon
+sudo service ssh start
+
+# Start Ambari Agent
+echo "Starting Ambari Agent..."
+exec ambari-agent start --debug=${AMBARI_DEBUG:-false}
+EOF
+
+RUN chmod +x /usr/local/bin/start-ambari-agent.sh
+
+# Configure SSH
+RUN apt-get update && apt-get install -y openssh-server && \
+ mkdir -p /var/run/sshd && \
+ sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
+ sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
+
+# Configure sudo for ambari user
+RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+
+# Switch to ambari user
+USER ambari
+
+# Expose SSH port
+EXPOSE 22 5006
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
+ CMD /usr/local/bin/health-check.sh agent
+
+# Set working directory
+WORKDIR /home/ambari
+
+# Default command
+CMD ["/usr/local/bin/start-ambari-agent.sh"]
+
+# Development stage
+FROM runtime AS development
+
+# Switch back to root for development tools
+USER root
+
+# Install development dependencies
+RUN apt-get update && apt-get install -y \
+ maven \
+ git \
+ vim \
+ less \
+ htop \
+ strace \
+ tcpdump \
+ && rm -rf /var/lib/apt/lists/*
+
+# Create Maven cache directory
+RUN mkdir -p /home/ambari/.m2 && \
+ chown -R ambari:ambari /home/ambari/.m2
+
+# Switch back to ambari user
+USER ambari
+
+# Mount point for source code
+VOLUME ["/workspace"]
+
+# Default command for development
+CMD ["bash"]
diff --git a/docker/images/ambari/Dockerfile.build b/docker/images/ambari/Dockerfile.build
new file mode 100644
index 00000000000..c4291590592
--- /dev/null
+++ b/docker/images/ambari/Dockerfile.build
@@ -0,0 +1,186 @@
+#
+# 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.
+#
+
+# Build-only Dockerfile for Apache Ambari
+# This image is used for building Ambari from source
+
+ARG OPENJDK_IMAGE=openjdk
+ARG JDK_VERSION=8
+ARG UBUNTU_VERSION=20.04
+
+FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jdk-slim
+
+# Build arguments
+ARG MAVEN_VERSION=3.6.3
+ARG NODE_VERSION=14
+ARG PYTHON_VERSION=3.8
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/local/openjdk-${JDK_VERSION}
+ENV MAVEN_HOME=/opt/maven
+ENV NODE_HOME=/opt/node
+ENV PATH=$PATH:$MAVEN_HOME/bin:$NODE_HOME/bin
+
+# Create ambari user
+RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \
+ && mkdir -p /home/ambari \
+ && chown -R ambari:ambari /home/ambari
+
+# Install build dependencies
+RUN apt-get update && apt-get install -y \
+ # Basic utilities
+ curl \
+ wget \
+ unzip \
+ zip \
+ tar \
+ gzip \
+ ca-certificates \
+ gnupg \
+ lsb-release \
+ # Build tools
+ build-essential \
+ gcc \
+ g++ \
+ make \
+ cmake \
+ autoconf \
+ automake \
+ libtool \
+ pkg-config \
+ # Version control
+ git \
+ # Python and development tools
+ python3 \
+ python3-pip \
+ python3-dev \
+ python3-setuptools \
+ python3-wheel \
+ # RPM building tools
+ rpm \
+ rpmbuild \
+ alien \
+ # Development headers
+ libssl-dev \
+ libffi-dev \
+ libxml2-dev \
+ libxslt1-dev \
+ zlib1g-dev \
+ # Network tools
+ net-tools \
+ netcat-openbsd \
+ telnet \
+ openssh-client \
+ # System tools
+ sudo \
+ vim \
+ less \
+ htop \
+ procps \
+ psmisc \
+ # Debugging tools
+ gdb \
+ strace \
+ tcpdump \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install Maven
+RUN wget -q https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
+ && tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt \
+ && mv /opt/apache-maven-${MAVEN_VERSION} /opt/maven \
+ && rm apache-maven-${MAVEN_VERSION}-bin.tar.gz
+
+# Install Node.js and npm
+RUN wget -q https://nodejs.org/dist/v${NODE_VERSION}.20.1/node-v${NODE_VERSION}.20.1-linux-x64.tar.xz \
+ && tar -xJf node-v${NODE_VERSION}.20.1-linux-x64.tar.xz -C /opt \
+ && mv /opt/node-v${NODE_VERSION}.20.1-linux-x64 /opt/node \
+ && rm node-v${NODE_VERSION}.20.1-linux-x64.tar.xz
+
+# Install global npm packages
+RUN npm install -g brunch bower grunt-cli
+
+# Install Python development packages
+RUN pip3 install --no-cache-dir \
+ setuptools \
+ wheel \
+ requests \
+ pyyaml \
+ jinja2 \
+ psutil \
+ six \
+ pytest \
+ mock \
+ coverage \
+ flake8 \
+ pylint
+
+# Create directory structure
+RUN mkdir -p \
+ /var/log/ambari-server \
+ /var/log/ambari-agent \
+ /var/log/ambari-metrics-collector \
+ /var/run/ambari-server \
+ /var/run/ambari-agent \
+ /var/run/ambari-metrics-collector \
+ /var/lib/ambari-server \
+ /var/lib/ambari-agent \
+ /var/lib/ambari-metrics-collector \
+ /etc/ambari-server/conf \
+ /etc/ambari-agent/conf \
+ /etc/ambari-metrics-collector/conf \
+ /home/ambari/.m2 \
+ /workspace \
+ && chown -R ambari:ambari \
+ /var/log/ambari-* \
+ /var/run/ambari-* \
+ /var/lib/ambari-* \
+ /etc/ambari-* \
+ /home/ambari \
+ /workspace
+
+# Configure sudo for ambari user
+RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ambari && \
+ chmod 0440 /etc/sudoers.d/ambari
+
+# SSH configuration for multi-node setups
+RUN mkdir -p /home/ambari/.ssh && \
+ ssh-keygen -t rsa -N '' -f /home/ambari/.ssh/id_rsa && \
+ cat /home/ambari/.ssh/id_rsa.pub >> /home/ambari/.ssh/authorized_keys && \
+ chmod 600 /home/ambari/.ssh/authorized_keys && \
+ chmod 700 /home/ambari/.ssh && \
+ chown -R ambari:ambari /home/ambari/.ssh
+
+# Pre-download Maven dependencies for faster builds
+COPY pom.xml /tmp/pom.xml
+RUN cd /tmp && \
+ mvn dependency:go-offline -B -q || true && \
+ rm -rf /tmp/*
+
+# Switch to ambari user
+USER ambari
+
+# Set working directory
+WORKDIR /workspace
+
+# Default volumes
+VOLUME ["/workspace", "/home/ambari/.m2"]
+
+# Default command
+CMD ["bash"]
diff --git a/docker/images/ambari/Dockerfile.package b/docker/images/ambari/Dockerfile.package
new file mode 100644
index 00000000000..4728dff02ab
--- /dev/null
+++ b/docker/images/ambari/Dockerfile.package
@@ -0,0 +1,168 @@
+#
+# 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.
+#
+
+# Package-based Dockerfile for Apache Ambari
+# This image uses pre-built packages instead of building from source
+
+ARG OPENJDK_IMAGE=openjdk
+ARG JDK_VERSION=8
+ARG UBUNTU_VERSION=20.04
+
+FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jre-slim
+
+# Build arguments
+ARG AMBARI_VERSION=2.7.5
+ARG AMBARI_REPO_URL=http://public-repo-1.hortonworks.com/ambari/ubuntu18/2.x/updates/2.7.5.0
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/local/openjdk-${JDK_VERSION}
+ENV AMBARI_HOME=/opt/ambari
+ENV PATH=$PATH:$AMBARI_HOME/bin
+
+# Create ambari user
+RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \
+ && mkdir -p /home/ambari \
+ && chown -R ambari:ambari /home/ambari
+
+# Install runtime dependencies
+RUN apt-get update && apt-get install -y \
+ # Basic utilities
+ curl \
+ wget \
+ unzip \
+ zip \
+ tar \
+ gzip \
+ ca-certificates \
+ gnupg \
+ lsb-release \
+ # Python runtime
+ python3 \
+ python3-pip \
+ # Database clients
+ postgresql-client \
+ mysql-client \
+ # Network tools
+ net-tools \
+ netcat-openbsd \
+ telnet \
+ openssh-client \
+ openssh-server \
+ # System tools
+ sudo \
+ vim \
+ less \
+ htop \
+ procps \
+ psmisc \
+ rsync \
+ # SSL/TLS support
+ openssl \
+ # Time synchronization
+ ntp \
+ ntpdate \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies
+RUN pip3 install --no-cache-dir \
+ psycopg2-binary \
+ requests \
+ pyyaml \
+ jinja2 \
+ psutil \
+ six
+
+# Add Ambari repository and install packages
+RUN wget -O - ${AMBARI_REPO_URL}/RPM-GPG-KEY/RPM-GPG-KEY-Jenkins | apt-key add - && \
+ echo "deb ${AMBARI_REPO_URL} Ambari main" > /etc/apt/sources.list.d/ambari.list && \
+ apt-get update && \
+ apt-get install -y \
+ ambari-server \
+ ambari-agent \
+ && rm -rf /var/lib/apt/lists/*
+
+# Create necessary directories
+RUN mkdir -p \
+ /var/lib/ambari-server \
+ /var/log/ambari-server \
+ /var/lib/ambari-agent \
+ /var/log/ambari-agent \
+ /var/lib/ambari-metrics-collector \
+ /var/log/ambari-metrics-collector \
+ /etc/ambari-server/conf \
+ /etc/ambari-agent/conf \
+ /etc/ambari-metrics-collector/conf \
+ /opt/ambari \
+ && chown -R ambari:ambari \
+ /var/lib/ambari-* \
+ /var/log/ambari-* \
+ /etc/ambari-* \
+ /opt/ambari
+
+# Copy configuration files and scripts
+COPY bin/ /opt/ambari/bin/
+COPY etc/ /etc/ambari/
+COPY docker/scripts/ /usr/local/bin/
+
+# Make scripts executable
+RUN chmod +x /opt/ambari/bin/*.sh /usr/local/bin/*.sh
+
+# Configure SSH
+RUN apt-get update && apt-get install -y openssh-server && \
+ mkdir -p /var/run/sshd && \
+ sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
+ sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
+ sed -i 's/UsePAM yes/UsePAM no/' /etc/ssh/sshd_config
+
+# SSH configuration for multi-node setups
+RUN mkdir -p /home/ambari/.ssh && \
+ ssh-keygen -t rsa -N '' -f /home/ambari/.ssh/id_rsa && \
+ cat /home/ambari/.ssh/id_rsa.pub >> /home/ambari/.ssh/authorized_keys && \
+ chmod 600 /home/ambari/.ssh/authorized_keys && \
+ chmod 700 /home/ambari/.ssh && \
+ chown -R ambari:ambari /home/ambari/.ssh
+
+# Configure sudo for ambari user
+RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ambari && \
+ chmod 0440 /etc/sudoers.d/ambari
+
+# Switch to ambari user
+USER ambari
+
+# Expose ports
+EXPOSE 8080 8441 8440 6188 61888
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
+ CMD /usr/local/bin/health-check.sh
+
+# Set working directory
+WORKDIR /home/ambari
+
+# Default volumes
+VOLUME ["/var/log/ambari-server", "/var/log/ambari-agent", "/var/log/ambari-metrics-collector"]
+VOLUME ["/var/lib/ambari-server", "/var/lib/ambari-agent", "/var/lib/ambari-metrics-collector"]
+VOLUME ["/etc/ambari-server/conf", "/etc/ambari-agent/conf", "/etc/ambari-metrics-collector/conf"]
+
+# Entry point
+ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
+
+# Default command
+CMD ["ambari-admin.sh"]
diff --git a/docker/images/ambari/Dockerfile.server b/docker/images/ambari/Dockerfile.server
new file mode 100644
index 00000000000..e9f178b62b4
--- /dev/null
+++ b/docker/images/ambari/Dockerfile.server
@@ -0,0 +1,202 @@
+# Multi-stage Dockerfile for Apache Ambari Server
+# Based on best practices from Apache Pinot and other Apache projects
+
+# Build stage
+FROM ubuntu:22.04 AS builder
+
+# Build arguments
+ARG MAVEN_VERSION=3.9.6
+ARG JAVA_VERSION=11
+ARG NODE_VERSION=18
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64
+ENV MAVEN_HOME=/opt/maven
+ENV NODE_HOME=/opt/node
+ENV PATH=$PATH:$MAVEN_HOME/bin:$NODE_HOME/bin
+
+# Install build dependencies
+RUN apt-get update && apt-get install -y \
+ openjdk-${JAVA_VERSION}-jdk \
+ maven \
+ nodejs \
+ npm \
+ curl \
+ wget \
+ git \
+ build-essential \
+ python3 \
+ python3-pip \
+ python3-dev \
+ rpm \
+ alien \
+ && rm -rf /var/lib/apt/lists/*
+
+# Set working directory
+WORKDIR /workspace
+
+# Copy source code
+COPY . .
+
+# Build Ambari Server
+RUN mvn clean install -DskipTests -Drat.skip=true -Dfindbugs.skip=true \
+ && mvn clean package rpm:rpm -pl ambari-server -DskipTests -Drat.skip=true
+
+# Runtime stage
+FROM ubuntu:22.04 AS runtime
+
+# Runtime arguments
+ARG JAVA_VERSION=11
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64
+ENV AMBARI_HOME=/opt/ambari
+ENV AMBARI_SERVER_HOME=/opt/ambari-server
+ENV PATH=$PATH:$AMBARI_SERVER_HOME/bin
+
+# Create ambari user
+RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \
+ && mkdir -p /home/ambari \
+ && chown -R ambari:ambari /home/ambari
+
+# Install runtime dependencies
+RUN apt-get update && apt-get install -y \
+ openjdk-${JAVA_VERSION}-jre-headless \
+ python3 \
+ python3-pip \
+ postgresql-client \
+ curl \
+ wget \
+ netcat-openbsd \
+ procps \
+ net-tools \
+ sudo \
+ openssh-server \
+ rsync \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies
+RUN pip3 install psycopg2-binary requests pyyaml
+
+# Copy built artifacts from builder stage
+COPY --from=builder /workspace/ambari-server/target/rpm/ambari-server/RPMS/noarch/*.rpm /tmp/
+
+# Convert and install RPM packages
+RUN cd /tmp && \
+ for rpm in *.rpm; do \
+ alien -d --scripts "$rpm"; \
+ done && \
+ dpkg -i *.deb && \
+ rm -f /tmp/*.rpm /tmp/*.deb
+
+# Create necessary directories
+RUN mkdir -p /var/lib/ambari-server \
+ /var/log/ambari-server \
+ /etc/ambari-server/conf \
+ /opt/ambari-server \
+ && chown -R ambari:ambari /var/lib/ambari-server \
+ /var/log/ambari-server \
+ /etc/ambari-server \
+ /opt/ambari-server
+
+# Copy configuration files and scripts
+COPY docker/config/server/ /etc/ambari-server/conf/
+COPY docker/scripts/ /usr/local/bin/
+
+# Make scripts executable
+RUN chmod +x /usr/local/bin/*.sh
+
+# Create startup script
+RUN cat > /usr/local/bin/start-ambari-server.sh << 'EOF'
+#!/bin/bash
+set -e
+
+# Wait for database
+echo "Waiting for database connection..."
+while ! nc -z ${AMBARI_DB_HOST:-localhost} ${AMBARI_DB_PORT:-5432}; do
+ echo "Database not ready, waiting..."
+ sleep 5
+done
+echo "Database is ready!"
+
+# Setup database if not already done
+if [ ! -f /var/lib/ambari-server/.db-setup-done ]; then
+ echo "Setting up Ambari database..."
+ ambari-server setup --database=postgres \
+ --databasehost=${AMBARI_DB_HOST:-localhost} \
+ --databaseport=${AMBARI_DB_PORT:-5432} \
+ --databasename=${AMBARI_DB_NAME:-ambari} \
+ --databaseusername=${AMBARI_DB_USER:-ambari} \
+ --databasepassword=${AMBARI_DB_PASSWORD:-bigdata} \
+ --silent
+
+ touch /var/lib/ambari-server/.db-setup-done
+ echo "Database setup completed!"
+fi
+
+# Start Ambari Server
+echo "Starting Ambari Server..."
+exec ambari-server start --debug=${AMBARI_DEBUG:-false}
+EOF
+
+RUN chmod +x /usr/local/bin/start-ambari-server.sh
+
+# Configure SSH
+RUN apt-get update && apt-get install -y openssh-server && \
+ mkdir -p /var/run/sshd && \
+ sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
+ sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
+
+# Configure sudo for ambari user
+RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+
+# Switch to ambari user
+USER ambari
+
+# Expose ports
+EXPOSE 8080 8441 5005
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
+ CMD /usr/local/bin/health-check.sh server
+
+# Set working directory
+WORKDIR /home/ambari
+
+# Default command
+CMD ["/usr/local/bin/start-ambari-server.sh"]
+
+# Development stage
+FROM runtime AS development
+
+# Switch back to root for development tools
+USER root
+
+# Install development dependencies
+RUN apt-get update && apt-get install -y \
+ maven \
+ nodejs \
+ npm \
+ git \
+ vim \
+ less \
+ htop \
+ && rm -rf /var/lib/apt/lists/*
+
+# Install global npm packages
+RUN npm install -g brunch
+
+# Create Maven cache directory
+RUN mkdir -p /home/ambari/.m2 && \
+ chown -R ambari:ambari /home/ambari/.m2
+
+# Switch back to ambari user
+USER ambari
+
+# Mount point for source code
+VOLUME ["/workspace"]
+
+# Default command for development
+CMD ["bash"]
diff --git a/docker/images/ambari/QUICKSTART.md b/docker/images/ambari/QUICKSTART.md
new file mode 100644
index 00000000000..861790bafc3
--- /dev/null
+++ b/docker/images/ambari/QUICKSTART.md
@@ -0,0 +1,343 @@
+# Apache Ambari Docker Quick Start Guide
+
+This guide will help you quickly set up and run Apache Ambari using Docker for development and testing purposes.
+
+## Prerequisites
+
+- Docker 20.10+ installed and running
+- Docker Compose 2.0+ installed
+- At least 8GB RAM available for Docker
+- At least 20GB free disk space
+
+## Quick Setup (5 minutes)
+
+### 1. Clone and Navigate
+```bash
+git clone https://github.com/apache/ambari.git
+cd ambari
+```
+
+### 2. Start Development Environment
+```bash
+# Start all services
+docker-compose -f docker/docker-compose.dev.yml up -d
+
+# Check status
+docker-compose -f docker/docker-compose.dev.yml ps
+```
+
+### 3. Access Services
+- **Ambari Web UI**: http://localhost:8080 (admin/admin)
+- **Grafana Dashboard**: http://localhost:3000 (admin/admin)
+- **Database**: localhost:5432 (ambari/bigdata)
+
+### 4. Build Ambari (Optional)
+```bash
+# Enter development container
+docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash
+
+# Build Ambari
+cd /workspace
+mvn clean install -DskipTests
+
+# Or use the build script
+./docker/build.sh all
+```
+
+## Step-by-Step Setup
+
+### Step 1: Environment Check
+```bash
+# Check Docker version
+docker --version
+docker-compose --version
+
+# Check available resources
+docker system df
+docker system info | grep -E "CPUs|Total Memory"
+```
+
+### Step 2: Build Base Images (Optional)
+```bash
+# Build all images from source
+./docker/build.sh all
+
+# Or build specific images
+./docker/build.sh base
+./docker/build.sh server
+./docker/build.sh agent
+./docker/build.sh metrics
+```
+
+### Step 3: Start Services
+```bash
+# Start database first
+docker-compose -f docker/docker-compose.dev.yml up -d ambari-db
+
+# Wait for database to be ready
+docker-compose -f docker/docker-compose.dev.yml logs -f ambari-db
+
+# Start all services
+docker-compose -f docker/docker-compose.dev.yml up -d
+
+# Monitor startup
+docker-compose -f docker/docker-compose.dev.yml logs -f
+```
+
+### Step 4: Verify Installation
+```bash
+# Check service health
+docker-compose -f docker/docker-compose.dev.yml ps
+
+# Check Ambari Server logs
+docker-compose -f docker/docker-compose.dev.yml logs ambari-server
+
+# Test API endpoint
+curl -u admin:admin http://localhost:8080/api/v1/clusters
+```
+
+## Development Workflow
+
+### Building and Testing
+```bash
+# Enter development container
+docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash
+
+# Navigate to workspace
+cd /workspace
+
+# Build specific module
+mvn clean install -pl ambari-server -DskipTests
+
+# Run tests
+mvn test -pl ambari-server
+
+# Build RPMs
+mvn clean package rpm:rpm -DskipTests
+```
+
+### Live Development
+```bash
+# Source code is mounted at /workspace
+# Changes are reflected immediately
+
+# Restart services after code changes
+docker-compose -f docker/docker-compose.dev.yml restart ambari-server
+
+# View logs
+docker-compose -f docker/docker-compose.dev.yml logs -f ambari-server
+```
+
+### Debugging
+```bash
+# Enable debug mode
+export AMBARI_DEBUG=true
+docker-compose -f docker/docker-compose.dev.yml up -d
+
+# Connect debugger to:
+# - Server: localhost:5005
+# - Agent: localhost:5006
+
+# Access container shell
+docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash
+```
+
+## Common Tasks
+
+### Scale Agents
+```bash
+# Scale to 3 agents
+docker-compose -f docker/docker-compose.dev.yml up -d --scale ambari-agent=3
+
+# Check agent status
+docker-compose -f docker/docker-compose.dev.yml ps ambari-agent
+```
+
+### Database Operations
+```bash
+# Connect to database
+docker-compose -f docker/docker-compose.dev.yml exec ambari-db psql -U ambari -d ambari
+
+# Backup database
+docker-compose -f docker/docker-compose.dev.yml exec ambari-db pg_dump -U ambari ambari > backup.sql
+
+# Restore database
+docker-compose -f docker/docker-compose.dev.yml exec -T ambari-db psql -U ambari -d ambari < backup.sql
+```
+
+### View Metrics
+```bash
+# Access Grafana
+open http://localhost:3000
+
+# Check metrics API
+curl http://localhost:6188/ws/v1/timeline/metrics/metadata
+
+# View metrics logs
+docker-compose -f docker/docker-compose.dev.yml logs ambari-metrics
+```
+
+### Clean Up
+```bash
+# Stop all services
+docker-compose -f docker/docker-compose.dev.yml down
+
+# Remove volumes (WARNING: This deletes all data)
+docker-compose -f docker/docker-compose.dev.yml down -v
+
+# Clean up images
+docker system prune -a
+```
+
+## Troubleshooting
+
+### Common Issues
+
+#### Services Won't Start
+```bash
+# Check logs
+docker-compose -f docker/docker-compose.dev.yml logs
+
+# Check resource usage
+docker stats
+
+# Restart specific service
+docker-compose -f docker/docker-compose.dev.yml restart ambari-server
+```
+
+#### Database Connection Issues
+```bash
+# Check database status
+docker-compose -f docker/docker-compose.dev.yml exec ambari-db pg_isready -U ambari
+
+# Reset database
+docker-compose -f docker/docker-compose.dev.yml down
+docker volume rm ambari_ambari-db-data
+docker-compose -f docker/docker-compose.dev.yml up -d ambari-db
+```
+
+#### Port Conflicts
+```bash
+# Check what's using ports
+lsof -i :8080
+lsof -i :5432
+
+# Change ports in docker-compose.dev.yml
+# Example: "8081:8080" instead of "8080:8080"
+```
+
+#### Memory Issues
+```bash
+# Check Docker memory limit
+docker system info | grep Memory
+
+# Increase Docker memory in Docker Desktop settings
+# Or reduce JVM heap sizes in docker-compose.dev.yml
+```
+
+### Health Checks
+```bash
+# Manual health check
+docker-compose -f docker/docker-compose.dev.yml exec ambari-server /usr/local/bin/health-check.sh
+
+# Check all container health
+docker-compose -f docker/docker-compose.dev.yml ps
+```
+
+### Performance Tuning
+```bash
+# Enable BuildKit for faster builds
+export DOCKER_BUILDKIT=1
+
+# Use cached Maven dependencies
+# (Already configured in docker-compose.dev.yml)
+
+# Increase JVM memory if needed
+# Edit JAVA_OPTS in docker-compose.dev.yml
+```
+
+## Advanced Usage
+
+### Custom Configuration
+```bash
+# Create custom configuration
+mkdir -p docker/config/server
+echo "server.jdbc.url=jdbc:postgresql://custom-db:5432/ambari" > docker/config/server/ambari.properties
+
+# Mount custom config
+# Add to docker-compose.dev.yml volumes:
+# - ./docker/config/server:/etc/ambari-server/conf
+```
+
+### Multi-Node Setup
+```bash
+# Scale agents
+docker-compose -f docker/docker-compose.dev.yml up -d --scale ambari-agent=3
+
+# Each agent gets a unique hostname
+# Check with: docker-compose -f docker/docker-compose.dev.yml ps
+```
+
+### Production-Like Setup
+```bash
+# Use production compose file
+docker-compose -f docker/docker-compose.prod.yml up -d
+
+# Enable HTTPS
+# Set AMBARI_SERVER_HTTPS=true in environment
+```
+
+### Integration with IDEs
+
+#### IntelliJ IDEA
+1. Open project in IntelliJ
+2. Configure remote debugger:
+ - Host: localhost
+ - Port: 5005 (server) or 5006 (agent)
+3. Set breakpoints and start debugging
+
+#### VS Code
+1. Install Docker extension
+2. Use "Attach to Container" feature
+3. Configure remote debugging in launch.json
+
+## Next Steps
+
+- Read the full [Docker README](README.md) for detailed configuration options
+- Check out [Production Deployment Guide](docker-compose.prod.yml) for production setup
+- Explore [Kubernetes deployment](k8s/) for container orchestration
+- Join the [Ambari community](https://ambari.apache.org/mail-lists.html) for support
+
+## Getting Help
+
+- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/)
+- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues)
+- **Community**: [Mailing Lists](https://ambari.apache.org/mail-lists.html)
+- **Docker Logs**: `docker-compose -f docker/docker-compose.dev.yml logs`
+
+## Useful Commands Reference
+
+```bash
+# Start services
+docker-compose -f docker/docker-compose.dev.yml up -d
+
+# Stop services
+docker-compose -f docker/docker-compose.dev.yml down
+
+# View logs
+docker-compose -f docker/docker-compose.dev.yml logs -f [service-name]
+
+# Execute commands in container
+docker-compose -f docker/docker-compose.dev.yml exec [service-name] [command]
+
+# Scale services
+docker-compose -f docker/docker-compose.dev.yml up -d --scale [service-name]=[count]
+
+# Build images
+./docker/build.sh [image-name]
+
+# Health check
+docker-compose -f docker/docker-compose.dev.yml exec [service-name] /usr/local/bin/health-check.sh
+```
+
+Happy developing with Apache Ambari on Docker! 🐳
diff --git a/docker/images/ambari/README.md b/docker/images/ambari/README.md
new file mode 100644
index 00000000000..0181c639d51
--- /dev/null
+++ b/docker/images/ambari/README.md
@@ -0,0 +1,618 @@
+# docker-ambari
+
+This is a docker image of [Apache Ambari](https://github.com/apache/ambari).
+
+## How to build a docker image
+
+There is a docker build script which will build a given Git repo/branch and tag the image.
+
+Usage:
+```bash
+./docker-build.sh [Docker Tag] [Git Branch] [Ambari Git URL] [Kafka Version] [Java Version] [JDK Version] [OpenJDK Image]
+```
+
+This script will check out Ambari Repo `[Ambari Git URL]` on branch `[Git Branch]` and build the docker image for that.
+
+The docker image is tagged as `[Docker Tag]`.
+
+**Parameters:**
+- `Docker Tag`: Name and tag your docker image. Default is `ambari:latest`.
+- `Git Branch`: The Ambari branch to build. Default is `trunk`.
+- `Ambari Git URL`: The Ambari Git Repo to build, users can set it to their own fork. Please note that, the URL is `https://` based, not `git://`. Default is the Apache Repo: `https://github.com/apache/ambari.git`.
+- `Kafka Version`: The Kafka Version to build ambari with. Default is `2.0`
+- `Java Version`: The Java Build and Runtime image version. Default is `8`
+- `JDK Version`: The JDK parameter to build ambari, set as part of maven build option: `-Djdk.version=${JDK_VERSION}`. Default is `8`
+- `OpenJDK Image`: Base image to use for Ambari build and runtime. Default is `openjdk`.
+
+### Examples
+
+* Example of building and tagging a snapshot on your own fork:
+```bash
+./docker-build.sh ambari_fork:snapshot-3.0 snapshot-3.0 https://github.com/your_own_fork/ambari.git
+```
+
+* Example of building a release version:
+```bash
+./docker-build.sh ambari:release-2.7.5 release-2.7.5 https://github.com/apache/ambari.git
+```
+
+### Build image with arm64 base image
+
+For users on Mac M1 chips, they need to build the images with arm64 base image, e.g. `arm64v8/openjdk`
+
+* Example of building an arm64 image:
+```bash
+./docker-build.sh ambari:latest trunk https://github.com/apache/ambari.git 2.0 8 8 arm64v8/openjdk
+```
+
+or just run the docker build script directly:
+```bash
+docker build -t ambari:latest --no-cache --network=host \
+ --build-arg AMBARI_GIT_URL=https://github.com/apache/ambari.git \
+ --build-arg AMBARI_BRANCH=trunk \
+ --build-arg JDK_VERSION=8 \
+ --build-arg OPENJDK_IMAGE=arm64v8/openjdk \
+ -f Dockerfile .
+```
+
+Note that if you are not on arm64 machine, you can still build the image by turning on the experimental feature of docker, and add `--platform linux/arm64` into the `docker build ...` script.
+
+## How to publish a docker image
+
+Script `docker-push.sh` publishes a given docker image to your docker registry.
+
+In order to push to your own repo, the image needs to be explicitly tagged with the repo name.
+
+* Example of publishing a image to [apache/ambari](https://hub.docker.com/r/apache/ambari) dockerHub repo:
+```bash
+./docker-push.sh apache/ambari:latest
+```
+
+* Tag a built image, then push:
+```bash
+docker tag ambari:release-2.7.5 apache/ambari:release-2.7.5
+docker push apache/ambari:release-2.7.5
+```
+
+Script `docker-build-and-push.sh` builds and publishes this docker image to your docker registry after build.
+
+* Example of building and publishing a image to [apache/ambari](https://hub.docker.com/r/apache/ambari) dockerHub repo:
+```bash
+./docker-build-and-push.sh apache/ambari:latest trunk https://github.com/apache/ambari.git
+```
+
+## How to Run it
+
+The entry point of docker image is `ambari-admin.sh` script.
+
+### Bring up PostgreSQL Database
+
+Example of bring up a local PostgreSQL database in docker:
+```bash
+docker pull postgres:13-alpine
+docker run --name ambari-database --restart always -p 5432:5432 \
+ -e POSTGRES_DB=ambari \
+ -e POSTGRES_USER=ambari \
+ -e POSTGRES_PASSWORD=bigdata \
+ postgres:13-alpine
+```
+
+You can extract the database host from:
+```bash
+docker inspect ambari-database | grep IPAddress
+ "SecondaryIPAddresses": null,
+ "IPAddress": "172.17.0.2",
+ "IPAddress": "172.17.0.2",
+```
+
+Please use local database path `172.17.0.2:5432` as database host parameter.
+
+### Ambari Server
+
+Example of bring up a local Ambari Server:
+```bash
+docker run -p 8080:8080 \
+ -e AMBARI_DB_HOST=172.17.0.2 \
+ -e AMBARI_DB_PORT=5432 \
+ -e AMBARI_DB_NAME=ambari \
+ -e AMBARI_DB_USER=ambari \
+ -e AMBARI_DB_PASSWORD=bigdata \
+ apache/ambari:latest StartServer
+```
+
+### Ambari Agent
+
+Example of bring up a local Ambari Agent:
+```bash
+docker run \
+ -e AMBARI_SERVER_HOST=172.17.0.3 \
+ -e AMBARI_SERVER_PORT=8080 \
+ --privileged \
+ apache/ambari:latest StartAgent
+```
+
+### Ambari Metrics Collector (Optional)
+
+Example of bring up Ambari Metrics Collector:
+```bash
+docker run -p 6188:6188 \
+ -e AMS_HBASE_ROOTDIR=/var/lib/ambari-metrics-collector/hbase \
+ -e AMS_COLLECTOR_PORT=6188 \
+ apache/ambari:latest StartMetrics
+```
+
+## QuickStart
+
+### Use docker compose to bring up Ambari stack
+
+Below is a script to use docker compose to bring up database/ambari-server/ambari-agent
+
+```bash
+docker-compose -f docker-compose.yml up
+```
+
+### Enable Optional Components
+
+#### Enable Metrics Collection
+```bash
+export METRICS_ENABLED=1
+docker-compose --profile metrics -f docker-compose.yml up
+```
+
+#### Enable Grafana Dashboard
+```bash
+export METRICS_ENABLED=1
+export GRAFANA_ENABLED=1
+docker-compose --profile metrics -f docker-compose.yml up
+```
+
+#### Enable Zookeeper and Kafka
+```bash
+export ZOOKEEPER_ENABLED=1
+export KAFKA_ENABLED=1
+docker-compose --profile zookeeper --profile kafka -f docker-compose.yml up
+```
+
+#### Enable All Components
+```bash
+export METRICS_ENABLED=1
+export GRAFANA_ENABLED=1
+export ZOOKEEPER_ENABLED=1
+export KAFKA_ENABLED=1
+docker-compose --profile metrics --profile zookeeper --profile kafka -f docker-compose.yml up
+```
+
+### Scale Ambari Agents
+
+You can scale the number of Ambari agents:
+```bash
+docker-compose -f docker-compose.yml up -d --scale ambari-agent=3
+```
+
+### Access Services
+
+Once your cluster is up and running:
+
+- **Ambari Web UI**: http://localhost:8080 (admin/admin)
+- **Grafana Dashboard**: http://localhost:3000 (admin/admin) - if enabled
+- **Metrics API**: http://localhost:6188/ws/v1/timeline/metrics/metadata - if enabled
+- **Database**: localhost:5432 (ambari/bigdata)
+
+## Configuration
+
+### Environment Variables
+
+#### Ambari Server
+- `AMBARI_DB_HOST`: Database hostname (default: ambari-database)
+- `AMBARI_DB_PORT`: Database port (default: 5432)
+- `AMBARI_DB_NAME`: Database name (default: ambari)
+- `AMBARI_DB_USER`: Database user (default: ambari)
+- `AMBARI_DB_PASSWORD`: Database password (default: bigdata)
+- `AMBARI_SERVER_HTTPS`: Enable HTTPS (default: false)
+- `JAVA_OPTS`: JVM options
+
+#### Ambari Agent
+- `AMBARI_SERVER_HOST`: Ambari Server hostname (default: ambari-server)
+- `AMBARI_SERVER_PORT`: Ambari Server port (default: 8080)
+- `AGENT_HOSTNAME`: Agent hostname (auto-detected if not set)
+
+#### Ambari Metrics (Optional)
+- `AMS_HBASE_ROOTDIR`: HBase root directory (default: /var/lib/ambari-metrics-collector/hbase)
+- `AMS_COLLECTOR_PORT`: Collector port (default: 6188)
+
+#### Optional Components Control
+- `METRICS_ENABLED`: Enable metrics collection (0 or 1, default: 0)
+- `GRAFANA_ENABLED`: Enable Grafana dashboard (0 or 1, default: 0)
+- `ZOOKEEPER_ENABLED`: Enable Zookeeper (0 or 1, default: 0)
+- `KAFKA_ENABLED`: Enable Kafka (0 or 1, default: 0)
+
+### Docker Images
+- `AMBARI_IMAGE`: Ambari image to use (default: apache/ambari:latest)
+- `POSTGRES_IMAGE`: PostgreSQL image to use (default: postgres:13-alpine)
+- `ZK_IMAGE`: Zookeeper image to use (default: zookeeper:3.8.1)
+- `KAFKA_IMAGE`: Kafka image to use (default: bitnami/kafka:3.6)
+
+## Available Dockerfiles
+
+### Dockerfile
+Main production Dockerfile that builds Ambari from source and creates a runtime image.
+
+### Dockerfile.build
+Build-only Dockerfile for development environments with all build tools.
+
+### Dockerfile.package
+Package-based Dockerfile that uses pre-built Ambari packages instead of building from source.
+
+## Troubleshooting
+
+### Common Issues
+
+#### Container Won't Start
+```bash
+# Check logs
+docker-compose logs ambari-server
+
+# Check container status
+docker-compose ps
+
+# Restart specific service
+docker-compose restart ambari-server
+```
+
+#### Database Connection Issues
+```bash
+# Verify database is running
+docker-compose exec ambari-database pg_isready -U ambari
+
+# Check database logs
+docker-compose logs ambari-database
+
+# Reset database
+docker-compose down -v
+docker-compose up -d ambari-database
+```
+
+#### Memory Issues
+```bash
+# Check resource usage
+docker stats
+
+# Increase memory limits in docker-compose.yml
+services:
+ ambari-server:
+ deploy:
+ resources:
+ limits:
+ memory: 4G
+```
+
+### Health Checks
+
+All services include health checks:
+- **Server**: HTTP check on `/api/v1/clusters`
+- **Agent**: Process and heartbeat check
+- **Metrics**: HTTP check on `/ws/v1/timeline/metrics/metadata`
+- **Database**: Connection check
+
+### Debug Mode
+
+Enable debug logging:
+```bash
+export AMBARI_DEBUG=true
+docker-compose up -d
+```
+
+## Security Considerations
+
+### Production Deployment
+1. Change default passwords
+2. Use external database with proper credentials
+3. Enable HTTPS/TLS
+4. Configure firewall rules
+5. Use secrets management
+6. Regular security updates
+
+### Network Security
+```yaml
+# Example secure configuration
+services:
+ ambari-server:
+ environment:
+ - AMBARI_DB_PASSWORD_FILE=/run/secrets/db_password
+ secrets:
+ - db_password
+
+secrets:
+ db_password:
+ external: true
+```
+
+## Performance Tuning
+
+### Resource Allocation
+```yaml
+# Recommended production resources
+services:
+ ambari-server:
+ deploy:
+ resources:
+ limits:
+ memory: 4G
+ cpus: '2.0'
+ reservations:
+ memory: 2G
+ cpus: '1.0'
+```
+
+### JVM Tuning
+```bash
+# Server JVM options
+JAVA_OPTS="-Xmx2g -Xms1g -XX:+UseG1GC"
+
+# Metrics JVM options
+JAVA_OPTS="-Xmx1g -Xms512m"
+```
+
+## Testing and Deployment Workflows
+
+### Complete Build and Test Workflow
+
+#### 1. Build Base Images First
+```bash
+# Build base image (required for all other builds)
+cd docker/images/ambari-base
+./docker-build.sh ambari-base:latest
+
+# Build metrics base (optional)
+cd ../ambari-metrics
+./docker-build.sh ambari-metrics:latest
+```
+
+#### 2. Build Main Ambari Image
+```bash
+# Build from current branch
+cd ../ambari
+./docker-build.sh ambari:latest
+
+# Build from specific branch/fork
+./docker-build.sh ambari:my-feature feature-branch https://github.com/myuser/ambari.git
+
+# Build with custom options
+./docker-build.sh ambari:arm64 trunk https://github.com/apache/ambari.git 2.0 8 8 arm64v8/openjdk
+```
+
+#### 3. Test the Built Images
+```bash
+# Quick test - start basic services
+./quick-test.sh
+
+# Minimal test - server only
+./minimal-test.sh
+
+# Full test - all components
+./simple-test.sh
+
+# Manual testing with docker-compose
+docker-compose up -d
+docker-compose ps
+docker-compose logs ambari-server
+```
+
+#### 4. Verify Functionality
+```bash
+# Check server health
+curl http://localhost:8080/api/v1/clusters
+
+# Check metrics (if enabled)
+curl http://localhost:6188/ws/v1/timeline/metrics/metadata
+
+# Access web UI
+open http://localhost:8080 # admin/admin
+```
+
+### Publishing Images to Registry
+
+#### 1. Tag Images Properly
+```bash
+# Tag for Docker Hub
+docker tag ambari:latest apache/ambari:latest
+docker tag ambari:latest apache/ambari:$(date +%Y%m%d)
+
+# Tag for custom registry
+docker tag ambari:latest myregistry.com/ambari:latest
+```
+
+#### 2. Push Using Scripts
+```bash
+# Push to Docker Hub
+./docker-push.sh apache/ambari:latest
+
+# Push with authentication
+./docker-push.sh apache/ambari:latest --username myuser --password mypass
+
+# Push to custom registry
+./docker-push.sh myregistry.com/ambari:latest --registry myregistry.com
+
+# Dry run to verify
+./docker-push.sh apache/ambari:latest --dry-run
+```
+
+#### 3. Build and Push in One Step
+```bash
+# Build and push latest
+./docker-build-and-push.sh apache/ambari:latest
+
+# Build specific branch and push
+./docker-build-and-push.sh apache/ambari:feature-v1 feature-branch https://github.com/myuser/ambari.git
+```
+
+### Automated CI/CD Pipeline Example
+
+#### GitHub Actions Workflow
+```yaml
+name: Build and Push Ambari Docker Images
+
+on:
+ push:
+ branches: [ main, trunk ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ build-and-test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Build Base Image
+ run: |
+ cd docker/images/ambari-base
+ ./docker-build.sh ambari-base:${{ github.sha }}
+
+ - name: Build Main Image
+ run: |
+ cd docker/images/ambari
+ ./docker-build.sh ambari:${{ github.sha }}
+
+ - name: Test Images
+ run: |
+ cd docker/images/ambari
+ ./quick-test.sh
+
+ - name: Push to Registry
+ if: github.ref == 'refs/heads/main'
+ run: |
+ echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
+ ./docker-push.sh apache/ambari:${{ github.sha }}
+ ./docker-push.sh apache/ambari:latest
+```
+
+### Development Workflow
+
+#### 1. Local Development Setup
+```bash
+# Clone and setup
+git clone https://github.com/apache/ambari.git
+cd ambari
+
+# Build development image
+cd docker/images/ambari
+./docker-build.sh ambari:dev trunk https://github.com/apache/ambari.git
+
+# Start development environment
+docker-compose -f docker-compose.dev.yml up -d
+```
+
+#### 2. Testing Changes
+```bash
+# Rebuild after changes
+./docker-build.sh ambari:dev --no-cache
+
+# Test specific components
+docker-compose restart ambari-server
+docker-compose logs -f ambari-server
+
+# Run integration tests
+./TESTING.md # Follow testing guide
+```
+
+#### 3. Multi-Architecture Builds
+```bash
+# Setup buildx for multi-arch
+docker buildx create --name multiarch --use
+docker buildx inspect --bootstrap
+
+# Build for multiple platforms
+docker buildx build --platform linux/amd64,linux/arm64 \
+ -t apache/ambari:latest \
+ --push .
+```
+
+### Production Deployment
+
+#### 1. Pre-deployment Checklist
+- [ ] Images tested in staging environment
+- [ ] Security scan completed
+- [ ] Performance benchmarks met
+- [ ] Documentation updated
+- [ ] Rollback plan prepared
+
+#### 2. Blue-Green Deployment
+```bash
+# Deploy to green environment
+docker-compose -f docker-compose.prod.yml -p ambari-green up -d
+
+# Verify green environment
+curl http://green-ambari:8080/api/v1/clusters
+
+# Switch traffic (update load balancer)
+# Monitor and rollback if needed
+
+# Cleanup old blue environment
+docker-compose -p ambari-blue down
+```
+
+#### 3. Rolling Updates
+```bash
+# Update images one by one
+docker-compose pull
+docker-compose up -d --no-deps ambari-server
+# Wait and verify
+docker-compose up -d --no-deps ambari-agent
+```
+
+### Monitoring and Maintenance
+
+#### 1. Health Monitoring
+```bash
+# Check all services
+docker-compose ps
+docker stats
+
+# Monitor logs
+docker-compose logs -f --tail=100
+
+# Health check endpoints
+curl http://localhost:8080/api/v1/clusters
+curl http://localhost:6188/ws/v1/timeline/metrics/metadata
+```
+
+#### 2. Backup and Recovery
+```bash
+# Backup database
+docker-compose exec ambari-database pg_dump -U ambari ambari > backup.sql
+
+# Backup configurations
+docker cp ambari_ambari-server_1:/etc/ambari-server/conf ./backup/
+
+# Restore from backup
+docker-compose exec -T ambari-database psql -U ambari ambari < backup.sql
+```
+
+## Contributing
+
+### Adding New Services
+1. Create Dockerfile in appropriate location
+2. Add to docker-compose.yml
+3. Update documentation
+4. Add health checks
+5. Test thoroughly
+
+### Testing Changes
+```bash
+# Run basic test
+docker-compose up -d
+docker-compose ps
+
+# Test specific component
+docker-compose logs ambari-server
+
+# Clean test environment
+docker-compose down -v
+```
+
+## Support
+
+- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/)
+- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues)
+- **Community**: [Apache Ambari Mailing Lists](https://ambari.apache.org/mail-lists.html)
diff --git a/docker/images/ambari/TESTING.md b/docker/images/ambari/TESTING.md
new file mode 100644
index 00000000000..b22d18bf2ea
--- /dev/null
+++ b/docker/images/ambari/TESTING.md
@@ -0,0 +1,417 @@
+# Apache Ambari Docker Testing Guide
+
+This guide provides complete step-by-step testing instructions for the improved Ambari Docker setup.
+
+## Prerequisites
+
+Before testing, ensure you have:
+- Docker 20.10+ installed
+- Docker Compose 2.0+ installed
+- At least 16GB RAM available
+- At least 50GB free disk space
+- Git (to clone the repository)
+
+## Step 1: Environment Setup
+
+```bash
+# Check Docker installation
+docker --version
+docker-compose --version
+
+# Check system resources
+docker system info | grep -E "CPUs|Total Memory"
+df -h # Check disk space
+
+# Navigate to Ambari project directory
+cd /path/to/ambari # Replace with your actual path
+pwd # Should show the ambari directory
+```
+
+## Step 2: Build Docker Images
+
+```bash
+# Make build script executable
+chmod +x docker/build.sh
+
+# Build all images (this will take 15-30 minutes)
+./docker/build.sh all
+
+# Verify images are created
+docker images | grep ambari
+
+# Expected output should show:
+# apache/ambari-server latest
+# apache/ambari-agent latest
+# apache/ambari-metrics latest
+# apache/ambari-base latest
+```
+
+## Step 3: Start the Complete Stack
+
+```bash
+# Start all services in detached mode
+docker-compose -f docker/docker-compose.yml up -d
+
+# Wait for services to start (2-5 minutes)
+# Monitor the startup process
+docker-compose -f docker/docker-compose.yml logs -f
+
+# Check all containers are running
+docker-compose -f docker/docker-compose.yml ps
+
+# Expected output: All services should show "Up" status
+```
+
+## Step 4: Basic Health Verification
+
+```bash
+# Wait for all services to be healthy (may take 5-10 minutes)
+watch docker-compose -f docker/docker-compose.yml ps
+
+# Check individual service health
+docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server
+docker-compose -f docker/docker-compose.yml exec ambari-agent /usr/local/bin/health-check.sh agent
+docker-compose -f docker/docker-compose.yml exec ambari-metrics /usr/local/bin/health-check.sh metrics
+
+# All health checks should return "Status: HEALTHY"
+```
+
+## Step 5: Web Interface Testing
+
+### Test Ambari Web UI
+```bash
+# Open Ambari Web UI
+open http://localhost:8080
+# Or use: curl -I http://localhost:8080
+
+# Login credentials:
+# Username: admin
+# Password: admin
+
+# You should see the Ambari welcome screen
+```
+
+### Test Grafana Dashboard
+```bash
+# Open Grafana
+open http://localhost:3000
+# Or use: curl -I http://localhost:3000
+
+# Login credentials:
+# Username: admin
+# Password: admin
+
+# You should see the Grafana dashboard
+```
+
+### Test Hadoop Web UIs
+```bash
+# Test NameNode UI
+curl -I http://localhost:9870
+open http://localhost:9870
+
+# Test ResourceManager UI
+curl -I http://localhost:8088
+open http://localhost:8088
+
+# Both should return HTTP 200 OK
+```
+
+## Step 6: API Testing
+
+```bash
+# Test Ambari Server API
+curl -u admin:admin http://localhost:8080/api/v1/clusters
+# Expected: JSON response with cluster information
+
+# Test Ambari version info
+curl -u admin:admin http://localhost:8080/api/v1/version
+# Expected: JSON with version details
+
+# Test Metrics Collector API
+curl http://localhost:6188/ws/v1/timeline/metrics/metadata
+# Expected: JSON response with metrics metadata
+
+# Test Grafana API
+curl http://localhost:3000/api/health
+# Expected: {"commit":"","database":"ok","version":""}
+```
+
+## Step 7: Database Testing
+
+```bash
+# Connect to PostgreSQL database
+docker-compose -f docker/docker-compose.yml exec ambari-db psql -U ambari -d ambari
+
+# Run these SQL commands:
+\dt # List tables
+SELECT COUNT(*) FROM users; # Should return 1 (admin user)
+SELECT user_name FROM users; # Should show 'admin'
+\q # Exit
+
+# Test database connectivity from server
+docker-compose -f docker/docker-compose.yml exec ambari-server pg_isready -h ambari-db -p 5432 -U ambari
+# Expected: ambari-db:5432 - accepting connections
+```
+
+## Step 8: Zookeeper Testing
+
+```bash
+# Check Zookeeper status
+docker-compose -f docker/docker-compose.yml exec zookeeper zkServer.sh status
+# Expected: Mode: standalone
+
+# Connect to Zookeeper CLI
+docker-compose -f docker/docker-compose.yml exec zookeeper zkCli.sh -server localhost:2181
+
+# Run these commands in ZK CLI:
+ls / # List root znodes
+create /test "data" # Create test node
+get /test # Get test node data
+delete /test # Delete test node
+quit # Exit ZK CLI
+```
+
+## Step 9: Hadoop Cluster Testing
+
+```bash
+# Check HDFS status
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report
+# Expected: Shows DataNode information
+
+# Test HDFS operations
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -mkdir /test
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -ls /
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -put /etc/hosts /test/
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -cat /test/hosts
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -rm -r /test
+
+# Check YARN nodes
+docker-compose -f docker/docker-compose.yml exec resourcemanager yarn node -list
+# Expected: Shows active NodeManagers
+```
+
+## Step 10: Agent Registration Testing
+
+```bash
+# Check agent logs for registration
+docker-compose -f docker/docker-compose.yml logs ambari-agent | grep -i "registration"
+
+# Verify agent is registered in Ambari
+curl -u admin:admin http://localhost:8080/api/v1/hosts
+# Expected: JSON showing registered hosts
+
+# Check agent heartbeat
+docker-compose -f docker/docker-compose.yml logs ambari-server | grep -i "heartbeat" | tail -5
+# Expected: Recent heartbeat messages
+```
+
+## Step 11: Metrics Collection Testing
+
+```bash
+# Check metrics collector status
+curl http://localhost:6188/ws/v1/timeline/metrics/metadata | jq .
+# Expected: JSON with metrics metadata
+
+# Verify HBase is running (embedded in metrics collector)
+docker-compose -f docker/docker-compose.yml exec ambari-metrics ps aux | grep HMaster
+# Expected: HMaster process running
+
+# Test metrics query (wait 5 minutes after startup)
+curl "http://localhost:6188/ws/v1/timeline/metrics?metricNames=cpu_user&hostname=ambari-agent&appId=HOST&startTime=$(date -d '1 hour ago' +%s)000&endTime=$(date +%s)000" | jq .
+# Expected: JSON with CPU metrics data
+```
+
+## Step 12: Scaling Testing
+
+```bash
+# Scale agents to 3 instances
+docker-compose -f docker/docker-compose.yml up -d --scale ambari-agent=3
+
+# Wait for new agents to register (2-3 minutes)
+sleep 180
+
+# Verify all agents are registered
+curl -u admin:admin http://localhost:8080/api/v1/hosts | jq '.items[].Hosts.host_name'
+# Expected: Should show 3 agent hostnames
+
+# Scale DataNodes to 3 instances
+docker-compose -f docker/docker-compose.yml up -d --scale datanode=3
+
+# Check DataNode status
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report
+# Expected: Should show 3 DataNodes
+```
+
+## Step 13: Performance Testing
+
+```bash
+# Monitor resource usage
+docker stats --no-stream
+
+# Check container health over time
+for i in {1..5}; do
+ echo "=== Health Check $i ==="
+ docker-compose -f docker/docker-compose.yml ps
+ sleep 30
+done
+
+# Test API response times
+time curl -u admin:admin http://localhost:8080/api/v1/clusters
+time curl http://localhost:6188/ws/v1/timeline/metrics/metadata
+# Response times should be under 2 seconds
+```
+
+## Step 14: Failure Recovery Testing
+
+```bash
+# Test container restart
+docker-compose -f docker/docker-compose.yml restart ambari-server
+
+# Wait for restart and check health
+sleep 60
+docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server
+
+# Test database recovery
+docker-compose -f docker/docker-compose.yml restart ambari-db
+sleep 30
+docker-compose -f docker/docker-compose.yml exec ambari-db pg_isready -U ambari
+
+# Verify services recover
+curl -u admin:admin http://localhost:8080/api/v1/clusters
+```
+
+## Step 15: Development Environment Testing
+
+```bash
+# Start development environment
+docker-compose -f docker/docker-compose.dev.yml up -d
+
+# Enter development container
+docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash
+
+# Inside container, test build environment
+cd /workspace
+mvn --version
+java -version
+node --version
+
+# Test Maven build (inside container)
+mvn clean compile -DskipTests -pl ambari-server
+
+# Exit container
+exit
+
+# Stop development environment
+docker-compose -f docker/docker-compose.dev.yml down
+```
+
+## Expected Test Results
+
+### ✅ Success Criteria
+
+All tests should pass with these results:
+
+1. **Images Built**: 4 Ambari images created successfully
+2. **Services Running**: All containers show "Up (healthy)" status
+3. **Web UIs Accessible**:
+ - Ambari UI at http://localhost:8080
+ - Grafana at http://localhost:3000
+ - NameNode UI at http://localhost:9870
+ - ResourceManager UI at http://localhost:8088
+4. **APIs Responding**: All curl commands return valid JSON
+5. **Database Connected**: PostgreSQL accessible with admin user
+6. **Zookeeper Working**: Can create/read/delete znodes
+7. **HDFS Operational**: Can create directories and files
+8. **Agents Registered**: At least 1 agent heartbeating
+9. **Metrics Collecting**: Metrics API returns data
+10. **Scaling Works**: Can scale agents and DataNodes
+
+### ❌ Troubleshooting Common Issues
+
+#### Issue: Containers not starting
+```bash
+# Check logs
+docker-compose -f docker/docker-compose.yml logs [service-name]
+
+# Check resources
+docker system df
+docker system info | grep Memory
+
+# Solution: Increase Docker memory or reduce JVM heap sizes
+```
+
+#### Issue: Port conflicts
+```bash
+# Check port usage
+lsof -i :8080
+lsof -i :5432
+
+# Solution: Change ports in docker-compose.yml
+```
+
+#### Issue: Health checks failing
+```bash
+# Manual health check
+docker-compose -f docker/docker-compose.yml exec [service] /usr/local/bin/health-check.sh [component]
+
+# Check service logs
+docker-compose -f docker/docker-compose.yml logs [service]
+
+# Solution: Wait longer for startup or check configuration
+```
+
+## Cleanup After Testing
+
+```bash
+# Stop all services
+docker-compose -f docker/docker-compose.yml down
+
+# Remove volumes (WARNING: Deletes all data)
+docker-compose -f docker/docker-compose.yml down -v
+
+# Clean up images (optional)
+docker images | grep ambari | awk '{print $3}' | xargs docker rmi
+
+# Clean up system
+docker system prune -f
+```
+
+## Automated Testing Script
+
+Create a test script for automated testing:
+
+```bash
+# Create test script
+cat > test-ambari-docker.sh << 'EOF'
+#!/bin/bash
+set -e
+
+echo "=== Starting Ambari Docker Tests ==="
+
+# Build images
+echo "Building images..."
+./docker/build.sh all
+
+# Start services
+echo "Starting services..."
+docker-compose -f docker/docker-compose.yml up -d
+
+# Wait for services
+echo "Waiting for services to start..."
+sleep 300
+
+# Run tests
+echo "Testing APIs..."
+curl -f -u admin:admin http://localhost:8080/api/v1/clusters
+curl -f http://localhost:6188/ws/v1/timeline/metrics/metadata
+curl -f http://localhost:3000/api/health
+
+echo "=== All tests passed! ==="
+EOF
+
+chmod +x test-ambari-docker.sh
+./test-ambari-docker.sh
+```
+
+This comprehensive testing guide ensures that all components of the improved Ambari Docker setup are working correctly and provides troubleshooting steps for common issues.
diff --git a/docker/images/ambari/VERIFICATION.md b/docker/images/ambari/VERIFICATION.md
new file mode 100644
index 00000000000..0c1a1d1325e
--- /dev/null
+++ b/docker/images/ambari/VERIFICATION.md
@@ -0,0 +1,383 @@
+# Apache Ambari Docker Verification Guide
+
+This guide provides step-by-step instructions to verify the Ambari Docker setup and ensure all components are working correctly.
+
+## Prerequisites
+
+- Docker 20.10+ installed and running
+- Docker Compose 2.0+ installed
+- At least 16GB RAM available for Docker
+- At least 50GB free disk space
+
+## Quick Verification Steps
+
+### 1. Environment Check
+
+```bash
+# Check Docker version
+docker --version
+docker-compose --version
+
+# Check available resources
+docker system df
+docker system info | grep -E "CPUs|Total Memory"
+
+# Ensure you're in the Ambari project root
+pwd # Should show /path/to/ambari
+ls docker/ # Should show docker-compose.yml and Dockerfiles
+```
+
+### 2. Build Images
+
+```bash
+# Build all Ambari images
+./docker/build.sh all
+
+# Or build specific images
+./docker/build.sh server
+./docker/build.sh agent
+./docker/build.sh metrics
+
+# Verify images are built
+docker images | grep ambari
+```
+
+### 3. Start the Complete Stack
+
+```bash
+# Start all services
+docker-compose -f docker/docker-compose.yml up -d
+
+# Check service status
+docker-compose -f docker/docker-compose.yml ps
+
+# Monitor startup logs
+docker-compose -f docker/docker-compose.yml logs -f
+```
+
+### 4. Verify Service Health
+
+```bash
+# Check all container health status
+docker-compose -f docker/docker-compose.yml ps
+
+# Check individual service health
+docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server
+docker-compose -f docker/docker-compose.yml exec ambari-agent /usr/local/bin/health-check.sh agent
+docker-compose -f docker/docker-compose.yml exec ambari-metrics /usr/local/bin/health-check.sh metrics
+```
+
+### 5. Access Web Interfaces
+
+```bash
+# Ambari Web UI
+open http://localhost:8080
+# Default credentials: admin/admin
+
+# Grafana Dashboard
+open http://localhost:3000
+# Default credentials: admin/admin
+
+# Hadoop NameNode UI
+open http://localhost:9870
+
+# YARN ResourceManager UI
+open http://localhost:8088
+```
+
+### 6. API Verification
+
+```bash
+# Test Ambari Server API
+curl -u admin:admin http://localhost:8080/api/v1/clusters
+
+# Test Metrics Collector API
+curl http://localhost:6188/ws/v1/timeline/metrics/metadata
+
+# Test Grafana API
+curl http://localhost:3000/api/health
+```
+
+## Detailed Verification Steps
+
+### Database Verification
+
+```bash
+# Connect to PostgreSQL database
+docker-compose -f docker/docker-compose.yml exec ambari-db psql -U ambari -d ambari
+
+# Check database tables
+\dt
+
+# Verify admin user exists
+SELECT user_name, admin FROM users WHERE user_name = 'admin';
+
+# Exit database
+\q
+```
+
+### Zookeeper Verification
+
+```bash
+# Check Zookeeper status
+docker-compose -f docker/docker-compose.yml exec zookeeper zkServer.sh status
+
+# Connect to Zookeeper CLI
+docker-compose -f docker/docker-compose.yml exec zookeeper zkCli.sh
+
+# List root znodes
+ls /
+
+# Exit Zookeeper CLI
+quit
+```
+
+### Hadoop Cluster Verification
+
+```bash
+# Check HDFS status
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report
+
+# Create test directory in HDFS
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -mkdir /test
+
+# List HDFS contents
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -ls /
+
+# Check YARN nodes
+docker-compose -f docker/docker-compose.yml exec resourcemanager yarn node -list
+```
+
+### Agent Registration Verification
+
+```bash
+# Check agent logs
+docker-compose -f docker/docker-compose.yml logs ambari-agent
+
+# Verify agent registration in Ambari Server
+curl -u admin:admin http://localhost:8080/api/v1/hosts
+
+# Check agent heartbeat
+docker-compose -f docker/docker-compose.yml exec ambari-server tail -f /var/log/ambari-server/ambari-server.log | grep heartbeat
+```
+
+### Metrics Collection Verification
+
+```bash
+# Check metrics collector status
+curl http://localhost:6188/ws/v1/timeline/metrics/metadata
+
+# Verify HBase is running (embedded in metrics collector)
+docker-compose -f docker/docker-compose.yml exec ambari-metrics ps aux | grep HMaster
+
+# Check metrics data
+curl "http://localhost:6188/ws/v1/timeline/metrics?metricNames=cpu_user&hostname=ambari-agent&appId=HOST&startTime=$(date -d '1 hour ago' +%s)000&endTime=$(date +%s)000"
+```
+
+## Scaling and Load Testing
+
+### Scale Agents
+
+```bash
+# Scale to 3 agents
+docker-compose -f docker/docker-compose.yml up -d --scale ambari-agent=3
+
+# Verify all agents are registered
+curl -u admin:admin http://localhost:8080/api/v1/hosts | jq '.items[].Hosts.host_name'
+```
+
+### Scale DataNodes
+
+```bash
+# Scale to 3 DataNodes
+docker-compose -f docker/docker-compose.yml up -d --scale datanode=3
+
+# Check DataNode status
+docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report
+```
+
+## Troubleshooting
+
+### Common Issues and Solutions
+
+#### 1. Services Won't Start
+
+```bash
+# Check logs for specific service
+docker-compose -f docker/docker-compose.yml logs [service-name]
+
+# Check resource usage
+docker stats
+
+# Restart specific service
+docker-compose -f docker/docker-compose.yml restart [service-name]
+```
+
+#### 2. Database Connection Issues
+
+```bash
+# Check database status
+docker-compose -f docker/docker-compose.yml exec ambari-db pg_isready -U ambari
+
+# Reset database
+docker-compose -f docker/docker-compose.yml down
+docker volume rm ambari_ambari-db-data
+docker-compose -f docker/docker-compose.yml up -d ambari-db
+```
+
+#### 3. Port Conflicts
+
+```bash
+# Check what's using ports
+lsof -i :8080
+lsof -i :5432
+
+# Modify ports in docker-compose.yml if needed
+# Example: Change "8080:8080" to "8081:8080"
+```
+
+#### 4. Memory Issues
+
+```bash
+# Check Docker memory limit
+docker system info | grep Memory
+
+# Reduce JVM heap sizes in docker-compose.yml
+# Example: Change JAVA_OPTS from -Xmx4G to -Xmx2G
+```
+
+### Health Check Commands
+
+```bash
+# Manual health checks
+docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server
+docker-compose -f docker/docker-compose.yml exec ambari-agent /usr/local/bin/health-check.sh agent
+docker-compose -f docker/docker-compose.yml exec ambari-metrics /usr/local/bin/health-check.sh metrics
+
+# Check all container health
+docker-compose -f docker/docker-compose.yml ps
+```
+
+### Log Analysis
+
+```bash
+# View all logs
+docker-compose -f docker/docker-compose.yml logs
+
+# Follow specific service logs
+docker-compose -f docker/docker-compose.yml logs -f ambari-server
+
+# Search for errors
+docker-compose -f docker/docker-compose.yml logs | grep -i error
+
+# Check last 100 lines
+docker-compose -f docker/docker-compose.yml logs --tail=100 ambari-server
+```
+
+## Performance Monitoring
+
+### Resource Usage
+
+```bash
+# Monitor container resource usage
+docker stats
+
+# Check disk usage
+docker system df
+
+# Monitor network traffic
+docker-compose -f docker/docker-compose.yml exec ambari-server netstat -tuln
+```
+
+### Metrics Dashboard
+
+1. Access Grafana at http://localhost:3000
+2. Login with admin/admin
+3. Import Ambari dashboards from `/docker/config/grafana/dashboards/`
+4. Monitor cluster metrics in real-time
+
+## Development Workflow
+
+### Live Development
+
+```bash
+# Start development environment
+docker-compose -f docker/docker-compose.dev.yml up -d
+
+# Enter development container
+docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash
+
+# Build and test changes
+cd /workspace
+mvn clean install -DskipTests
+
+# Restart services after changes
+docker-compose -f docker/docker-compose.dev.yml restart ambari-server
+```
+
+### Debugging
+
+```bash
+# Enable debug mode
+export AMBARI_DEBUG=true
+docker-compose -f docker/docker-compose.yml up -d
+
+# Connect debugger to:
+# - Server: localhost:5005
+# - Agent: localhost:5006
+
+# Access container shell
+docker-compose -f docker/docker-compose.yml exec ambari-server bash
+```
+
+## Cleanup
+
+### Stop Services
+
+```bash
+# Stop all services
+docker-compose -f docker/docker-compose.yml down
+
+# Stop and remove volumes (WARNING: This deletes all data)
+docker-compose -f docker/docker-compose.yml down -v
+```
+
+### Clean Up Images
+
+```bash
+# Remove Ambari images
+docker images | grep ambari | awk '{print $3}' | xargs docker rmi
+
+# Clean up system
+docker system prune -a
+```
+
+## Success Criteria
+
+Your Ambari Docker setup is successfully verified when:
+
+1. ✅ All containers are running and healthy
+2. ✅ Ambari Web UI is accessible at http://localhost:8080
+3. ✅ Database connection is working
+4. ✅ At least one agent is registered and heartbeating
+5. ✅ Metrics collector is receiving data
+6. ✅ Grafana dashboards are displaying metrics
+7. ✅ Hadoop cluster (NameNode, DataNodes, ResourceManager) is operational
+8. ✅ API endpoints are responding correctly
+
+## Next Steps
+
+After successful verification:
+
+1. **Cluster Setup**: Use Ambari Web UI to install Hadoop services
+2. **Security**: Configure Kerberos and SSL/TLS for production
+3. **Monitoring**: Set up alerts and monitoring dashboards
+4. **Backup**: Configure database and HDFS backups
+5. **Scaling**: Add more agents and DataNodes as needed
+
+## Getting Help
+
+- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/)
+- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues)
+- **Community**: [Apache Ambari Mailing Lists](https://ambari.apache.org/mail-lists.html)
+- **Docker Logs**: `docker-compose -f docker/docker-compose.yml logs`
diff --git a/docker/images/ambari/bin/ambari-admin.sh b/docker/images/ambari/bin/ambari-admin.sh
new file mode 100755
index 00000000000..ddb04cac461
--- /dev/null
+++ b/docker/images/ambari/bin/ambari-admin.sh
@@ -0,0 +1,385 @@
+#!/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.
+#
+
+# Apache Ambari Admin Script
+# Similar to Pinot's pinot-admin.sh - main entry point for Ambari Docker containers
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_debug() {
+ if [[ "${AMBARI_DEBUG:-false}" == "true" ]]; then
+ echo -e "${BLUE}[DEBUG]${NC} $1"
+ fi
+}
+
+# Default environment variables
+export AMBARI_HOME=${AMBARI_HOME:-/opt/ambari}
+export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-8-openjdk-amd64}
+export PATH=${JAVA_HOME}/bin:${AMBARI_HOME}/bin:${PATH}
+
+# Database configuration
+export AMBARI_DB_HOST=${AMBARI_DB_HOST:-ambari-database}
+export AMBARI_DB_PORT=${AMBARI_DB_PORT:-5432}
+export AMBARI_DB_NAME=${AMBARI_DB_NAME:-ambari}
+export AMBARI_DB_USER=${AMBARI_DB_USER:-ambari}
+export AMBARI_DB_PASSWORD=${AMBARI_DB_PASSWORD:-bigdata}
+
+# Server configuration
+export AMBARI_SERVER_HOST=${AMBARI_SERVER_HOST:-localhost}
+export AMBARI_SERVER_PORT=${AMBARI_SERVER_PORT:-8080}
+
+# Function to show usage
+show_usage() {
+ cat << EOF
+Apache Ambari Admin Script
+
+Usage: $0 [COMMAND] [OPTIONS]
+
+Available Commands:
+ StartServer Start Ambari Server
+ StartAgent Start Ambari Agent
+ StartMetrics Start Ambari Metrics Collector
+ QuickStart Start Ambari in quick start mode
+
+Server Commands:
+ SetupServer Setup Ambari Server database
+ ResetServer Reset Ambari Server
+ UpgradeServer Upgrade Ambari Server
+
+Agent Commands:
+ RegisterAgent Register agent with server
+
+Utility Commands:
+ CheckHealth Check component health
+ ShowVersion Show Ambari version
+ ShowConfig Show current configuration
+
+Options:
+ -h, --help Show this help message
+ -v, --verbose Enable verbose output
+ --debug Enable debug mode
+
+Examples:
+ # Start Ambari Server
+ $0 StartServer
+
+ # Start Ambari Agent connecting to specific server
+ $0 StartAgent -server ambari-server
+
+ # Start Metrics Collector
+ $0 StartMetrics
+
+ # Quick start with all components
+ $0 QuickStart
+
+ # Setup server with custom database
+ $0 SetupServer --database postgres --host db.example.com
+
+Environment Variables:
+ AMBARI_HOME Ambari installation directory
+ JAVA_HOME Java installation directory
+ AMBARI_DB_HOST Database hostname
+ AMBARI_DB_PORT Database port
+ AMBARI_DB_NAME Database name
+ AMBARI_DB_USER Database username
+ AMBARI_DB_PASSWORD Database password
+ AMBARI_SERVER_HOST Server hostname (for agents)
+ AMBARI_SERVER_PORT Server port (for agents)
+ AMBARI_DEBUG Enable debug output
+
+EOF
+}
+
+# Function to wait for service
+wait_for_service() {
+ local host=$1
+ local port=$2
+ local service_name=$3
+ local timeout=${4:-60}
+
+ log_info "Waiting for ${service_name} at ${host}:${port}..."
+
+ local count=0
+ while ! nc -z "${host}" "${port}" >/dev/null 2>&1; do
+ if [ ${count} -ge ${timeout} ]; then
+ log_error "Timeout waiting for ${service_name} at ${host}:${port}"
+ return 1
+ fi
+ count=$((count + 1))
+ sleep 1
+ done
+
+ log_info "${service_name} is available at ${host}:${port}"
+ return 0
+}
+
+# Function to setup Ambari Server
+setup_server() {
+ log_info "Setting up Ambari Server..."
+
+ # Wait for database
+ wait_for_service "${AMBARI_DB_HOST}" "${AMBARI_DB_PORT}" "Database" 120
+
+ # Setup database if not already done
+ if [ ! -f /var/lib/ambari-server/.db-setup-done ]; then
+ log_info "Setting up Ambari database..."
+ ambari-server setup --database=postgres \
+ --databasehost="${AMBARI_DB_HOST}" \
+ --databaseport="${AMBARI_DB_PORT}" \
+ --databasename="${AMBARI_DB_NAME}" \
+ --databaseusername="${AMBARI_DB_USER}" \
+ --databasepassword="${AMBARI_DB_PASSWORD}" \
+ --silent
+
+ touch /var/lib/ambari-server/.db-setup-done
+ log_info "Database setup completed!"
+ else
+ log_info "Database already setup, skipping..."
+ fi
+}
+
+# Function to start Ambari Server
+start_server() {
+ log_info "Starting Ambari Server..."
+
+ # Setup server first
+ setup_server
+
+ # Start server
+ log_info "Starting Ambari Server process..."
+ exec ambari-server start --debug="${AMBARI_DEBUG:-false}"
+}
+
+# Function to start Ambari Agent
+start_agent() {
+ local server_host="${AMBARI_SERVER_HOST}"
+
+ # Parse additional arguments
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ -server|--server)
+ server_host="$2"
+ shift 2
+ ;;
+ *)
+ shift
+ ;;
+ esac
+ done
+
+ log_info "Starting Ambari Agent..."
+ log_info "Server: ${server_host}:${AMBARI_SERVER_PORT}"
+
+ # Wait for server
+ wait_for_service "${server_host}" "${AMBARI_SERVER_PORT}" "Ambari Server" 300
+
+ # Configure agent
+ if [ ! -f /etc/ambari-agent/conf/ambari-agent.ini ]; then
+ log_info "Configuring Ambari Agent..."
+ mkdir -p /etc/ambari-agent/conf
+ cat > /etc/ambari-agent/conf/ambari-agent.ini << EOF
+[server]
+hostname=${server_host}
+url_port=${AMBARI_SERVER_PORT}
+secured_url_port=8441
+
+[agent]
+prefix=/var/lib/ambari-agent/data
+cache_dir=/var/lib/ambari-agent/cache
+log_dir=/var/log/ambari-agent
+run_dir=/var/run/ambari-agent
+EOF
+ fi
+
+ # Start agent
+ log_info "Starting Ambari Agent process..."
+ exec ambari-agent start --debug="${AMBARI_DEBUG:-false}"
+}
+
+# Function to start Ambari Metrics
+start_metrics() {
+ log_info "Starting Ambari Metrics Collector..."
+
+ # Configure metrics collector
+ if [ ! -f /etc/ambari-metrics-collector/conf/ams-site.xml ]; then
+ log_info "Configuring Ambari Metrics Collector..."
+ mkdir -p /etc/ambari-metrics-collector/conf
+ # Add basic configuration here
+ fi
+
+ # Start metrics collector
+ log_info "Starting Ambari Metrics Collector process..."
+ exec ambari-metrics-collector start
+}
+
+# Function for quick start
+quick_start() {
+ log_info "Starting Ambari Quick Start..."
+
+ # Start server in background
+ start_server &
+ SERVER_PID=$!
+
+ # Wait a bit for server to start
+ sleep 30
+
+ # Start agent
+ start_agent &
+ AGENT_PID=$!
+
+ # Wait for both processes
+ wait $SERVER_PID $AGENT_PID
+}
+
+# Function to check health
+check_health() {
+ log_info "Checking Ambari component health..."
+
+ if command -v /usr/local/bin/health-check.sh >/dev/null 2>&1; then
+ /usr/local/bin/health-check.sh
+ else
+ log_warn "Health check script not found"
+ return 1
+ fi
+}
+
+# Function to show version
+show_version() {
+ log_info "Apache Ambari Version Information"
+
+ if command -v ambari-server >/dev/null 2>&1; then
+ ambari-server --version 2>/dev/null || echo "Ambari Server: Unknown version"
+ fi
+
+ if command -v ambari-agent >/dev/null 2>&1; then
+ ambari-agent --version 2>/dev/null || echo "Ambari Agent: Unknown version"
+ fi
+
+ echo "Java Version: $(java -version 2>&1 | head -n 1)"
+ echo "Container: $(hostname)"
+}
+
+# Function to show configuration
+show_config() {
+ log_info "Current Ambari Configuration"
+ echo "AMBARI_HOME: ${AMBARI_HOME}"
+ echo "JAVA_HOME: ${JAVA_HOME}"
+ echo "Database Host: ${AMBARI_DB_HOST}"
+ echo "Database Port: ${AMBARI_DB_PORT}"
+ echo "Database Name: ${AMBARI_DB_NAME}"
+ echo "Database User: ${AMBARI_DB_USER}"
+ echo "Server Host: ${AMBARI_SERVER_HOST}"
+ echo "Server Port: ${AMBARI_SERVER_PORT}"
+ echo "Debug Mode: ${AMBARI_DEBUG:-false}"
+}
+
+# Main function
+main() {
+ local command="${1:-}"
+
+ # Parse global options
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ show_usage
+ exit 0
+ ;;
+ -v|--verbose)
+ export AMBARI_DEBUG=true
+ shift
+ ;;
+ --debug)
+ export AMBARI_DEBUG=true
+ shift
+ ;;
+ -*)
+ log_error "Unknown option: $1"
+ show_usage
+ exit 1
+ ;;
+ *)
+ if [[ -z "$command" ]]; then
+ command="$1"
+ fi
+ shift
+ ;;
+ esac
+ done
+
+ # Execute command
+ case "$command" in
+ StartServer)
+ start_server "$@"
+ ;;
+ StartAgent)
+ start_agent "$@"
+ ;;
+ StartMetrics)
+ start_metrics "$@"
+ ;;
+ QuickStart)
+ quick_start "$@"
+ ;;
+ SetupServer)
+ setup_server "$@"
+ ;;
+ CheckHealth)
+ check_health "$@"
+ ;;
+ ShowVersion)
+ show_version "$@"
+ ;;
+ ShowConfig)
+ show_config "$@"
+ ;;
+ "")
+ log_info "No command specified. Starting interactive shell..."
+ exec /bin/bash
+ ;;
+ *)
+ log_error "Unknown command: $command"
+ show_usage
+ exit 1
+ ;;
+ esac
+}
+
+# Run main function
+main "$@"
diff --git a/docker/images/ambari/docker-build-and-push.sh b/docker/images/ambari/docker-build-and-push.sh
new file mode 100755
index 00000000000..133c1c72a33
--- /dev/null
+++ b/docker/images/ambari/docker-build-and-push.sh
@@ -0,0 +1,394 @@
+#!/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.
+#
+
+# Apache Ambari Docker Build and Push Script
+# Based on Apache Pinot's docker-build-and-push.sh approach
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Script directory
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_debug() {
+ if [[ "${DEBUG:-false}" == "true" ]]; then
+ echo -e "${BLUE}[DEBUG]${NC} $1"
+ fi
+}
+
+# Function to show usage
+show_usage() {
+ cat << EOF
+Apache Ambari Docker Build and Push Script
+
+Usage: $0 [Docker Tag] [Git Branch] [Ambari Git URL] [OPTIONS]
+
+This script builds and publishes a docker image to your docker registry.
+It combines the functionality of docker-build.sh and docker-push.sh.
+
+Parameters:
+ Docker Tag Name and tag your docker image (required)
+ Git Branch The Ambari branch to build (default: trunk)
+ Ambari Git URL The Ambari Git Repo to build (default: Apache repo)
+
+Build Options:
+ --dockerfile DOCKERFILE Use specific Dockerfile (default: Dockerfile)
+ --no-cache Build without using cache
+ --platform PLATFORM Target platform (e.g., linux/amd64,linux/arm64)
+ --build-arg KEY=VALUE Pass build argument
+
+Push Options:
+ --registry REGISTRY Docker registry URL (default: docker.io)
+ --username USERNAME Registry username (can also use DOCKER_USERNAME env var)
+ --password PASSWORD Registry password (can also use DOCKER_PASSWORD env var)
+ --dry-run Show what would be done without actually doing it
+ --force Force push even if image exists
+ --skip-push Build only, skip push
+
+General Options:
+ --help Show this help message
+
+Examples:
+ # Build and push to Docker Hub (apache/ambari repo):
+ $0 apache/ambari:latest
+
+ # Build from specific branch and push:
+ $0 apache/ambari:2.7.5 release-2.7.5
+
+ # Build from fork and push with authentication:
+ $0 myregistry.com/ambari:latest trunk https://github.com/myfork/ambari.git \\
+ --registry myregistry.com --username myuser --password mypass
+
+ # Build only (skip push):
+ $0 ambari:dev trunk --skip-push
+
+ # Dry run to see what would be done:
+ $0 apache/ambari:latest --dry-run
+
+Environment Variables:
+ DOCKER_USERNAME Registry username
+ DOCKER_PASSWORD Registry password
+ DOCKER_REGISTRY Default registry URL
+ DOCKER_BUILDKIT Enable BuildKit (recommended: 1)
+ DEBUG Enable debug output (true/false)
+
+EOF
+}
+
+# Function to parse arguments
+parse_args() {
+ # Required arguments
+ DOCKER_TAG=""
+ GIT_BRANCH="trunk"
+ AMBARI_GIT_URL="https://github.com/apache/ambari.git"
+
+ # Build options
+ DOCKERFILE="Dockerfile"
+ NO_CACHE=""
+ PLATFORM=""
+ BUILD_ARGS=()
+
+ # Push options
+ REGISTRY="${DOCKER_REGISTRY:-docker.io}"
+ USERNAME="${DOCKER_USERNAME:-}"
+ PASSWORD="${DOCKER_PASSWORD:-}"
+ DRY_RUN=false
+ FORCE=false
+ SKIP_PUSH=false
+
+ # Parse positional arguments first
+ if [[ $# -gt 0 && ! "$1" =~ ^-- ]]; then
+ DOCKER_TAG="$1"
+ shift
+ fi
+
+ if [[ $# -gt 0 && ! "$1" =~ ^-- ]]; then
+ GIT_BRANCH="$1"
+ shift
+ fi
+
+ if [[ $# -gt 0 && ! "$1" =~ ^-- ]]; then
+ AMBARI_GIT_URL="$1"
+ shift
+ fi
+
+ # Parse optional arguments
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ --dockerfile)
+ DOCKERFILE="$2"
+ shift 2
+ ;;
+ --no-cache)
+ NO_CACHE="--no-cache"
+ shift
+ ;;
+ --platform)
+ PLATFORM="--platform $2"
+ shift 2
+ ;;
+ --build-arg)
+ BUILD_ARGS+=("--build-arg" "$2")
+ shift 2
+ ;;
+ --registry)
+ REGISTRY="$2"
+ shift 2
+ ;;
+ --username)
+ USERNAME="$2"
+ shift 2
+ ;;
+ --password)
+ PASSWORD="$2"
+ shift 2
+ ;;
+ --dry-run)
+ DRY_RUN=true
+ shift
+ ;;
+ --force)
+ FORCE=true
+ shift
+ ;;
+ --skip-push)
+ SKIP_PUSH=true
+ shift
+ ;;
+ --help)
+ show_usage
+ exit 0
+ ;;
+ *)
+ log_error "Unknown option: $1"
+ show_usage
+ exit 1
+ ;;
+ esac
+ done
+
+ # Validate required arguments
+ if [[ -z "$DOCKER_TAG" ]]; then
+ log_error "Docker tag is required"
+ show_usage
+ exit 1
+ fi
+}
+
+# Function to display configuration
+display_config() {
+ log_info "=== Build and Push Configuration ==="
+ log_info "Docker Tag: $DOCKER_TAG"
+ log_info "Git Branch: $GIT_BRANCH"
+ log_info "Ambari Git URL: $AMBARI_GIT_URL"
+ log_info "Dockerfile: $DOCKERFILE"
+ if [[ -n "$PLATFORM" ]]; then
+ log_info "Platform: $PLATFORM"
+ fi
+ if [[ "$SKIP_PUSH" == "false" ]]; then
+ log_info "Registry: $REGISTRY"
+ log_info "Username: ${USERNAME:-}"
+ log_info "Password: ${PASSWORD:+}${PASSWORD:-}"
+ else
+ log_info "Push: SKIPPED"
+ fi
+ log_info "Dry Run: $DRY_RUN"
+ log_info "Force: $FORCE"
+ log_info "================================="
+}
+
+# Function to build image
+build_image() {
+ log_info "=== Building Docker Image ==="
+
+ # Prepare build command arguments
+ local build_cmd_args=(
+ "$DOCKER_TAG"
+ "$GIT_BRANCH"
+ "$AMBARI_GIT_URL"
+ )
+
+ # Add build options
+ if [[ -n "$DOCKERFILE" && "$DOCKERFILE" != "Dockerfile" ]]; then
+ build_cmd_args+=("--dockerfile" "$DOCKERFILE")
+ fi
+
+ if [[ -n "$NO_CACHE" ]]; then
+ build_cmd_args+=("$NO_CACHE")
+ fi
+
+ if [[ -n "$PLATFORM" ]]; then
+ build_cmd_args+=($PLATFORM)
+ fi
+
+ # Add custom build args
+ build_cmd_args+=("${BUILD_ARGS[@]}")
+
+ # Execute build command
+ if [[ "$DRY_RUN" == "true" ]]; then
+ log_info "[DRY RUN] Would execute: $SCRIPT_DIR/docker-build.sh ${build_cmd_args[*]}"
+ return 0
+ else
+ log_info "Executing: $SCRIPT_DIR/docker-build.sh ${build_cmd_args[*]}"
+ if "$SCRIPT_DIR/docker-build.sh" "${build_cmd_args[@]}"; then
+ log_info "Build completed successfully"
+ return 0
+ else
+ log_error "Build failed"
+ return 1
+ fi
+ fi
+}
+
+# Function to push image
+push_image() {
+ log_info "=== Pushing Docker Image ==="
+
+ # Prepare push command arguments
+ local push_cmd_args=("$DOCKER_TAG")
+
+ # Add push options
+ if [[ -n "$REGISTRY" && "$REGISTRY" != "docker.io" ]]; then
+ push_cmd_args+=("--registry" "$REGISTRY")
+ fi
+
+ if [[ -n "$USERNAME" ]]; then
+ push_cmd_args+=("--username" "$USERNAME")
+ fi
+
+ if [[ -n "$PASSWORD" ]]; then
+ push_cmd_args+=("--password" "$PASSWORD")
+ fi
+
+ if [[ "$DRY_RUN" == "true" ]]; then
+ push_cmd_args+=("--dry-run")
+ fi
+
+ if [[ "$FORCE" == "true" ]]; then
+ push_cmd_args+=("--force")
+ fi
+
+ # Execute push command
+ log_info "Executing: $SCRIPT_DIR/docker-push.sh ${push_cmd_args[*]}"
+ if "$SCRIPT_DIR/docker-push.sh" "${push_cmd_args[@]}"; then
+ log_info "Push completed successfully"
+ return 0
+ else
+ log_error "Push failed"
+ return 1
+ fi
+}
+
+# Function to validate prerequisites
+validate_prerequisites() {
+ log_info "Validating prerequisites..."
+
+ # Check if build script exists
+ if [[ ! -f "$SCRIPT_DIR/docker-build.sh" ]]; then
+ log_error "Build script not found: $SCRIPT_DIR/docker-build.sh"
+ exit 1
+ fi
+
+ # Check if push script exists (only if not skipping push)
+ if [[ "$SKIP_PUSH" == "false" && ! -f "$SCRIPT_DIR/docker-push.sh" ]]; then
+ log_error "Push script not found: $SCRIPT_DIR/docker-push.sh"
+ exit 1
+ fi
+
+ # Make sure scripts are executable
+ chmod +x "$SCRIPT_DIR/docker-build.sh"
+ if [[ "$SKIP_PUSH" == "false" ]]; then
+ chmod +x "$SCRIPT_DIR/docker-push.sh"
+ fi
+
+ log_info "Prerequisites validation passed"
+}
+
+# Main function
+main() {
+ log_info "Apache Ambari Docker Build and Push Script"
+ log_info "=========================================="
+
+ # Parse arguments
+ parse_args "$@"
+
+ # Validate prerequisites
+ validate_prerequisites
+
+ # Display configuration
+ display_config
+
+ # Build image
+ if ! build_image; then
+ log_error "Build phase failed"
+ exit 1
+ fi
+
+ # Push image (if not skipped)
+ if [[ "$SKIP_PUSH" == "false" ]]; then
+ if ! push_image; then
+ log_error "Push phase failed"
+ exit 1
+ fi
+ else
+ log_info "Push phase skipped as requested"
+ fi
+
+ # Success message
+ log_info ""
+ log_info "=== Build and Push Completed Successfully ==="
+ log_info "Image: $DOCKER_TAG"
+ if [[ "$SKIP_PUSH" == "false" && "$DRY_RUN" == "false" ]]; then
+ log_info "Registry: $REGISTRY"
+ log_info ""
+ log_info "Next steps:"
+ log_info " 1. Verify image: docker pull $DOCKER_TAG"
+ log_info " 2. Test image: docker run -it --rm $DOCKER_TAG"
+ log_info " 3. Use in production deployments"
+ elif [[ "$DRY_RUN" == "true" ]]; then
+ log_info "This was a dry run - no actual changes were made"
+ else
+ log_info "Image built locally - use docker-push.sh to publish"
+ fi
+
+ log_info "============================================="
+}
+
+# Run main function
+main "$@"
diff --git a/docker/images/ambari/docker-build.sh b/docker/images/ambari/docker-build.sh
new file mode 100755
index 00000000000..3eb2448f6bb
--- /dev/null
+++ b/docker/images/ambari/docker-build.sh
@@ -0,0 +1,335 @@
+#!/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.
+#
+
+# Apache Ambari Docker Build Script
+# Based on Apache Pinot's docker-build.sh approach
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Default configuration
+DEFAULT_DOCKER_TAG="ambari:latest"
+DEFAULT_GIT_BRANCH="trunk"
+DEFAULT_AMBARI_GIT_URL="https://github.com/apache/ambari.git"
+DEFAULT_KAFKA_VERSION="2.0"
+DEFAULT_JAVA_VERSION="8"
+DEFAULT_JDK_VERSION="8"
+DEFAULT_OPENJDK_IMAGE="eclipse-temurin"
+
+# Script directory
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_debug() {
+ if [[ "${DEBUG:-false}" == "true" ]]; then
+ echo -e "${BLUE}[DEBUG]${NC} $1"
+ fi
+}
+
+# Function to show usage
+show_usage() {
+ cat << EOF
+Apache Ambari Docker Build Script
+
+Usage: $0 [Docker Tag] [Git Branch] [Ambari Git URL] [Kafka Version] [Java Version] [JDK Version] [OpenJDK Image]
+
+This script will check out Ambari Repo [Ambari Git URL] on branch [Git Branch] and build the docker image for that.
+The docker image is tagged as [Docker Tag].
+
+Parameters:
+ Docker Tag Name and tag your docker image. Default is '$DEFAULT_DOCKER_TAG'.
+ Git Branch The Ambari branch to build. Default is '$DEFAULT_GIT_BRANCH'.
+ Ambari Git URL The Ambari Git Repo to build, users can set it to their own fork.
+ Please note that, the URL is https:// based, not git://.
+ Default is the Apache Repo: '$DEFAULT_AMBARI_GIT_URL'.
+ Kafka Version The Kafka Version to build ambari with. Default is '$DEFAULT_KAFKA_VERSION'
+ Java Version The Java Build and Runtime image version. Default is '$DEFAULT_JAVA_VERSION'
+ JDK Version The JDK parameter to build ambari, set as part of maven build option:
+ -Djdk.version=\${JDK_VERSION}. Default is '$DEFAULT_JDK_VERSION'
+ OpenJDK Image Base image to use for Ambari build and runtime. Default is '$DEFAULT_OPENJDK_IMAGE'.
+
+Examples:
+ # Build and tag a snapshot on your own fork:
+ $0 ambari_fork:snapshot-3.0 snapshot-3.0 https://github.com/your_own_fork/ambari.git
+
+ # Build a release version:
+ $0 ambari:release-2.7.5 release-2.7.5 https://github.com/apache/ambari.git
+
+ # Build image with arm64 base image (for Mac M1 chips):
+ $0 ambari:latest trunk https://github.com/apache/ambari.git 2.0 8 8 arm64v8/openjdk
+
+Options:
+ --dockerfile DOCKERFILE Use specific Dockerfile (default: Dockerfile)
+ --no-cache Build without using cache
+ --platform PLATFORM Target platform (e.g., linux/amd64,linux/arm64)
+ --build-arg KEY=VALUE Pass build argument
+ --help Show this help message
+
+Environment Variables:
+ DOCKER_BUILDKIT Enable BuildKit (recommended: 1)
+ DEBUG Enable debug output (true/false)
+
+EOF
+}
+
+# Function to parse arguments
+parse_args() {
+ # Optional arguments
+ DOCKERFILE="Dockerfile"
+ NO_CACHE=""
+ PLATFORM=""
+ BUILD_ARGS=()
+
+ # Parse all arguments, separating positional from optional
+ local positional_args=()
+
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ --dockerfile)
+ DOCKERFILE="$2"
+ shift 2
+ ;;
+ --no-cache)
+ NO_CACHE="--no-cache"
+ shift
+ ;;
+ --platform)
+ PLATFORM="--platform $2"
+ shift 2
+ ;;
+ --build-arg)
+ BUILD_ARGS+=("--build-arg" "$2")
+ shift 2
+ ;;
+ --help)
+ show_usage
+ exit 0
+ ;;
+ --*)
+ log_error "Unknown option: $1"
+ show_usage
+ exit 1
+ ;;
+ *)
+ # This is a positional argument
+ positional_args+=("$1")
+ shift
+ ;;
+ esac
+ done
+
+ # Assign positional arguments
+ DOCKER_TAG="${positional_args[0]:-$DEFAULT_DOCKER_TAG}"
+ GIT_BRANCH="${positional_args[1]:-$DEFAULT_GIT_BRANCH}"
+ AMBARI_GIT_URL="${positional_args[2]:-$DEFAULT_AMBARI_GIT_URL}"
+ KAFKA_VERSION="${positional_args[3]:-$DEFAULT_KAFKA_VERSION}"
+ JAVA_VERSION="${positional_args[4]:-$DEFAULT_JAVA_VERSION}"
+ JDK_VERSION="${positional_args[5]:-$DEFAULT_JDK_VERSION}"
+ OPENJDK_IMAGE="${positional_args[6]:-$DEFAULT_OPENJDK_IMAGE}"
+}
+
+# Function to validate inputs
+validate_inputs() {
+ log_info "Validating inputs..."
+
+ # Check if Docker is available
+ if ! command -v docker >/dev/null 2>&1; then
+ log_error "Docker is not installed or not in PATH"
+ exit 1
+ fi
+
+ # Check Docker daemon
+ if ! docker info >/dev/null 2>&1; then
+ log_error "Docker daemon is not running"
+ exit 1
+ fi
+
+ # Validate Git URL format
+ if [[ ! "$AMBARI_GIT_URL" =~ ^https:// ]]; then
+ log_error "Git URL must be https:// based: $AMBARI_GIT_URL"
+ exit 1
+ fi
+
+ # Check if Dockerfile exists
+ if [[ ! -f "$SCRIPT_DIR/$DOCKERFILE" ]]; then
+ log_error "Dockerfile not found: $SCRIPT_DIR/$DOCKERFILE"
+ exit 1
+ fi
+
+ log_info "Input validation passed"
+}
+
+# Function to display configuration
+display_config() {
+ log_info "=== Build Configuration ==="
+ log_info "Docker Tag: $DOCKER_TAG"
+ log_info "Git Branch: $GIT_BRANCH"
+ log_info "Ambari Git URL: $AMBARI_GIT_URL"
+ log_info "Kafka Version: $KAFKA_VERSION"
+ log_info "Java Version: $JAVA_VERSION"
+ log_info "JDK Version: $JDK_VERSION"
+ log_info "OpenJDK Image: $OPENJDK_IMAGE"
+ log_info "Dockerfile: $DOCKERFILE"
+ if [[ -n "$PLATFORM" ]]; then
+ log_info "Platform: $PLATFORM"
+ fi
+ log_info "=========================="
+}
+
+# Function to build Docker image
+build_image() {
+ log_info "Starting Docker build..."
+
+ # Prepare build arguments
+ local build_args=(
+ "--build-arg" "AMBARI_GIT_URL=$AMBARI_GIT_URL"
+ "--build-arg" "AMBARI_BRANCH=$GIT_BRANCH"
+ "--build-arg" "KAFKA_VERSION=$KAFKA_VERSION"
+ "--build-arg" "JDK_VERSION=$JDK_VERSION"
+ "--build-arg" "OPENJDK_IMAGE=$OPENJDK_IMAGE"
+ )
+
+ # Add custom build args
+ build_args+=("${BUILD_ARGS[@]}")
+
+ # Build command
+ local build_cmd=(
+ "docker" "build"
+ "${build_args[@]}"
+ "-f" "$SCRIPT_DIR/$DOCKERFILE"
+ "-t" "$DOCKER_TAG"
+ )
+
+ # Add optional flags
+ if [[ -n "$NO_CACHE" ]]; then
+ build_cmd+=("$NO_CACHE")
+ fi
+
+ if [[ -n "$PLATFORM" ]]; then
+ build_cmd+=($PLATFORM)
+ fi
+
+ # Add context (docker directory - parent of script directory)
+ build_cmd+=("$(dirname "$(dirname "$SCRIPT_DIR")")")
+
+ log_debug "Build command: ${build_cmd[*]}"
+
+ # Execute build
+ log_info "Executing: ${build_cmd[*]}"
+ if "${build_cmd[@]}"; then
+ log_info "Docker image built successfully: $DOCKER_TAG"
+
+ # Display image info
+ log_info "Image details:"
+ docker images "$DOCKER_TAG" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}"
+
+ return 0
+ else
+ log_error "Docker build failed"
+ return 1
+ fi
+}
+
+# Function to run post-build tests
+run_tests() {
+ log_info "Running post-build tests..."
+
+ # Test if image can be run
+ log_info "Testing image startup..."
+ if docker run --rm "$DOCKER_TAG" java -version >/dev/null 2>&1; then
+ log_info "Image startup test passed"
+ else
+ log_warn "Image startup test failed"
+ fi
+
+ # Test if required tools are available
+ log_info "Testing required tools..."
+ if docker run --rm "$DOCKER_TAG" which ambari-server >/dev/null 2>&1; then
+ log_info "Ambari server found in image"
+ else
+ log_warn "Ambari server not found in image"
+ fi
+}
+
+# Function to cleanup
+cleanup() {
+ log_info "Cleaning up temporary files..."
+ # Add any cleanup logic here if needed
+}
+
+# Main function
+main() {
+ log_info "Apache Ambari Docker Build Script"
+ log_info "================================="
+
+ # Parse arguments
+ parse_args "$@"
+
+ # Validate inputs
+ validate_inputs
+
+ # Display configuration
+ display_config
+
+ # Set up cleanup trap
+ trap cleanup EXIT
+
+ # Build image
+ if build_image; then
+ # Run tests
+ run_tests
+
+ log_info "Build completed successfully!"
+ log_info "Image: $DOCKER_TAG"
+
+ # Show next steps
+ log_info ""
+ log_info "Next steps:"
+ log_info " 1. Test the image: docker run -it --rm $DOCKER_TAG"
+ log_info " 2. Push to registry: docker push $DOCKER_TAG"
+ log_info " 3. Use in docker-compose or kubernetes"
+
+ exit 0
+ else
+ log_error "Build failed!"
+ exit 1
+ fi
+}
+
+# Run main function
+main "$@"
diff --git a/docker/images/ambari/docker-compose.yml b/docker/images/ambari/docker-compose.yml
new file mode 100644
index 00000000000..8930e0ac9a7
--- /dev/null
+++ b/docker/images/ambari/docker-compose.yml
@@ -0,0 +1,273 @@
+#
+# 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.
+#
+
+# Apache Ambari Docker Compose Configuration
+# Based on Apache Pinot's docker-compose approach
+
+version: '3.7'
+
+services:
+ # PostgreSQL Database for Ambari
+ ambari-database:
+ image: ${POSTGRES_IMAGE:-postgres:13-alpine}
+ container_name: "ambari-database"
+ restart: unless-stopped
+ ports:
+ - "5432:5432"
+ environment:
+ POSTGRES_DB: ambari
+ POSTGRES_USER: ambari
+ POSTGRES_PASSWORD: bigdata
+ POSTGRES_INITDB_ARGS: "--encoding=UTF8"
+ volumes:
+ - ambari-db-data:/var/lib/postgresql/data
+ networks:
+ - ambari-demo
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 10s
+
+ # Ambari Server
+ ambari-server:
+ image: ${AMBARI_IMAGE:-apache/ambari:latest}
+ command: "StartServer -zkAddress ambari-zookeeper:2181"
+ container_name: "ambari-server"
+ restart: unless-stopped
+ ports:
+ - "8080:8080" # Ambari Web UI
+ - "8441:8441" # Ambari HTTPS
+ environment:
+ # Database configuration
+ AMBARI_DB_HOST: ambari-database
+ AMBARI_DB_PORT: 5432
+ AMBARI_DB_NAME: ambari
+ AMBARI_DB_USER: ambari
+ AMBARI_DB_PASSWORD: bigdata
+ # Server configuration
+ AMBARI_COMPONENT: server
+ JAVA_OPTS: "-Dplugins.dir=/opt/ambari/plugins -Xms1G -Xmx4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-ambari-server.log"
+ depends_on:
+ ambari-database:
+ condition: service_healthy
+ networks:
+ - ambari-demo
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/clusters || exit 1"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 120s
+ volumes:
+ - ambari-server-data:/var/lib/ambari-server
+ - ambari-server-logs:/var/log/ambari-server
+
+ # Ambari Agent (can be scaled)
+ ambari-agent:
+ image: ${AMBARI_IMAGE:-apache/ambari:latest}
+ command: "StartAgent -server ambari-server"
+ container_name: "ambari-agent"
+ restart: unless-stopped
+ environment:
+ # Server connection
+ AMBARI_SERVER_HOST: ambari-server
+ AMBARI_SERVER_PORT: 8080
+ AMBARI_COMPONENT: agent
+ # Agent configuration
+ AGENT_HOSTNAME: ambari-agent
+ JAVA_OPTS: "-Xms512M -Xmx1G -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
+ depends_on:
+ ambari-server:
+ condition: service_healthy
+ networks:
+ - ambari-demo
+ healthcheck:
+ test: ["CMD-SHELL", "/usr/local/bin/health-check.sh"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 60s
+ volumes:
+ - ambari-agent-data:/var/lib/ambari-agent
+ - ambari-agent-logs:/var/log/ambari-agent
+ privileged: true # Required for some agent operations
+
+ # Ambari Metrics Collector (Optional - controlled by METRICS_ENABLED)
+ ambari-metrics:
+ image: ${AMBARI_IMAGE:-apache/ambari:latest}
+ command: "StartMetrics"
+ container_name: "ambari-metrics"
+ restart: unless-stopped
+ ports:
+ - "6188:6188" # Metrics Collector API
+ - "61888:61888" # Metrics aggregation port
+ environment:
+ # Metrics configuration
+ AMS_HBASE_ROOTDIR: /var/lib/ambari-metrics-collector/hbase
+ AMS_COLLECTOR_PORT: 6188
+ AMBARI_COMPONENT: metrics
+ JAVA_OPTS: "-Xms1G -Xmx2G -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
+ depends_on:
+ ambari-server:
+ condition: service_healthy
+ networks:
+ - ambari-demo
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:6188/ws/v1/timeline/metrics/metadata || exit 1"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 90s
+ volumes:
+ - ambari-metrics-data:/var/lib/ambari-metrics-collector
+ - ambari-metrics-logs:/var/log/ambari-metrics-collector
+ profiles:
+ - metrics
+ deploy:
+ replicas: ${METRICS_ENABLED:-0} # Default to 0, meaning metrics won't start unless METRICS_ENABLED is set
+
+ # Grafana for Metrics Visualization (Optional)
+ ambari-grafana:
+ image: grafana/grafana:10.2.0
+ container_name: "ambari-grafana"
+ restart: unless-stopped
+ ports:
+ - "3000:3000" # Grafana Web UI
+ environment:
+ GF_SECURITY_ADMIN_PASSWORD: admin
+ GF_INSTALL_PLUGINS: grafana-clock-panel,grafana-simple-json-datasource
+ GF_USERS_ALLOW_SIGN_UP: false
+ GF_SERVER_ROOT_URL: http://localhost:3000
+ depends_on:
+ - ambari-metrics
+ networks:
+ - ambari-demo
+ healthcheck:
+ test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 30s
+ volumes:
+ - grafana-data:/var/lib/grafana
+ profiles:
+ - metrics
+ deploy:
+ replicas: ${GRAFANA_ENABLED:-0} # Default to 0, controlled by GRAFANA_ENABLED
+
+ # Optional Zookeeper (for advanced setups)
+ ambari-zookeeper:
+ image: ${ZK_IMAGE:-zookeeper:3.8.1}
+ container_name: "ambari-zookeeper"
+ restart: unless-stopped
+ ports:
+ - "2181:2181"
+ environment:
+ ZOOKEEPER_CLIENT_PORT: 2181
+ ZOOKEEPER_TICK_TIME: 2000
+ networks:
+ - ambari-demo
+ healthcheck:
+ test: ["CMD", "zkServer.sh", "status"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 10s
+ volumes:
+ - zookeeper-data:/data
+ - zookeeper-logs:/datalog
+ profiles:
+ - zookeeper
+ deploy:
+ replicas: ${ZOOKEEPER_ENABLED:-0} # Default to 0, controlled by ZOOKEEPER_ENABLED
+
+ # Optional Kafka (for streaming data)
+ ambari-kafka:
+ image: ${KAFKA_IMAGE:-bitnami/kafka:3.6}
+ container_name: "ambari-kafka"
+ restart: unless-stopped
+ ports:
+ - "9092:9092"
+ environment:
+ KAFKA_ZOOKEEPER_CONNECT: ambari-zookeeper:2181/kafka
+ KAFKA_BROKER_ID: 0
+ KAFKA_ADVERTISED_HOST_NAME: kafka
+ depends_on:
+ ambari-zookeeper:
+ condition: service_healthy
+ networks:
+ - ambari-demo
+ healthcheck:
+ test: ["CMD-SHELL", "kafka-broker-api-versions.sh --bootstrap-server kafka:9092"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
+ start_period: 10s
+ volumes:
+ - kafka-data:/bitnami/kafka
+ profiles:
+ - kafka
+ deploy:
+ replicas: ${KAFKA_ENABLED:-0} # Default to 0, controlled by KAFKA_ENABLED
+
+# Networks
+networks:
+ ambari-demo:
+ name: ambari-demo
+ driver: bridge
+
+# Volumes
+volumes:
+ # Database
+ ambari-db-data:
+ driver: local
+
+ # Ambari Server
+ ambari-server-data:
+ driver: local
+ ambari-server-logs:
+ driver: local
+
+ # Ambari Agent
+ ambari-agent-data:
+ driver: local
+ ambari-agent-logs:
+ driver: local
+
+ # Ambari Metrics (Optional)
+ ambari-metrics-data:
+ driver: local
+ ambari-metrics-logs:
+ driver: local
+
+ # Grafana (Optional)
+ grafana-data:
+ driver: local
+
+ # Zookeeper (Optional)
+ zookeeper-data:
+ driver: local
+ zookeeper-logs:
+ driver: local
+
+ # Kafka (Optional)
+ kafka-data:
+ driver: local
diff --git a/docker/images/ambari/docker-push.sh b/docker/images/ambari/docker-push.sh
new file mode 100755
index 00000000000..6f2fd1143a0
--- /dev/null
+++ b/docker/images/ambari/docker-push.sh
@@ -0,0 +1,366 @@
+#!/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.
+#
+
+# Apache Ambari Docker Push Script
+# Based on Apache Pinot's docker-push.sh approach
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Default configuration
+DEFAULT_REGISTRY="apache"
+DEFAULT_TAG="latest"
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_debug() {
+ if [[ "${DEBUG:-false}" == "true" ]]; then
+ echo -e "${BLUE}[DEBUG]${NC} $1"
+ fi
+}
+
+# Function to show usage
+show_usage() {
+ cat << EOF
+Apache Ambari Docker Push Script
+
+Usage: $0 [IMAGE_NAME] [OPTIONS]
+
+This script publishes a given docker image to your docker registry.
+In order to push to your own repo, the image needs to be explicitly tagged with the repo name.
+
+Parameters:
+ IMAGE_NAME Docker image name with tag to push (required)
+
+Options:
+ --registry REGISTRY Docker registry URL (default: docker.io)
+ --username USERNAME Registry username (can also use DOCKER_USERNAME env var)
+ --password PASSWORD Registry password (can also use DOCKER_PASSWORD env var)
+ --dry-run Show what would be pushed without actually pushing
+ --force Force push even if image exists
+ --all-tags Push all tags for the repository
+ --help Show this help message
+
+Examples:
+ # Push to Docker Hub (apache/ambari repo):
+ $0 apache/ambari:latest
+
+ # Push with custom registry:
+ $0 myregistry.com/ambari:latest --registry myregistry.com
+
+ # Push with authentication:
+ $0 apache/ambari:latest --username myuser --password mypass
+
+ # Dry run to see what would be pushed:
+ $0 apache/ambari:latest --dry-run
+
+ # Push all tags:
+ $0 apache/ambari --all-tags
+
+Environment Variables:
+ DOCKER_USERNAME Registry username
+ DOCKER_PASSWORD Registry password
+ DOCKER_REGISTRY Default registry URL
+ DEBUG Enable debug output (true/false)
+
+EOF
+}
+
+# Function to parse arguments
+parse_args() {
+ IMAGE_NAME=""
+ REGISTRY="${DOCKER_REGISTRY:-docker.io}"
+ USERNAME="${DOCKER_USERNAME:-}"
+ PASSWORD="${DOCKER_PASSWORD:-}"
+ DRY_RUN=false
+ FORCE=false
+ ALL_TAGS=false
+
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ --registry)
+ REGISTRY="$2"
+ shift 2
+ ;;
+ --username)
+ USERNAME="$2"
+ shift 2
+ ;;
+ --password)
+ PASSWORD="$2"
+ shift 2
+ ;;
+ --dry-run)
+ DRY_RUN=true
+ shift
+ ;;
+ --force)
+ FORCE=true
+ shift
+ ;;
+ --all-tags)
+ ALL_TAGS=true
+ shift
+ ;;
+ --help)
+ show_usage
+ exit 0
+ ;;
+ -*)
+ log_error "Unknown option: $1"
+ show_usage
+ exit 1
+ ;;
+ *)
+ if [[ -z "$IMAGE_NAME" ]]; then
+ IMAGE_NAME="$1"
+ else
+ log_error "Multiple image names specified: $IMAGE_NAME and $1"
+ exit 1
+ fi
+ shift
+ ;;
+ esac
+ done
+
+ # Validate required arguments
+ if [[ -z "$IMAGE_NAME" ]]; then
+ log_error "Image name is required"
+ show_usage
+ exit 1
+ fi
+}
+
+# Function to validate inputs
+validate_inputs() {
+ log_info "Validating inputs..."
+
+ # Check if Docker is available
+ if ! command -v docker >/dev/null 2>&1; then
+ log_error "Docker is not installed or not in PATH"
+ exit 1
+ fi
+
+ # Check Docker daemon
+ if ! docker info >/dev/null 2>&1; then
+ log_error "Docker daemon is not running"
+ exit 1
+ fi
+
+ # Check if image exists locally
+ if [[ "$ALL_TAGS" == "false" ]]; then
+ if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
+ log_error "Image not found locally: $IMAGE_NAME"
+ log_info "Available images:"
+ docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}"
+ exit 1
+ fi
+ fi
+
+ log_info "Input validation passed"
+}
+
+# Function to display configuration
+display_config() {
+ log_info "=== Push Configuration ==="
+ log_info "Image Name: $IMAGE_NAME"
+ log_info "Registry: $REGISTRY"
+ log_info "Username: ${USERNAME:-}"
+ log_info "Password: ${PASSWORD:+}${PASSWORD:-}"
+ log_info "Dry Run: $DRY_RUN"
+ log_info "Force: $FORCE"
+ log_info "All Tags: $ALL_TAGS"
+ log_info "========================="
+}
+
+# Function to login to registry
+docker_login() {
+ if [[ -n "$USERNAME" && -n "$PASSWORD" ]]; then
+ log_info "Logging in to registry: $REGISTRY"
+
+ if [[ "$DRY_RUN" == "true" ]]; then
+ log_info "[DRY RUN] Would login to $REGISTRY as $USERNAME"
+ return 0
+ fi
+
+ if echo "$PASSWORD" | docker login "$REGISTRY" --username "$USERNAME" --password-stdin; then
+ log_info "Successfully logged in to $REGISTRY"
+ else
+ log_error "Failed to login to $REGISTRY"
+ return 1
+ fi
+ else
+ log_info "No credentials provided, assuming already logged in or using public registry"
+ fi
+}
+
+# Function to push image
+push_image() {
+ local image_to_push="$1"
+
+ log_info "Pushing image: $image_to_push"
+
+ if [[ "$DRY_RUN" == "true" ]]; then
+ log_info "[DRY RUN] Would push: $image_to_push"
+ return 0
+ fi
+
+ # Check if image exists on registry (unless force is used)
+ if [[ "$FORCE" == "false" ]]; then
+ log_info "Checking if image already exists on registry..."
+ if docker manifest inspect "$image_to_push" >/dev/null 2>&1; then
+ log_warn "Image already exists on registry: $image_to_push"
+ log_warn "Use --force to overwrite existing image"
+ return 1
+ fi
+ fi
+
+ # Push the image
+ if docker push "$image_to_push"; then
+ log_info "Successfully pushed: $image_to_push"
+
+ # Display image info
+ log_info "Pushed image details:"
+ docker images "$image_to_push" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}"
+
+ return 0
+ else
+ log_error "Failed to push: $image_to_push"
+ return 1
+ fi
+}
+
+# Function to push all tags
+push_all_tags() {
+ local repo_name="${IMAGE_NAME%:*}" # Remove tag if present
+
+ log_info "Finding all local tags for repository: $repo_name"
+
+ # Get all local images for this repository
+ local images
+ images=$(docker images "$repo_name" --format "{{.Repository}}:{{.Tag}}" | grep -v "")
+
+ if [[ -z "$images" ]]; then
+ log_error "No images found for repository: $repo_name"
+ return 1
+ fi
+
+ log_info "Found images to push:"
+ echo "$images"
+
+ # Push each image
+ local failed_pushes=()
+ while IFS= read -r image; do
+ if ! push_image "$image"; then
+ failed_pushes+=("$image")
+ fi
+ done <<< "$images"
+
+ # Report results
+ if [[ ${#failed_pushes[@]} -eq 0 ]]; then
+ log_info "All images pushed successfully!"
+ else
+ log_error "Failed to push images: ${failed_pushes[*]}"
+ return 1
+ fi
+}
+
+# Function to logout from registry
+docker_logout() {
+ if [[ -n "$USERNAME" && "$DRY_RUN" == "false" ]]; then
+ log_info "Logging out from registry: $REGISTRY"
+ docker logout "$REGISTRY" || true
+ fi
+}
+
+# Function to cleanup
+cleanup() {
+ docker_logout
+}
+
+# Main function
+main() {
+ log_info "Apache Ambari Docker Push Script"
+ log_info "================================"
+
+ # Parse arguments
+ parse_args "$@"
+
+ # Validate inputs
+ validate_inputs
+
+ # Display configuration
+ display_config
+
+ # Set up cleanup trap
+ trap cleanup EXIT
+
+ # Login to registry
+ if ! docker_login; then
+ log_error "Registry login failed"
+ exit 1
+ fi
+
+ # Push image(s)
+ if [[ "$ALL_TAGS" == "true" ]]; then
+ if push_all_tags; then
+ log_info "All tags pushed successfully!"
+ else
+ log_error "Some pushes failed!"
+ exit 1
+ fi
+ else
+ if push_image "$IMAGE_NAME"; then
+ log_info "Image pushed successfully!"
+ else
+ log_error "Push failed!"
+ exit 1
+ fi
+ fi
+
+ # Show next steps
+ log_info ""
+ log_info "Next steps:"
+ log_info " 1. Verify image on registry: docker pull $IMAGE_NAME"
+ log_info " 2. Use in docker-compose or kubernetes"
+ log_info " 3. Update documentation with new image tag"
+
+ log_info "Push completed successfully!"
+}
+
+# Run main function
+main "$@"
diff --git a/docker/images/ambari/etc/ambari.properties b/docker/images/ambari/etc/ambari.properties
new file mode 100644
index 00000000000..440b77dbd74
--- /dev/null
+++ b/docker/images/ambari/etc/ambari.properties
@@ -0,0 +1,69 @@
+#
+# 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.
+#
+
+# Apache Ambari Configuration Template
+# This file contains default configuration values for Ambari Docker containers
+
+# Database Configuration
+server.jdbc.driver=org.postgresql.Driver
+server.jdbc.url=jdbc:postgresql://${AMBARI_DB_HOST}:${AMBARI_DB_PORT}/${AMBARI_DB_NAME}
+server.jdbc.user.name=${AMBARI_DB_USER}
+server.jdbc.user.passwd=${AMBARI_DB_PASSWORD}
+
+# Server Configuration
+server.http.port=8080
+server.https.port=8441
+server.secured.url.port=8441
+
+# Agent Configuration
+agent.package.install.task.timeout=1800
+agent.task.timeout=900
+agent.parallel.stage.execution.enabled=true
+
+# Metrics Configuration (Optional)
+timeline.metrics.service.default.result.limit=15840
+timeline.metrics.service.checkpointdir=/var/lib/ambari-metrics-collector/checkpoint
+timeline.metrics.aggregator.checkpoint.dir=/var/lib/ambari-metrics-collector/checkpoint
+
+# Security Configuration
+security.server.two_way_ssl=false
+security.server.cert_name=ca.crt
+security.server.key_name=ca.key
+
+# Logging Configuration
+log4j.logger.org.apache.ambari=INFO
+log4j.logger.org.eclipse.jetty=WARN
+log4j.logger.org.springframework=WARN
+
+# Performance Tuning
+server.connection.max.idle.millis=900000
+server.fqdn.service.url=http://169.254.169.254/latest/meta-data/public-hostname
+server.stages.parallel=true
+
+# Views Configuration
+views.dir=/var/lib/ambari-server/resources/views
+views.validate=false
+
+# Stack Configuration
+resources.dir=/var/lib/ambari-server/resources
+shared.resources.dir=/usr/lib/ambari-server/lib/ambari_commons/resources
+
+# Custom Properties (can be overridden by environment variables)
+custom.action.definitions=/var/lib/ambari-server/resources/custom_action_definitions
+mpacks.staging.path=/var/lib/ambari-server/resources/mpacks
diff --git a/docker/images/ambari/minimal-test.sh b/docker/images/ambari/minimal-test.sh
new file mode 100755
index 00000000000..ed43345ae28
--- /dev/null
+++ b/docker/images/ambari/minimal-test.sh
@@ -0,0 +1,214 @@
+#!/bin/bash
+#
+# Minimal Test Script for Apache Ambari Docker Infrastructure
+# This script tests core infrastructure components that work on ARM64 Macs
+#
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_test() {
+ echo -e "${BLUE}[TEST]${NC} $1"
+}
+
+# Test counter
+TESTS_PASSED=0
+TESTS_FAILED=0
+
+# Function to run test
+run_test() {
+ local test_name="$1"
+ local test_command="$2"
+
+ log_test "Running: $test_name"
+
+ if eval "$test_command" >/dev/null 2>&1; then
+ echo -e " ${GREEN}✓${NC} PASSED: $test_name"
+ TESTS_PASSED=$((TESTS_PASSED + 1))
+ else
+ echo -e " ${RED}✗${NC} FAILED: $test_name"
+ TESTS_FAILED=$((TESTS_FAILED + 1))
+ fi
+}
+
+# Function to check HTTP endpoint
+check_http() {
+ local url="$1"
+ local expected_status="${2:-200}"
+
+ local status=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000")
+
+ if [[ "$status" == "$expected_status" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# Main test function
+main() {
+ log_info "=== Apache Ambari Docker Minimal Infrastructure Test ==="
+ log_info "Testing core infrastructure components (ARM64 compatible)..."
+
+ # Test 1: Check Docker is running
+ run_test "Docker daemon running" "docker info"
+
+ # Test 2: Check Docker Compose is available
+ run_test "Docker Compose available" "docker-compose --version"
+
+ # Test 3: Check if we're in the right directory
+ run_test "In Ambari project directory" "test -f pom.xml && test -d docker"
+
+ # Test 4: Start minimal infrastructure services
+ log_info "Starting minimal infrastructure services..."
+ docker-compose -f docker/docker-compose.minimal.yml up -d
+
+ # Wait for services to start
+ log_info "Waiting for services to start (30 seconds)..."
+ sleep 30
+
+ # Test 5: Check if containers are running
+ run_test "Database container running" "docker-compose -f docker/docker-compose.minimal.yml ps | grep -q 'ambari-database.*Up'"
+ run_test "Zookeeper container running" "docker-compose -f docker/docker-compose.minimal.yml ps | grep -q 'ambari-zookeeper.*Up'"
+ run_test "Grafana container running" "docker-compose -f docker/docker-compose.minimal.yml ps | grep -q 'ambari-grafana-test.*Up'"
+
+ # Test 6: Check HTTP endpoints
+ run_test "Grafana accessible" "check_http 'http://localhost:3002'"
+
+ # Test 7: Check API endpoints
+ run_test "Grafana API responding" "curl -s http://localhost:3002/api/health | grep -q 'database'"
+
+ # Test 8: Check database connectivity
+ run_test "Database accessible" "docker-compose -f docker/docker-compose.minimal.yml exec -T ambari-db pg_isready -U ambari"
+
+ # Test 9: Check Zookeeper
+ run_test "Zookeeper accessible" "echo 'ruok' | nc localhost 2182 | grep -q 'imok'"
+
+ # Test 10: Check database operations
+ run_test "Database operations working" "docker-compose -f docker/docker-compose.minimal.yml exec -T ambari-db psql -U ambari -d ambari -c 'SELECT COUNT(*) FROM users;' | grep -q '1'"
+
+ # Summary
+ log_info "=== Test Results ==="
+ log_info "Tests Passed: ${GREEN}$TESTS_PASSED${NC}"
+ log_info "Tests Failed: ${RED}$TESTS_FAILED${NC}"
+
+ if [[ $TESTS_FAILED -eq 0 ]]; then
+ log_info "${GREEN}🎉 All minimal infrastructure tests passed!${NC}"
+ log_info ""
+ log_info "Core infrastructure is ready. You can now:"
+ log_info "1. Access Grafana: http://localhost:3002 (admin/admin)"
+ log_info "2. Connect to database: docker-compose -f docker/docker-compose.minimal.yml exec ambari-db psql -U ambari -d ambari"
+ log_info "3. Connect to Zookeeper: echo 'ls /' | nc localhost 2182"
+ log_info ""
+ log_info "Database contains:"
+ log_info "- Admin user (admin/admin)"
+ log_info "- Sample development cluster"
+ log_info "- Ambari schema tables"
+ log_info ""
+ log_info "To stop services: docker-compose -f docker/docker-compose.minimal.yml down"
+ return 0
+ else
+ log_error "❌ Some tests failed. Please check the logs and troubleshoot."
+ log_info ""
+ log_info "Troubleshooting steps:"
+ log_info "1. Check container logs: docker-compose -f docker/docker-compose.minimal.yml logs"
+ log_info "2. Check container status: docker-compose -f docker/docker-compose.minimal.yml ps"
+ log_info "3. Restart services: docker-compose -f docker/docker-compose.minimal.yml restart"
+ return 1
+ fi
+}
+
+# Help function
+show_help() {
+ cat << EOF
+Apache Ambari Docker Minimal Infrastructure Test Script
+
+Usage: $0 [OPTIONS]
+
+Options:
+ -h, --help Show this help message
+ -v, --verbose Enable verbose output
+ --stop Stop services after testing
+ --clean Clean up volumes after testing
+
+Examples:
+ $0 # Run minimal infrastructure tests
+ $0 --stop # Run tests and stop services
+ $0 --clean # Run tests and clean up everything
+
+EOF
+}
+
+# Parse command line arguments
+VERBOSE=false
+STOP_SERVICES=false
+CLEAN_UP=false
+
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ show_help
+ exit 0
+ ;;
+ -v|--verbose)
+ VERBOSE=true
+ shift
+ ;;
+ --stop)
+ STOP_SERVICES=true
+ shift
+ ;;
+ --clean)
+ CLEAN_UP=true
+ shift
+ ;;
+ *)
+ log_error "Unknown option: $1"
+ show_help
+ exit 1
+ ;;
+ esac
+done
+
+# Enable verbose mode if requested
+if [[ "$VERBOSE" == "true" ]]; then
+ set -x
+fi
+
+# Run main tests
+main
+exit_code=$?
+
+# Stop services if requested
+if [[ "$STOP_SERVICES" == "true" ]]; then
+ log_info "Stopping Docker services..."
+ docker-compose -f docker/docker-compose.minimal.yml down
+fi
+
+# Clean up if requested
+if [[ "$CLEAN_UP" == "true" ]]; then
+ log_info "Cleaning up volumes and networks..."
+ docker-compose -f docker/docker-compose.minimal.yml down -v
+ docker system prune -f
+fi
+
+exit $exit_code
diff --git a/docker/images/ambari/quick-test.sh b/docker/images/ambari/quick-test.sh
new file mode 100755
index 00000000000..06cfbd85680
--- /dev/null
+++ b/docker/images/ambari/quick-test.sh
@@ -0,0 +1,225 @@
+#!/bin/bash
+#
+# Quick Test Script for Apache Ambari Docker Setup
+# This script performs basic verification of the Ambari Docker environment
+#
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_test() {
+ echo -e "${BLUE}[TEST]${NC} $1"
+}
+
+# Test counter
+TESTS_PASSED=0
+TESTS_FAILED=0
+
+# Function to run test
+run_test() {
+ local test_name="$1"
+ local test_command="$2"
+
+ log_test "Running: $test_name"
+
+ if eval "$test_command" >/dev/null 2>&1; then
+ echo -e " ${GREEN}✓${NC} PASSED: $test_name"
+ TESTS_PASSED=$((TESTS_PASSED + 1))
+ else
+ echo -e " ${RED}✗${NC} FAILED: $test_name"
+ TESTS_FAILED=$((TESTS_FAILED + 1))
+ fi
+}
+
+# Function to check HTTP endpoint
+check_http() {
+ local url="$1"
+ local expected_status="${2:-200}"
+
+ local status=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000")
+
+ if [[ "$status" == "$expected_status" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# Main test function
+main() {
+ log_info "=== Apache Ambari Docker Quick Test ==="
+ log_info "Starting basic verification tests..."
+
+ # Test 1: Check Docker is running
+ run_test "Docker daemon running" "docker info"
+
+ # Test 2: Check Docker Compose is available
+ run_test "Docker Compose available" "docker-compose --version"
+
+ # Test 3: Check if we're in the right directory
+ run_test "In Ambari project directory" "test -f pom.xml && test -d docker"
+
+ # Test 4: Check if images exist
+ run_test "Ambari server image exists" "docker images | grep -q 'apache/ambari-server'"
+ run_test "Ambari agent image exists" "docker images | grep -q 'apache/ambari-agent'"
+ run_test "Ambari metrics image exists" "docker images | grep -q 'apache/ambari-metrics'"
+
+ # Test 5: Check if containers are running
+ run_test "Ambari server container running" "docker-compose -f docker/docker-compose.yml ps | grep -q 'ambari-server.*Up'"
+ run_test "Ambari database container running" "docker-compose -f docker/docker-compose.yml ps | grep -q 'ambari-database.*Up'"
+ run_test "Zookeeper container running" "docker-compose -f docker/docker-compose.yml ps | grep -q 'ambari-zookeeper.*Up'"
+
+ # Test 6: Check HTTP endpoints
+ run_test "Ambari Web UI accessible" "check_http 'http://localhost:8080'"
+ run_test "Grafana accessible" "check_http 'http://localhost:3000'"
+ run_test "NameNode UI accessible" "check_http 'http://localhost:9870'"
+ run_test "ResourceManager UI accessible" "check_http 'http://localhost:8088'"
+
+ # Test 7: Check API endpoints
+ run_test "Ambari API responding" "curl -s -u admin:admin http://localhost:8080/api/v1/version | grep -q 'version'"
+ run_test "Metrics API responding" "curl -s http://localhost:6188/ws/v1/timeline/metrics/metadata | grep -q 'metadata'"
+ run_test "Grafana API responding" "curl -s http://localhost:3000/api/health | grep -q 'database'"
+
+ # Test 8: Check database connectivity
+ run_test "Database accessible" "docker-compose -f docker/docker-compose.yml exec -T ambari-db pg_isready -U ambari"
+
+ # Test 9: Check Zookeeper
+ run_test "Zookeeper accessible" "echo 'ruok' | nc localhost 2181 | grep -q 'imok'"
+
+ # Test 10: Check agent registration
+ run_test "Agent registered" "curl -s -u admin:admin http://localhost:8080/api/v1/hosts | grep -q 'host_name'"
+
+ # Summary
+ log_info "=== Test Results ==="
+ log_info "Tests Passed: ${GREEN}$TESTS_PASSED${NC}"
+ log_info "Tests Failed: ${RED}$TESTS_FAILED${NC}"
+
+ if [[ $TESTS_FAILED -eq 0 ]]; then
+ log_info "${GREEN}🎉 All tests passed! Ambari Docker setup is working correctly.${NC}"
+ log_info ""
+ log_info "Next steps:"
+ log_info "1. Access Ambari Web UI: http://localhost:8080 (admin/admin)"
+ log_info "2. Access Grafana: http://localhost:3000 (admin/admin)"
+ log_info "3. Check Hadoop NameNode: http://localhost:9870"
+ log_info "4. Check YARN ResourceManager: http://localhost:8088"
+ return 0
+ else
+ log_error "❌ Some tests failed. Please check the logs and troubleshoot."
+ log_info ""
+ log_info "Troubleshooting steps:"
+ log_info "1. Check container logs: docker-compose -f docker/docker-compose.yml logs"
+ log_info "2. Check container status: docker-compose -f docker/docker-compose.yml ps"
+ log_info "3. Restart services: docker-compose -f docker/docker-compose.yml restart"
+ log_info "4. See full testing guide: docker/TESTING.md"
+ return 1
+ fi
+}
+
+# Help function
+show_help() {
+ cat << EOF
+Apache Ambari Docker Quick Test Script
+
+Usage: $0 [OPTIONS]
+
+Options:
+ -h, --help Show this help message
+ -v, --verbose Enable verbose output
+ --build Build images before testing
+ --start Start services before testing
+ --stop Stop services after testing
+
+Examples:
+ $0 # Run basic tests
+ $0 --build --start # Build images, start services, then test
+ $0 -v # Run tests with verbose output
+
+EOF
+}
+
+# Parse command line arguments
+VERBOSE=false
+BUILD_IMAGES=false
+START_SERVICES=false
+STOP_SERVICES=false
+
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ show_help
+ exit 0
+ ;;
+ -v|--verbose)
+ VERBOSE=true
+ shift
+ ;;
+ --build)
+ BUILD_IMAGES=true
+ shift
+ ;;
+ --start)
+ START_SERVICES=true
+ shift
+ ;;
+ --stop)
+ STOP_SERVICES=true
+ shift
+ ;;
+ *)
+ log_error "Unknown option: $1"
+ show_help
+ exit 1
+ ;;
+ esac
+done
+
+# Enable verbose mode if requested
+if [[ "$VERBOSE" == "true" ]]; then
+ set -x
+fi
+
+# Build images if requested
+if [[ "$BUILD_IMAGES" == "true" ]]; then
+ log_info "Building Docker images..."
+ ./docker/build.sh all
+fi
+
+# Start services if requested
+if [[ "$START_SERVICES" == "true" ]]; then
+ log_info "Starting Docker services..."
+ docker-compose -f docker/docker-compose.yml up -d
+
+ log_info "Waiting for services to start (60 seconds)..."
+ sleep 60
+fi
+
+# Run main tests
+main
+exit_code=$?
+
+# Stop services if requested
+if [[ "$STOP_SERVICES" == "true" ]]; then
+ log_info "Stopping Docker services..."
+ docker-compose -f docker/docker-compose.yml down
+fi
+
+exit $exit_code
diff --git a/docker/images/ambari/simple-test.sh b/docker/images/ambari/simple-test.sh
new file mode 100755
index 00000000000..ba6e18edf9d
--- /dev/null
+++ b/docker/images/ambari/simple-test.sh
@@ -0,0 +1,217 @@
+#!/bin/bash
+#
+# Simple Test Script for Apache Ambari Docker Infrastructure
+# This script tests the supporting infrastructure without building Ambari from source
+#
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_test() {
+ echo -e "${BLUE}[TEST]${NC} $1"
+}
+
+# Test counter
+TESTS_PASSED=0
+TESTS_FAILED=0
+
+# Function to run test
+run_test() {
+ local test_name="$1"
+ local test_command="$2"
+
+ log_test "Running: $test_name"
+
+ if eval "$test_command" >/dev/null 2>&1; then
+ echo -e " ${GREEN}✓${NC} PASSED: $test_name"
+ TESTS_PASSED=$((TESTS_PASSED + 1))
+ else
+ echo -e " ${RED}✗${NC} FAILED: $test_name"
+ TESTS_FAILED=$((TESTS_FAILED + 1))
+ fi
+}
+
+# Function to check HTTP endpoint
+check_http() {
+ local url="$1"
+ local expected_status="${2:-200}"
+
+ local status=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000")
+
+ if [[ "$status" == "$expected_status" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# Main test function
+main() {
+ log_info "=== Apache Ambari Docker Infrastructure Test ==="
+ log_info "Testing supporting infrastructure components..."
+
+ # Test 1: Check Docker is running
+ run_test "Docker daemon running" "docker info"
+
+ # Test 2: Check Docker Compose is available
+ run_test "Docker Compose available" "docker-compose --version"
+
+ # Test 3: Check if we're in the right directory
+ run_test "In Ambari project directory" "test -f pom.xml && test -d docker"
+
+ # Test 4: Start infrastructure services
+ log_info "Starting infrastructure services..."
+ docker-compose -f docker/docker-compose.simple.yml up -d
+
+ # Wait for services to start
+ log_info "Waiting for services to start (60 seconds)..."
+ sleep 60
+
+ # Test 5: Check if containers are running
+ run_test "Database container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'ambari-database.*Up'"
+ run_test "Zookeeper container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'ambari-zookeeper.*Up'"
+ run_test "NameNode container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'hadoop-namenode.*Up'"
+ run_test "DataNode container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'hadoop-datanode.*Up'"
+ run_test "ResourceManager container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'hadoop-resourcemanager.*Up'"
+ run_test "Grafana container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'ambari-grafana.*Up'"
+
+ # Test 6: Check HTTP endpoints
+ run_test "Grafana accessible" "check_http 'http://localhost:3001'"
+ run_test "NameNode UI accessible" "check_http 'http://localhost:9870'"
+ run_test "DataNode UI accessible" "check_http 'http://localhost:9864'"
+ run_test "ResourceManager UI accessible" "check_http 'http://localhost:8088'"
+
+ # Test 7: Check API endpoints
+ run_test "Grafana API responding" "curl -s http://localhost:3001/api/health | grep -q 'database'"
+
+ # Test 8: Check database connectivity
+ run_test "Database accessible" "docker-compose -f docker/docker-compose.simple.yml exec -T ambari-db pg_isready -U ambari"
+
+ # Test 9: Check Zookeeper
+ run_test "Zookeeper accessible" "echo 'ruok' | nc localhost 2181 | grep -q 'imok'"
+
+ # Test 10: Check HDFS operations
+ run_test "HDFS operations working" "docker-compose -f docker/docker-compose.simple.yml exec namenode hdfs dfs -mkdir -p /test && docker-compose -f docker/docker-compose.simple.yml exec namenode hdfs dfs -ls / | grep -q test"
+
+ # Summary
+ log_info "=== Test Results ==="
+ log_info "Tests Passed: ${GREEN}$TESTS_PASSED${NC}"
+ log_info "Tests Failed: ${RED}$TESTS_FAILED${NC}"
+
+ if [[ $TESTS_FAILED -eq 0 ]]; then
+ log_info "${GREEN}🎉 All infrastructure tests passed!${NC}"
+ log_info ""
+ log_info "Infrastructure is ready. You can now:"
+ log_info "1. Access Grafana: http://localhost:3001 (admin/admin)"
+ log_info "2. Check Hadoop NameNode: http://localhost:9870"
+ log_info "3. Check DataNode: http://localhost:9864"
+ log_info "4. Check YARN ResourceManager: http://localhost:8088"
+ log_info "5. Connect to database: docker-compose -f docker/docker-compose.simple.yml exec ambari-db psql -U ambari -d ambari"
+ log_info ""
+ log_info "To stop services: docker-compose -f docker/docker-compose.simple.yml down"
+ return 0
+ else
+ log_error "❌ Some tests failed. Please check the logs and troubleshoot."
+ log_info ""
+ log_info "Troubleshooting steps:"
+ log_info "1. Check container logs: docker-compose -f docker/docker-compose.simple.yml logs"
+ log_info "2. Check container status: docker-compose -f docker/docker-compose.simple.yml ps"
+ log_info "3. Restart services: docker-compose -f docker/docker-compose.simple.yml restart"
+ return 1
+ fi
+}
+
+# Help function
+show_help() {
+ cat << EOF
+Apache Ambari Docker Infrastructure Test Script
+
+Usage: $0 [OPTIONS]
+
+Options:
+ -h, --help Show this help message
+ -v, --verbose Enable verbose output
+ --stop Stop services after testing
+ --clean Clean up volumes after testing
+
+Examples:
+ $0 # Run infrastructure tests
+ $0 --stop # Run tests and stop services
+ $0 --clean # Run tests and clean up everything
+
+EOF
+}
+
+# Parse command line arguments
+VERBOSE=false
+STOP_SERVICES=false
+CLEAN_UP=false
+
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ show_help
+ exit 0
+ ;;
+ -v|--verbose)
+ VERBOSE=true
+ shift
+ ;;
+ --stop)
+ STOP_SERVICES=true
+ shift
+ ;;
+ --clean)
+ CLEAN_UP=true
+ shift
+ ;;
+ *)
+ log_error "Unknown option: $1"
+ show_help
+ exit 1
+ ;;
+ esac
+done
+
+# Enable verbose mode if requested
+if [[ "$VERBOSE" == "true" ]]; then
+ set -x
+fi
+
+# Run main tests
+main
+exit_code=$?
+
+# Stop services if requested
+if [[ "$STOP_SERVICES" == "true" ]]; then
+ log_info "Stopping Docker services..."
+ docker-compose -f docker/docker-compose.simple.yml down
+fi
+
+# Clean up if requested
+if [[ "$CLEAN_UP" == "true" ]]; then
+ log_info "Cleaning up volumes and networks..."
+ docker-compose -f docker/docker-compose.simple.yml down -v
+ docker system prune -f
+fi
+
+exit $exit_code
diff --git a/docker/scripts/entrypoint.sh b/docker/scripts/entrypoint.sh
new file mode 100644
index 00000000000..f1558703625
--- /dev/null
+++ b/docker/scripts/entrypoint.sh
@@ -0,0 +1,256 @@
+#!/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.
+#
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Logging functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+log_debug() {
+ if [[ "${AMBARI_DEBUG:-false}" == "true" ]]; then
+ echo -e "${BLUE}[DEBUG]${NC} $1"
+ fi
+}
+
+# Default environment variables
+export AMBARI_USER=${AMBARI_USER:-ambari}
+export AMBARI_HOME=${AMBARI_HOME:-/opt/ambari}
+export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-amd64}
+export MAVEN_HOME=${MAVEN_HOME:-/opt/maven}
+export PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${PATH}
+
+# Database configuration
+export AMBARI_DB_HOST=${AMBARI_DB_HOST:-ambari-db}
+export AMBARI_DB_PORT=${AMBARI_DB_PORT:-5432}
+export AMBARI_DB_NAME=${AMBARI_DB_NAME:-ambari}
+export AMBARI_DB_USER=${AMBARI_DB_USER:-ambari}
+export AMBARI_DB_PASSWORD=${AMBARI_DB_PASSWORD:-bigdata}
+
+# Server configuration
+export AMBARI_SERVER_HOST=${AMBARI_SERVER_HOST:-localhost}
+export AMBARI_SERVER_PORT=${AMBARI_SERVER_PORT:-8080}
+export AMBARI_SERVER_HTTPS=${AMBARI_SERVER_HTTPS:-false}
+
+# Agent configuration
+export AGENT_HOSTNAME=${AGENT_HOSTNAME:-$(hostname -f)}
+
+# Metrics configuration
+export AMS_HBASE_ROOTDIR=${AMS_HBASE_ROOTDIR:-/var/lib/ambari-metrics-collector/hbase}
+export AMS_COLLECTOR_PORT=${AMS_COLLECTOR_PORT:-6188}
+export AMS_GRAFANA_ENABLED=${AMS_GRAFANA_ENABLED:-true}
+
+# JVM configuration
+export JAVA_OPTS=${JAVA_OPTS:-"-Xmx2g -Xms1g -XX:+UseG1GC"}
+export AMS_JAVA_OPTS=${AMS_JAVA_OPTS:-"-Xmx1g -Xms512m"}
+
+# Debug configuration
+if [[ "${AMBARI_DEBUG:-false}" == "true" ]]; then
+ export JAVA_OPTS="${JAVA_OPTS} -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
+ log_info "Debug mode enabled. Java debug port: 5005"
+fi
+
+# Function to wait for service
+wait_for_service() {
+ local host=$1
+ local port=$2
+ local service_name=$3
+ local timeout=${4:-60}
+
+ log_info "Waiting for ${service_name} at ${host}:${port}..."
+
+ local count=0
+ while ! nc -z "${host}" "${port}" >/dev/null 2>&1; do
+ if [ ${count} -ge ${timeout} ]; then
+ log_error "Timeout waiting for ${service_name} at ${host}:${port}"
+ return 1
+ fi
+ count=$((count + 1))
+ sleep 1
+ done
+
+ log_info "${service_name} is available at ${host}:${port}"
+ return 0
+}
+
+# Function to wait for database
+wait_for_database() {
+ if [[ "${AMBARI_DB_HOST}" != "localhost" && "${AMBARI_DB_HOST}" != "127.0.0.1" ]]; then
+ wait_for_service "${AMBARI_DB_HOST}" "${AMBARI_DB_PORT}" "Database" 120
+ fi
+}
+
+# Function to setup directories and permissions
+setup_directories() {
+ log_info "Setting up directories and permissions..."
+
+ # Ensure directories exist and have correct permissions
+ local dirs=(
+ "/var/log/ambari-server"
+ "/var/log/ambari-agent"
+ "/var/log/ambari-metrics-collector"
+ "/var/log/ambari-metrics-monitor"
+ "/var/run/ambari-server"
+ "/var/run/ambari-agent"
+ "/var/run/ambari-metrics-collector"
+ "/var/run/ambari-metrics-monitor"
+ "/var/lib/ambari-server"
+ "/var/lib/ambari-agent"
+ "/var/lib/ambari-metrics-collector"
+ "/etc/ambari-server/conf"
+ "/etc/ambari-agent/conf"
+ "/etc/ambari-metrics-collector/conf"
+ "/etc/ambari-metrics-monitor/conf"
+ )
+
+ for dir in "${dirs[@]}"; do
+ if [[ ! -d "${dir}" ]]; then
+ sudo mkdir -p "${dir}"
+ fi
+ sudo chown -R ${AMBARI_USER}:${AMBARI_USER} "${dir}"
+ done
+}
+
+# Function to setup SSH
+setup_ssh() {
+ log_info "Setting up SSH configuration..."
+
+ # Start SSH daemon if not running
+ if ! pgrep -x "sshd" > /dev/null; then
+ sudo service ssh start || sudo /usr/sbin/sshd
+ fi
+
+ # Ensure SSH keys are properly configured
+ if [[ ! -f "/home/${AMBARI_USER}/.ssh/id_rsa" ]]; then
+ ssh-keygen -t rsa -N '' -f "/home/${AMBARI_USER}/.ssh/id_rsa"
+ cat "/home/${AMBARI_USER}/.ssh/id_rsa.pub" >> "/home/${AMBARI_USER}/.ssh/authorized_keys"
+ chmod 600 "/home/${AMBARI_USER}/.ssh/authorized_keys"
+ chmod 700 "/home/${AMBARI_USER}/.ssh"
+ fi
+}
+
+# Function to setup time synchronization
+setup_time_sync() {
+ log_info "Setting up time synchronization..."
+
+ # Start NTP service if available
+ if command -v ntpd >/dev/null 2>&1; then
+ sudo service ntp start || true
+ fi
+
+ # Sync time once
+ sudo ntpdate -s time.nist.gov || true
+}
+
+# Function to display environment info
+display_environment_info() {
+ log_info "=== Ambari Docker Environment ==="
+ log_info "Java Version: $(java -version 2>&1 | head -n 1)"
+ log_info "Maven Version: $(mvn -version 2>&1 | head -n 1)"
+ log_info "Node.js Version: $(node --version 2>/dev/null || echo 'Not installed')"
+ log_info "Python Version: $(python3 --version)"
+ log_info "User: $(whoami)"
+ log_info "Working Directory: $(pwd)"
+ log_info "JAVA_HOME: ${JAVA_HOME}"
+ log_info "MAVEN_HOME: ${MAVEN_HOME}"
+ log_info "================================="
+}
+
+# Function to handle signals
+cleanup() {
+ log_info "Received shutdown signal, cleaning up..."
+
+ # Stop any running Ambari services
+ if pgrep -f "ambari-server" > /dev/null; then
+ log_info "Stopping Ambari Server..."
+ sudo ambari-server stop || true
+ fi
+
+ if pgrep -f "ambari-agent" > /dev/null; then
+ log_info "Stopping Ambari Agent..."
+ sudo ambari-agent stop || true
+ fi
+
+ if pgrep -f "ambari-metrics-collector" > /dev/null; then
+ log_info "Stopping Ambari Metrics Collector..."
+ sudo ambari-metrics-collector stop || true
+ fi
+
+ if pgrep -f "ambari-metrics-monitor" > /dev/null; then
+ log_info "Stopping Ambari Metrics Monitor..."
+ sudo ambari-metrics-monitor stop || true
+ fi
+
+ log_info "Cleanup completed"
+ exit 0
+}
+
+# Set up signal handlers
+trap cleanup SIGTERM SIGINT SIGQUIT
+
+# Main initialization
+main() {
+ log_info "Starting Ambari Docker container initialization..."
+
+ # Display environment information
+ display_environment_info
+
+ # Setup basic requirements
+ setup_directories
+ setup_ssh
+ setup_time_sync
+
+ # Wait for dependencies if needed
+ if [[ "${1}" == "ambari-server" || "${1}" == "server" ]]; then
+ wait_for_database
+ elif [[ "${1}" == "ambari-agent" || "${1}" == "agent" ]]; then
+ wait_for_service "${AMBARI_SERVER_HOST}" "${AMBARI_SERVER_PORT}" "Ambari Server" 300
+ fi
+
+ log_info "Container initialization completed successfully"
+
+ # Execute the command
+ if [[ $# -eq 0 ]]; then
+ log_info "No command specified, starting interactive shell"
+ exec /bin/bash
+ else
+ log_info "Executing command: $*"
+ exec "$@"
+ fi
+}
+
+# Run main function
+main "$@"
diff --git a/docker/scripts/health-check.sh b/docker/scripts/health-check.sh
new file mode 100644
index 00000000000..9d2a1d40fca
--- /dev/null
+++ b/docker/scripts/health-check.sh
@@ -0,0 +1,329 @@
+#!/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.
+#
+
+# Health check script for Ambari Docker containers
+# This script determines the container type and performs appropriate health checks
+
+set -e
+
+# Configuration
+AMBARI_SERVER_PORT=${AMBARI_SERVER_PORT:-8080}
+AMBARI_SERVER_SSL_PORT=${AMBARI_SERVER_SSL_PORT:-8441}
+AMS_COLLECTOR_PORT=${AMS_COLLECTOR_PORT:-6188}
+GRAFANA_PORT=${GRAFANA_PORT:-3000}
+
+# Timeout for HTTP requests (seconds)
+HTTP_TIMEOUT=10
+
+# Function to check HTTP endpoint
+check_http() {
+ local url=$1
+ local expected_status=${2:-200}
+ local timeout=${3:-$HTTP_TIMEOUT}
+
+ local response
+ response=$(curl -s -o /dev/null -w "%{http_code}" --max-time "$timeout" "$url" 2>/dev/null || echo "000")
+
+ if [[ "$response" == "$expected_status" ]]; then
+ return 0
+ else
+ echo "HTTP check failed for $url (got $response, expected $expected_status)"
+ return 1
+ fi
+}
+
+# Function to check if process is running
+check_process() {
+ local process_name=$1
+ if pgrep -f "$process_name" > /dev/null; then
+ return 0
+ else
+ echo "Process check failed: $process_name not running"
+ return 1
+ fi
+}
+
+# Function to check if port is listening
+check_port() {
+ local port=$1
+ local host=${2:-localhost}
+
+ if nc -z "$host" "$port" 2>/dev/null; then
+ return 0
+ else
+ echo "Port check failed: $host:$port not accessible"
+ return 1
+ fi
+}
+
+# Function to check file exists and is readable
+check_file() {
+ local file_path=$1
+ if [[ -r "$file_path" ]]; then
+ return 0
+ else
+ echo "File check failed: $file_path not readable"
+ return 1
+ fi
+}
+
+# Function to check Ambari Server health
+check_ambari_server() {
+ echo "Checking Ambari Server health..."
+
+ # Check if server process is running
+ if ! check_process "ambari-server"; then
+ return 1
+ fi
+
+ # Check if server port is listening
+ if ! check_port "$AMBARI_SERVER_PORT"; then
+ return 1
+ fi
+
+ # Check server API endpoint
+ local server_url="http://localhost:$AMBARI_SERVER_PORT/api/v1/clusters"
+ if ! check_http "$server_url" "200"; then
+ # Try with authentication (default admin:admin)
+ server_url="http://admin:admin@localhost:$AMBARI_SERVER_PORT/api/v1/clusters"
+ if ! check_http "$server_url" "200"; then
+ return 1
+ fi
+ fi
+
+ # Check server log file exists
+ if ! check_file "/var/log/ambari-server/ambari-server.log"; then
+ return 1
+ fi
+
+ echo "Ambari Server health check passed"
+ return 0
+}
+
+# Function to check Ambari Agent health
+check_ambari_agent() {
+ echo "Checking Ambari Agent health..."
+
+ # Check if agent process is running
+ if ! check_process "ambari-agent"; then
+ return 1
+ fi
+
+ # Check agent log file exists
+ if ! check_file "/var/log/ambari-agent/ambari-agent.log"; then
+ return 1
+ fi
+
+ # Check if agent can communicate with server (if server host is set)
+ if [[ -n "${AMBARI_SERVER_HOST:-}" && "${AMBARI_SERVER_HOST}" != "localhost" ]]; then
+ if ! check_port "$AMBARI_SERVER_PORT" "$AMBARI_SERVER_HOST"; then
+ echo "Warning: Cannot reach Ambari Server at $AMBARI_SERVER_HOST:$AMBARI_SERVER_PORT"
+ # Don't fail health check for this, as server might be starting
+ fi
+ fi
+
+ echo "Ambari Agent health check passed"
+ return 0
+}
+
+# Function to check Ambari Metrics Collector health
+check_ambari_metrics() {
+ echo "Checking Ambari Metrics Collector health..."
+
+ # Check if metrics collector process is running
+ if ! check_process "ambari-metrics-collector"; then
+ return 1
+ fi
+
+ # Check if collector port is listening
+ if ! check_port "$AMS_COLLECTOR_PORT"; then
+ return 1
+ fi
+
+ # Check metrics API endpoint
+ local metrics_url="http://localhost:$AMS_COLLECTOR_PORT/ws/v1/timeline/metrics/metadata"
+ if ! check_http "$metrics_url" "200"; then
+ return 1
+ fi
+
+ # Check HBase master process (embedded in metrics collector)
+ if ! check_process "HMaster"; then
+ echo "Warning: HBase Master process not found"
+ # Don't fail for this as it might be starting
+ fi
+
+ # Check collector log file exists
+ if ! check_file "/var/log/ambari-metrics-collector/ambari-metrics-collector.log"; then
+ return 1
+ fi
+
+ echo "Ambari Metrics Collector health check passed"
+ return 0
+}
+
+# Function to check Grafana health
+check_grafana() {
+ echo "Checking Grafana health..."
+
+ # Check if Grafana process is running
+ if ! check_process "grafana-server"; then
+ return 1
+ fi
+
+ # Check if Grafana port is listening
+ if ! check_port "$GRAFANA_PORT"; then
+ return 1
+ fi
+
+ # Check Grafana API endpoint
+ local grafana_url="http://localhost:$GRAFANA_PORT/api/health"
+ if ! check_http "$grafana_url" "200"; then
+ return 1
+ fi
+
+ echo "Grafana health check passed"
+ return 0
+}
+
+# Function to check database connectivity
+check_database() {
+ echo "Checking database connectivity..."
+
+ local db_host=${AMBARI_DB_HOST:-localhost}
+ local db_port=${AMBARI_DB_PORT:-5432}
+ local db_name=${AMBARI_DB_NAME:-ambari}
+ local db_user=${AMBARI_DB_USER:-ambari}
+
+ # Check if database port is accessible
+ if ! check_port "$db_port" "$db_host"; then
+ return 1
+ fi
+
+ # Try to connect to database (if PostgreSQL client is available)
+ if command -v psql >/dev/null 2>&1; then
+ if ! PGPASSWORD="${AMBARI_DB_PASSWORD}" psql -h "$db_host" -p "$db_port" -U "$db_user" -d "$db_name" -c "SELECT 1;" >/dev/null 2>&1; then
+ echo "Database connection test failed"
+ return 1
+ fi
+ fi
+
+ echo "Database connectivity check passed"
+ return 0
+}
+
+# Function to perform basic system health checks
+check_system() {
+ echo "Checking system health..."
+
+ # Check disk space (warn if less than 1GB free)
+ local free_space
+ free_space=$(df / | awk 'NR==2 {print $4}')
+ if [[ "$free_space" -lt 1048576 ]]; then # 1GB in KB
+ echo "Warning: Low disk space ($(($free_space / 1024))MB free)"
+ fi
+
+ # Check memory usage (warn if less than 512MB free)
+ local free_memory
+ free_memory=$(free | awk 'NR==2{printf "%.0f", $7/1024}')
+ if [[ "$free_memory" -lt 512 ]]; then
+ echo "Warning: Low memory (${free_memory}MB free)"
+ fi
+
+ # Check if Java is available
+ if ! command -v java >/dev/null 2>&1; then
+ echo "Java not found in PATH"
+ return 1
+ fi
+
+ echo "System health check passed"
+ return 0
+}
+
+# Main health check function
+main() {
+ local exit_code=0
+
+ echo "=== Ambari Docker Health Check ==="
+ echo "Timestamp: $(date)"
+ echo "Hostname: $(hostname)"
+ echo "Container ID: $(hostname)"
+
+ # Always check system health
+ if ! check_system; then
+ exit_code=1
+ fi
+
+ # Determine container type and run appropriate checks
+ # Check based on running processes and environment variables
+
+ if pgrep -f "ambari-server" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "server" ]]; then
+ if ! check_ambari_server; then
+ exit_code=1
+ fi
+
+ # If this is a server container, also check database
+ if ! check_database; then
+ exit_code=1
+ fi
+ fi
+
+ if pgrep -f "ambari-agent" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "agent" ]]; then
+ if ! check_ambari_agent; then
+ exit_code=1
+ fi
+ fi
+
+ if pgrep -f "ambari-metrics-collector" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "metrics" ]]; then
+ if ! check_ambari_metrics; then
+ exit_code=1
+ fi
+ fi
+
+ if pgrep -f "grafana-server" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "grafana" ]]; then
+ if ! check_grafana; then
+ exit_code=1
+ fi
+ fi
+
+ # If no specific component is detected, this might be a base container
+ if ! pgrep -f "ambari-" > /dev/null && ! pgrep -f "grafana-server" > /dev/null; then
+ echo "No Ambari services detected - assuming base container"
+ # For base containers, just check that basic tools are available
+ if ! command -v java >/dev/null 2>&1 || ! command -v mvn >/dev/null 2>&1; then
+ echo "Basic tools (Java/Maven) not available"
+ exit_code=1
+ else
+ echo "Base container health check passed"
+ fi
+ fi
+
+ echo "=== Health Check Complete ==="
+
+ if [[ $exit_code -eq 0 ]]; then
+ echo "Status: HEALTHY"
+ else
+ echo "Status: UNHEALTHY"
+ fi
+
+ exit $exit_code
+}
+
+# Run main function
+main "$@"
diff --git a/docker/scripts/init-db.sql b/docker/scripts/init-db.sql
new file mode 100644
index 00000000000..13ca74df1f7
--- /dev/null
+++ b/docker/scripts/init-db.sql
@@ -0,0 +1,401 @@
+--
+-- 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.
+--
+
+-- Apache Ambari Database Initialization Script for PostgreSQL
+-- This script initializes the Ambari database with required schemas and data
+
+\echo 'Initializing Ambari database...'
+
+-- Set client encoding
+SET client_encoding = 'UTF8';
+
+-- Create additional databases if needed
+-- CREATE DATABASE ambari_metrics OWNER ambari;
+
+-- Connect to ambari database
+\c ambari;
+
+-- Set search path
+SET search_path = public;
+
+-- Create extensions if available
+CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
+CREATE EXTENSION IF NOT EXISTS "pgcrypto";
+
+-- Create basic tables for Ambari (simplified schema for Docker setup)
+-- Note: The full schema will be created by Ambari Server setup process
+
+-- Users table
+CREATE TABLE IF NOT EXISTS users (
+ user_id SERIAL PRIMARY KEY,
+ user_name VARCHAR(255) NOT NULL UNIQUE,
+ user_password VARCHAR(255),
+ user_type VARCHAR(255) NOT NULL DEFAULT 'LOCAL',
+ ldap_user BOOLEAN NOT NULL DEFAULT FALSE,
+ user_active BOOLEAN NOT NULL DEFAULT TRUE,
+ admin BOOLEAN NOT NULL DEFAULT FALSE,
+ created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ modified_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- Insert default admin user (password: admin)
+INSERT INTO users (user_name, user_password, user_type, ldap_user, user_active, admin)
+VALUES ('admin', 'c7063d9d94f7ac7d8c6e6d3b429c7c8d', 'LOCAL', FALSE, TRUE, TRUE)
+ON CONFLICT (user_name) DO NOTHING;
+
+-- Clusters table
+CREATE TABLE IF NOT EXISTS clusters (
+ cluster_id BIGSERIAL PRIMARY KEY,
+ cluster_name VARCHAR(255) NOT NULL UNIQUE,
+ cluster_info VARCHAR(255) NOT NULL DEFAULT 'Ambari',
+ desired_cluster_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
+ desired_stack_version VARCHAR(255) NOT NULL DEFAULT '{"stackName":"HDP","stackVersion":"2.6"}',
+ cluster_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
+ provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
+ security_type VARCHAR(255) NOT NULL DEFAULT 'NONE',
+ version VARCHAR(255) NOT NULL DEFAULT '1.0.0'
+);
+
+-- Hosts table
+CREATE TABLE IF NOT EXISTS hosts (
+ host_id BIGSERIAL PRIMARY KEY,
+ host_name VARCHAR(255) NOT NULL UNIQUE,
+ cpu_count INTEGER NOT NULL DEFAULT 1,
+ cpu_info VARCHAR(255) NOT NULL DEFAULT 'Unknown',
+ discovery_status VARCHAR(2000) NOT NULL DEFAULT 'PENDING',
+ host_attributes TEXT,
+ ipv4 VARCHAR(255),
+ ipv6 VARCHAR(255),
+ last_registration_time BIGINT,
+ os_arch VARCHAR(255) NOT NULL DEFAULT 'x86_64',
+ os_info VARCHAR(1000) NOT NULL DEFAULT 'Unknown',
+ os_type VARCHAR(255) NOT NULL DEFAULT 'Unknown',
+ ph_cpu_count INTEGER,
+ public_host_name VARCHAR(255),
+ rack_info VARCHAR(255) NOT NULL DEFAULT '/default-rack',
+ total_mem BIGINT NOT NULL DEFAULT 0
+);
+
+-- Services table
+CREATE TABLE IF NOT EXISTS clusterservices (
+ service_name VARCHAR(255) NOT NULL,
+ cluster_id BIGINT NOT NULL,
+ service_enabled INTEGER NOT NULL DEFAULT 1,
+ PRIMARY KEY (service_name, cluster_id),
+ FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id)
+);
+
+-- Components table
+CREATE TABLE IF NOT EXISTS servicecomponentdesiredstate (
+ component_name VARCHAR(255) NOT NULL,
+ cluster_id BIGINT NOT NULL,
+ service_name VARCHAR(255) NOT NULL,
+ desired_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
+ desired_stack_version VARCHAR(255) NOT NULL,
+ PRIMARY KEY (component_name, cluster_id, service_name),
+ FOREIGN KEY (cluster_id, service_name) REFERENCES clusterservices(cluster_id, service_name)
+);
+
+-- Host components table
+CREATE TABLE IF NOT EXISTS hostcomponentdesiredstate (
+ cluster_id BIGINT NOT NULL,
+ component_name VARCHAR(255) NOT NULL,
+ host_id BIGINT NOT NULL,
+ service_name VARCHAR(255) NOT NULL,
+ desired_state VARCHAR(255) NOT NULL DEFAULT 'INIT',
+ desired_stack_version VARCHAR(255) NOT NULL,
+ admin_state VARCHAR(255),
+ maintenance_state VARCHAR(255) NOT NULL DEFAULT 'OFF',
+ restart_required BOOLEAN NOT NULL DEFAULT FALSE,
+ PRIMARY KEY (cluster_id, component_name, host_id, service_name),
+ FOREIGN KEY (host_id) REFERENCES hosts(host_id),
+ FOREIGN KEY (cluster_id, service_name) REFERENCES clusterservices(cluster_id, service_name)
+);
+
+-- Configuration tables
+CREATE TABLE IF NOT EXISTS clusterconfig (
+ config_id BIGSERIAL PRIMARY KEY,
+ version_tag VARCHAR(255) NOT NULL,
+ version BIGINT NOT NULL,
+ type_name VARCHAR(255) NOT NULL,
+ cluster_id BIGINT NOT NULL,
+ config_data TEXT NOT NULL,
+ config_attributes TEXT,
+ create_timestamp BIGINT NOT NULL,
+ selected SMALLINT NOT NULL DEFAULT 0,
+ selected_timestamp BIGINT NOT NULL DEFAULT 0,
+ unmapped SMALLINT NOT NULL DEFAULT 0,
+ FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id),
+ UNIQUE (cluster_id, type_name, version_tag)
+);
+
+-- Permissions and privileges tables
+CREATE TABLE IF NOT EXISTS adminprincipal (
+ principal_id BIGSERIAL PRIMARY KEY,
+ principal_type_id INTEGER NOT NULL DEFAULT 1
+);
+
+CREATE TABLE IF NOT EXISTS adminprincipaltype (
+ principal_type_id SERIAL PRIMARY KEY,
+ principal_type_name VARCHAR(255) NOT NULL UNIQUE
+);
+
+-- Insert default principal types
+INSERT INTO adminprincipaltype (principal_type_name) VALUES ('USER') ON CONFLICT DO NOTHING;
+INSERT INTO adminprincipaltype (principal_type_name) VALUES ('GROUP') ON CONFLICT DO NOTHING;
+INSERT INTO adminprincipaltype (principal_type_name) VALUES ('ROLE') ON CONFLICT DO NOTHING;
+
+-- Create principal for admin user
+INSERT INTO adminprincipal (principal_type_id)
+SELECT principal_type_id FROM adminprincipaltype WHERE principal_type_name = 'USER'
+ON CONFLICT DO NOTHING;
+
+-- Repositories table
+CREATE TABLE IF NOT EXISTS repo_version (
+ repo_version_id BIGSERIAL PRIMARY KEY,
+ stack_id BIGINT NOT NULL,
+ version VARCHAR(255) NOT NULL,
+ display_name VARCHAR(128) NOT NULL,
+ repo_type VARCHAR(255) NOT NULL DEFAULT 'STANDARD',
+ version_url VARCHAR(1024),
+ version_xml TEXT,
+ version_xsd VARCHAR(512),
+ parent_id BIGINT,
+ hidden SMALLINT NOT NULL DEFAULT 0,
+ resolved SMALLINT NOT NULL DEFAULT 0,
+ legacy SMALLINT NOT NULL DEFAULT 1,
+ UNIQUE (stack_id, version)
+);
+
+-- Stacks table
+CREATE TABLE IF NOT EXISTS stack (
+ stack_id BIGSERIAL PRIMARY KEY,
+ stack_name VARCHAR(255) NOT NULL,
+ stack_version VARCHAR(255) NOT NULL,
+ UNIQUE (stack_name, stack_version)
+);
+
+-- Insert default stack
+INSERT INTO stack (stack_name, stack_version) VALUES ('HDP', '2.6') ON CONFLICT DO NOTHING;
+
+-- Metrics tables (simplified)
+CREATE TABLE IF NOT EXISTS metricaggregate (
+ metric_name VARCHAR(255) NOT NULL,
+ app_id VARCHAR(255) NOT NULL,
+ instance_id VARCHAR(255),
+ start_time BIGINT NOT NULL,
+ units VARCHAR(255),
+ metric_sum DOUBLE PRECISION,
+ metric_count INTEGER,
+ metric_max DOUBLE PRECISION,
+ metric_min DOUBLE PRECISION,
+ PRIMARY KEY (metric_name, app_id, instance_id, start_time)
+);
+
+-- Views tables
+CREATE TABLE IF NOT EXISTS viewmain (
+ view_name VARCHAR(255) NOT NULL,
+ label VARCHAR(255),
+ description VARCHAR(2048),
+ version VARCHAR(255),
+ build VARCHAR(128),
+ resource_type_id INTEGER,
+ icon VARCHAR(255),
+ icon64 VARCHAR(255),
+ archive VARCHAR(255),
+ mask VARCHAR(255),
+ system_view SMALLINT NOT NULL DEFAULT 0,
+ PRIMARY KEY (view_name)
+);
+
+-- Alerts tables (simplified)
+CREATE TABLE IF NOT EXISTS alert_definition (
+ definition_id BIGSERIAL PRIMARY KEY,
+ cluster_id BIGINT NOT NULL,
+ definition_name VARCHAR(255) NOT NULL,
+ service_name VARCHAR(255) NOT NULL,
+ component_name VARCHAR(255),
+ scope VARCHAR(255) DEFAULT 'ANY',
+ label VARCHAR(255),
+ description TEXT,
+ enabled SMALLINT NOT NULL DEFAULT 1,
+ schedule_interval INTEGER NOT NULL,
+ source_type VARCHAR(255) NOT NULL,
+ alert_source TEXT NOT NULL,
+ hash VARCHAR(64) NOT NULL,
+ ignore_host SMALLINT NOT NULL DEFAULT 0,
+ help_url VARCHAR(512),
+ repeat_tolerance INTEGER NOT NULL DEFAULT 1,
+ repeat_tolerance_enabled SMALLINT NOT NULL DEFAULT 0,
+ FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id),
+ UNIQUE (cluster_id, definition_name)
+);
+
+-- Topology tables
+CREATE TABLE IF NOT EXISTS topology_request (
+ id BIGSERIAL PRIMARY KEY,
+ action VARCHAR(255) NOT NULL,
+ cluster_id BIGINT NOT NULL,
+ bp_name VARCHAR(100) NOT NULL,
+ cluster_properties TEXT,
+ cluster_attributes TEXT,
+ description VARCHAR(1024),
+ provision_action VARCHAR(255),
+ FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id)
+);
+
+-- Upgrade tables
+CREATE TABLE IF NOT EXISTS upgrade (
+ upgrade_id BIGSERIAL PRIMARY KEY,
+ cluster_id BIGINT NOT NULL,
+ request_id BIGINT NOT NULL,
+ from_version VARCHAR(255) NOT NULL DEFAULT '',
+ to_version VARCHAR(255) NOT NULL DEFAULT '',
+ direction VARCHAR(255) NOT NULL DEFAULT 'UPGRADE',
+ upgrade_package VARCHAR(255) NOT NULL,
+ upgrade_type VARCHAR(32) NOT NULL,
+ repo_version_id BIGINT NOT NULL,
+ skip_failures SMALLINT NOT NULL DEFAULT 0,
+ skip_service_check_failures SMALLINT NOT NULL DEFAULT 0,
+ downgrade_allowed SMALLINT NOT NULL DEFAULT 1,
+ suspended SMALLINT NOT NULL DEFAULT 0,
+ FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id),
+ FOREIGN KEY (repo_version_id) REFERENCES repo_version(repo_version_id)
+);
+
+-- Create indexes for better performance
+CREATE INDEX IF NOT EXISTS idx_users_user_name ON users(user_name);
+CREATE INDEX IF NOT EXISTS idx_users_user_type ON users(user_type);
+CREATE INDEX IF NOT EXISTS idx_clusters_cluster_name ON clusters(cluster_name);
+CREATE INDEX IF NOT EXISTS idx_hosts_host_name ON hosts(host_name);
+CREATE INDEX IF NOT EXISTS idx_clusterservices_cluster_id ON clusterservices(cluster_id);
+CREATE INDEX IF NOT EXISTS idx_clusterconfig_cluster_id ON clusterconfig(cluster_id);
+CREATE INDEX IF NOT EXISTS idx_clusterconfig_type_name ON clusterconfig(type_name);
+
+-- Grant permissions
+GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ambari;
+GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ambari;
+GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO ambari;
+
+-- Create a function to update modified timestamps
+CREATE OR REPLACE FUNCTION update_modified_column()
+RETURNS TRIGGER AS $$
+BEGIN
+ NEW.modified_date = CURRENT_TIMESTAMP;
+ RETURN NEW;
+END;
+$$ language 'plpgsql';
+
+-- Create triggers for timestamp updates
+DROP TRIGGER IF EXISTS update_users_modtime ON users;
+CREATE TRIGGER update_users_modtime
+ BEFORE UPDATE ON users
+ FOR EACH ROW EXECUTE FUNCTION update_modified_column();
+
+-- Insert some sample data for development
+DO $$
+BEGIN
+ -- Insert sample cluster if not exists
+ IF NOT EXISTS (SELECT 1 FROM clusters WHERE cluster_name = 'development') THEN
+ INSERT INTO clusters (cluster_name, cluster_info, desired_stack_version)
+ VALUES ('development', 'Development Cluster', '{"stackName":"HDP","stackVersion":"2.6"}');
+ END IF;
+
+ -- Insert localhost as a host if not exists
+ IF NOT EXISTS (SELECT 1 FROM hosts WHERE host_name = 'localhost') THEN
+ INSERT INTO hosts (host_name, cpu_count, cpu_info, os_arch, os_type, total_mem, rack_info)
+ VALUES ('localhost', 4, 'Intel Core i7', 'x86_64', 'centos7', 8589934592, '/default-rack');
+ END IF;
+END $$;
+
+-- Create a view for easy cluster monitoring
+CREATE OR REPLACE VIEW cluster_summary AS
+SELECT
+ c.cluster_id,
+ c.cluster_name,
+ c.cluster_state,
+ c.desired_cluster_state,
+ c.security_type,
+ COUNT(DISTINCT h.host_id) as host_count,
+ COUNT(DISTINCT cs.service_name) as service_count
+FROM clusters c
+LEFT JOIN hosts h ON TRUE -- All hosts for now, should join through cluster_host_mapping
+LEFT JOIN clusterservices cs ON c.cluster_id = cs.cluster_id
+GROUP BY c.cluster_id, c.cluster_name, c.cluster_state, c.desired_cluster_state, c.security_type;
+
+-- Create a function to get cluster health
+CREATE OR REPLACE FUNCTION get_cluster_health(cluster_name_param VARCHAR)
+RETURNS TABLE (
+ cluster_name VARCHAR,
+ total_hosts BIGINT,
+ total_services BIGINT,
+ cluster_state VARCHAR,
+ last_updated TIMESTAMP
+) AS $$
+BEGIN
+ RETURN QUERY
+ SELECT
+ c.cluster_name,
+ COUNT(DISTINCT h.host_id) as total_hosts,
+ COUNT(DISTINCT cs.service_name) as total_services,
+ c.cluster_state,
+ CURRENT_TIMESTAMP as last_updated
+ FROM clusters c
+ LEFT JOIN hosts h ON TRUE
+ LEFT JOIN clusterservices cs ON c.cluster_id = cs.cluster_id
+ WHERE c.cluster_name = cluster_name_param
+ GROUP BY c.cluster_name, c.cluster_state;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Set up database maintenance
+-- Create a function to clean old metrics data
+CREATE OR REPLACE FUNCTION cleanup_old_metrics(days_to_keep INTEGER DEFAULT 30)
+RETURNS INTEGER AS $$
+DECLARE
+ deleted_count INTEGER;
+ cutoff_time BIGINT;
+BEGIN
+ -- Calculate cutoff time (current time - days_to_keep in milliseconds)
+ cutoff_time := EXTRACT(EPOCH FROM CURRENT_TIMESTAMP - INTERVAL '1 day' * days_to_keep) * 1000;
+
+ -- Delete old metrics
+ DELETE FROM metricaggregate WHERE start_time < cutoff_time;
+ GET DIAGNOSTICS deleted_count = ROW_COUNT;
+
+ RETURN deleted_count;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Create database statistics view
+CREATE OR REPLACE VIEW database_stats AS
+SELECT
+ schemaname,
+ tablename,
+ attname as column_name,
+ n_distinct,
+ correlation
+FROM pg_stats
+WHERE schemaname = 'public'
+ORDER BY schemaname, tablename, attname;
+
+\echo 'Ambari database initialization completed successfully!'
+\echo 'Default admin user created: admin/admin'
+\echo 'Sample development cluster created'
+\echo 'Database is ready for Ambari Server setup'