openvidu/openvidu-deployment/pro/elastic/install_ov_master_node.sh

229 lines
9.6 KiB
Bash

#!/bin/sh
# Docker & Docker Compose will need to be installed on the machine
set -eu
export DOCKER_VERSION="${DOCKER_VERSION:-28.1.1}"
export DOCKER_COMPOSE_VERSION="${DOCKER_COMPOSE_VERSION:-v2.35.1}"
export OPENVIDU_VERSION="${OPENVIDU_VERSION:-main}"
export INSTALLER_IMAGE="${INSTALLER_IMAGE:-docker.io/openvidu/openvidu-installer:${OPENVIDU_VERSION}}"
export MINIO_SERVER_IMAGE="${MINIO_SERVER_IMAGE:-docker.io/bitnami/minio:2025.5.24-debian-12-r1}"
export MINIO_CLIENT_IMAGE="${MINIO_CLIENT_IMAGE:-docker.io/minio/mc:RELEASE.2025-05-21T01-59-54Z}"
export MONGO_SERVER_IMAGE="${MONGO_SERVER_IMAGE:-docker.io/mongo:8.0.9}"
export REDIS_SERVER_IMAGE="${REDIS_SERVER_IMAGE:-docker.io/redis:7.4.4-alpine}"
export BUSYBOX_IMAGE="${BUSYBOX_IMAGE:-docker.io/busybox:1.37.0}"
export CADDY_SERVER_IMAGE="${CADDY_SERVER_IMAGE:-docker.io/openvidu/openvidu-caddy:${OPENVIDU_VERSION}}"
export CADDY_SERVER_PRO_IMAGE="${CADDY_SERVER_PRO_IMAGE:-docker.io/openvidu/openvidu-pro-caddy:${OPENVIDU_VERSION}}"
export OPENVIDU_OPERATOR_IMAGE="${OPENVIDU_OPERATOR_IMAGE:-docker.io/openvidu/openvidu-operator:${OPENVIDU_VERSION}}"
export OPENVIDU_SERVER_PRO_IMAGE="${OPENVIDU_SERVER_PRO_IMAGE:-docker.io/openvidu/openvidu-server-pro:${OPENVIDU_VERSION}}"
export OPENVIDU_SERVER_IMAGE="${OPENVIDU_SERVER_IMAGE:-docker.io/openvidu/openvidu-server:${OPENVIDU_VERSION}}"
export OPENVIDU_MEET_SERVER_IMAGE="${OPENVIDU_MEET_SERVER_IMAGE:-docker.io/openvidu/openvidu-meet:${OPENVIDU_VERSION}}"
export OPENVIDU_DASHBOARD_PRO_IMAGE="${OPENVIDU_DASHBOARD_PRO_IMAGE:-docker.io/openvidu/openvidu-pro-dashboard:${OPENVIDU_VERSION}}"
export OPENVIDU_DASHBOARD_IMAGE="${OPENVIDU_DASHBOARD_IMAGE:-docker.io/openvidu/openvidu-dashboard:${OPENVIDU_VERSION}}"
export OPENVIDU_V2COMPATIBILITY_IMAGE="${OPENVIDU_V2COMPATIBILITY_IMAGE:-docker.io/openvidu/openvidu-v2compatibility:${OPENVIDU_VERSION}}"
export OPENVIDU_AGENT_SPEECH_PROCESSING_IMAGE="${OPENVIDU_AGENT_SPEECH_PROCESSING_IMAGE:-docker.io/openvidu/agent-speech-processing:${OPENVIDU_VERSION}}"
export LIVEKIT_INGRESS_SERVER_IMAGE="${LIVEKIT_INGRESS_SERVER_IMAGE:-docker.io/openvidu/ingress:${OPENVIDU_VERSION}}"
export LIVEKIT_EGRESS_SERVER_IMAGE="${LIVEKIT_EGRESS_SERVER_IMAGE:-docker.io/livekit/egress:v1.9.1}"
export PROMETHEUS_IMAGE="${PROMETHEUS_IMAGE:-docker.io/prom/prometheus:v3.4.0}"
export PROMTAIL_IMAGE="${PROMTAIL_IMAGE:-docker.io/grafana/promtail:3.5.1}"
export LOKI_IMAGE="${LOKI_IMAGE:-docker.io/grafana/loki:3.5.1}"
export MIMIR_IMAGE="${MIMIR_IMAGE:-docker.io/bitnami/grafana-mimir:2.16.0}"
export GRAFANA_IMAGE="${GRAFANA_IMAGE:-docker.io/grafana/grafana:11.6.2}"
# Function to compare two version strings
compare_versions() {
# Remove 'v' prefix if present
VERSION1=$(echo "$1" | sed 's/^v//')
VERSION2=$(echo "$2" | sed 's/^v//')
# Compare versions
if [ "$(printf '%s\n' "$VERSION1" "$VERSION2" | sort -V | head -n1)" = "$VERSION1" ]; then
if [ "$VERSION1" = "$VERSION2" ]; then
echo "equal"
else
echo "lower"
fi
else
echo "higher"
fi
}
wait_for_docker() {
echo "Waiting for Docker to start..."
# Set a countdown (in seconds)
COUNTDOWN=60
while [ "$COUNTDOWN" -gt 0 ]; do
if docker info >/dev/null 2>&1; then
echo "Docker started successfully."
break
else
# Reduce the countdown by 1 each iteration.
COUNTDOWN=$(( COUNTDOWN - 1 ))
if [ "$COUNTDOWN" -eq 0 ]; then
echo "ERROR: Docker did not start within the allocated time."
break
fi
sleep 1
fi
done
}
# Check if executing as root
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
# Check Docker installation and version
DOCKER_NEEDED=false
if ! command -v docker > /dev/null 2>&1; then
echo "Docker not found. Will install Docker version ${DOCKER_VERSION}."
DOCKER_NEEDED=true
else
CURRENT_DOCKER_VERSION=$(docker --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
VERSION_COMPARISON=$(compare_versions "$CURRENT_DOCKER_VERSION" "$DOCKER_VERSION")
if [ "$VERSION_COMPARISON" = "lower" ]; then
echo "Docker version $CURRENT_DOCKER_VERSION is older than required version $DOCKER_VERSION."
echo "Please update Docker to version $DOCKER_VERSION or later."
exit 1
else
echo "Docker version $CURRENT_DOCKER_VERSION is compatible with required version $DOCKER_VERSION."
fi
fi
# Install Docker if needed
if [ "$DOCKER_NEEDED" = true ]; then
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
sh /tmp/get-docker.sh --version "${DOCKER_VERSION}" || { echo "Can't install Docker automatically. Install it manually and run this script again"; exit 1; }
fi
# Check Docker Compose installation and version
DOCKER_COMPOSE_NEEDED=false
if ! command -v docker-compose > /dev/null 2>&1; then
echo "Docker Compose not found. Will install Docker Compose version ${DOCKER_COMPOSE_VERSION}."
DOCKER_COMPOSE_NEEDED=true
else
CURRENT_DC_VERSION=$(docker-compose --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
# Add 'v' prefix for proper comparison
CURRENT_DC_VERSION="v${CURRENT_DC_VERSION}"
VERSION_COMPARISON=$(compare_versions "$CURRENT_DC_VERSION" "$DOCKER_COMPOSE_VERSION")
if [ "$VERSION_COMPARISON" = "lower" ]; then
echo "Docker Compose version $CURRENT_DC_VERSION is older than required version $DOCKER_COMPOSE_VERSION."
echo "Will update Docker Compose to version $DOCKER_COMPOSE_VERSION."
DOCKER_COMPOSE_NEEDED=true
else
echo "Docker Compose version $CURRENT_DC_VERSION is compatible with required version $DOCKER_COMPOSE_VERSION."
fi
fi
# Install or update Docker Compose if needed
if [ "$DOCKER_COMPOSE_NEEDED" = true ]; then
TIME_LIMIT_SECONDS=20
START_TIME=$(awk 'BEGIN{srand(); print srand()}')
while true
do
CURRENT_TIME=$(awk 'BEGIN{srand(); print srand()}')
if [ $((CURRENT_TIME-START_TIME)) -gt $TIME_LIMIT_SECONDS ]; then
echo "Error downloading docker-compose. Could not download it in $TIME_LIMIT_SECONDS seconds"
rm -f /usr/local/bin/docker-compose
exit 1
fi
STATUS_RECEIVED=$(curl --retry 5 --retry-max-time 40 --write-out "%{http_code}\n" -L "https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose)
CURL_EXIT_CODE=$?
if [ $CURL_EXIT_CODE -ne 0 ]; then
echo "Error downloading docker-compose. curl failed with exit code $CURL_EXIT_CODE. There are still $((TIME_LIMIT_SECONDS - (CURRENT_TIME - START_TIME))) seconds left to retry..."
rm -f /usr/local/bin/docker-compose
sleep 2
continue
fi
if [ "${STATUS_RECEIVED}" -ne "200" ]; then
echo "Error downloading docker-compose. Received HTTP status code $STATUS_RECEIVED. There are still $((TIME_LIMIT_SECONDS - (CURRENT_TIME - START_TIME))) seconds left to retry..."
rm -f /usr/local/bin/docker-compose
sleep 2
continue
fi
echo "Success downloading docker-compose version $DOCKER_COMPOSE_VERSION"
chmod 755 /usr/local/bin/docker-compose
break
done
# Create a symbolic link to docker-compose in the Docker CLI plugins directory
# so docker compose can be used also
mkdir -p /usr/local/lib/docker/cli-plugins
ln -sf /usr/local/bin/docker-compose /usr/local/lib/docker/cli-plugins/docker-compose
fi
# Restart Docker and wait for it to start
systemctl enable docker
systemctl stop docker
systemctl start docker
wait_for_docker
# Create random temp directory
TMP_DIR=$(mktemp -d)
docker pull "${INSTALLER_IMAGE}"
# Generate installation scripts
COMMON_DOCKER_OPTIONS="--network=host -v ${TMP_DIR}:/output \
-e OPENVIDU_VERSION=$OPENVIDU_VERSION \
-e CADDY_SERVER_IMAGE=$CADDY_SERVER_IMAGE \
-e CADDY_SERVER_PRO_IMAGE=$CADDY_SERVER_PRO_IMAGE \
-e MINIO_SERVER_IMAGE=$MINIO_SERVER_IMAGE \
-e MINIO_CLIENT_IMAGE=$MINIO_CLIENT_IMAGE \
-e MONGO_SERVER_IMAGE=$MONGO_SERVER_IMAGE \
-e REDIS_SERVER_IMAGE=$REDIS_SERVER_IMAGE \
-e BUSYBOX_IMAGE=$BUSYBOX_IMAGE \
-e OPENVIDU_OPERATOR_IMAGE=$OPENVIDU_OPERATOR_IMAGE \
-e OPENVIDU_SERVER_PRO_IMAGE=$OPENVIDU_SERVER_PRO_IMAGE \
-e OPENVIDU_SERVER_IMAGE=$OPENVIDU_SERVER_IMAGE \
-e OPENVIDU_MEET_SERVER_IMAGE=$OPENVIDU_MEET_SERVER_IMAGE \
-e OPENVIDU_DASHBOARD_PRO_IMAGE=$OPENVIDU_DASHBOARD_PRO_IMAGE \
-e OPENVIDU_DASHBOARD_IMAGE=$OPENVIDU_DASHBOARD_IMAGE \
-e OPENVIDU_V2COMPATIBILITY_IMAGE=$OPENVIDU_V2COMPATIBILITY_IMAGE \
-e OPENVIDU_AGENT_SPEECH_PROCESSING_IMAGE=$OPENVIDU_AGENT_SPEECH_PROCESSING_IMAGE \
-e LIVEKIT_INGRESS_SERVER_IMAGE=$LIVEKIT_INGRESS_SERVER_IMAGE \
-e LIVEKIT_EGRESS_SERVER_IMAGE=$LIVEKIT_EGRESS_SERVER_IMAGE \
-e PROMETHEUS_IMAGE=$PROMETHEUS_IMAGE \
-e PROMTAIL_IMAGE=$PROMTAIL_IMAGE \
-e LOKI_IMAGE=$LOKI_IMAGE \
-e MIMIR_IMAGE=$MIMIR_IMAGE \
-e GRAFANA_IMAGE=$GRAFANA_IMAGE \
${INSTALLER_IMAGE} \
--deployment-type=elastic \
--node-role=master-node \
--install \
$*"
INTERACTIVE_MODE=true
for arg in "$@"; do
if [ "$arg" = "--no-tty" ]; then
INTERACTIVE_MODE=false;
break
fi
done
if [ "$INTERACTIVE_MODE" = true ]; then
docker run -it ${COMMON_DOCKER_OPTIONS} > /dev/tty
else
docker run -i ${COMMON_DOCKER_OPTIONS}
fi
cd "$TMP_DIR/installation-scripts/openvidu/"
chmod +x install_ov_master_node.sh
./install_ov_master_node.sh
cat finish-message.txt
# Warn about private IP being setup correctly
echo
echo "ATTENTION!!! This is the private IP of the 'Master Node'. Make sure this IP is reachable from all the 'Media Nodes'"
cat private-ip.txt
echo "If this is not your private IP, reinstall the 'Master Node' with the correct '--private-ip' parameter"
echo