From f6b8edb7dfe34fb32e1bec3e7c7e68dbf09e31b2 Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Tue, 24 Feb 2026 12:32:09 +0100 Subject: [PATCH] feat: add Runtipi addon + upgrade all addons with Proxmox host check, optional Docker install, Alpine support - New: tools/addon/runtipi.sh with full Alpine support (gcompat for musl) - New: tools/headers/runtipi ASCII header - Updated: runtipi.json to addon type with null resources - Removed: ct/runtipi.sh, install/runtipi-install.sh (migrated to addon) - All addons (dockge, komodo, dokploy, coolify, runtipi) now have: - check_proxmox_host(): warns when running on PVE host, default N - check_or_install_docker(): optional Docker install (Debian+Alpine) - Alpine-aware curl bootstrap and dependency installation --- ct/runtipi.sh | 42 ------ frontend/public/json/runtipi.json | 24 ++- install/runtipi-install.sh | 41 ----- tools/addon/coolify.sh | 74 +++++++-- tools/addon/dockge.sh | 68 +++++++-- tools/addon/dokploy.sh | 74 +++++++-- tools/addon/komodo.sh | 59 ++++++-- tools/addon/runtipi.sh | 243 ++++++++++++++++++++++++++++++ tools/headers/runtipi | 5 + 9 files changed, 499 insertions(+), 131 deletions(-) delete mode 100644 ct/runtipi.sh delete mode 100644 install/runtipi-install.sh create mode 100644 tools/addon/runtipi.sh create mode 100644 tools/headers/runtipi diff --git a/ct/runtipi.sh b/ct/runtipi.sh deleted file mode 100644 index 105bcc8b7..000000000 --- a/ct/runtipi.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) -# Copyright (c) 2021-2026 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://runtipi.io/ - -APP="Runtipi" -var_tags="${var_tags:-os}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" -var_disk="${var_disk:-8}" -var_os="${var_os:-debian}" -var_version="${var_version:-13}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -d /opt/runtipi ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - cd /opt/runtipi && ./runtipi-cli update latest - msg_ok "Updated successfully!" - exit -} - -start -build_container -description - -msg_ok "Completed successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}" diff --git a/frontend/public/json/runtipi.json b/frontend/public/json/runtipi.json index fb8772c5c..045cb7e61 100644 --- a/frontend/public/json/runtipi.json +++ b/frontend/public/json/runtipi.json @@ -5,25 +5,25 @@ 2 ], "date_created": "2024-05-02", - "type": "ct", + "type": "addon", "updateable": true, "privileged": false, "interface_port": 80, "documentation": "https://runtipi.io/docs/introduction", "website": "https://runtipi.io/", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/runtipi.webp", - "config_path": "opt/runtipi/state/settings.json", + "config_path": "/opt/runtipi/state/settings.json", "description": "Runtipi lets you install all your favorite self-hosted apps without the hassle of configuring and managing each service. One-click installs and updates for more than 180 popular apps.", "install_methods": [ { "type": "default", - "script": "ct/runtipi.sh", + "script": "tools/addon/runtipi.sh", "resources": { - "cpu": 2, - "ram": 2048, - "hdd": 8, - "os": "debian", - "version": "13" + "cpu": null, + "ram": null, + "hdd": null, + "os": null, + "version": null } } ], @@ -32,9 +32,17 @@ "password": null }, "notes": [ + { + "text": "This is an addon script intended to be used on top of an existing Docker container.", + "type": "info" + }, { "text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.", "type": "warning" + }, + { + "text": "To update via CLI, run the addon script again and select Update, or use: bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/runtipi.sh)", + "type": "info" } ] } diff --git a/install/runtipi-install.sh b/install/runtipi-install.sh deleted file mode 100644 index 04ec9c974..000000000 --- a/install/runtipi-install.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2026 tteck -# Author: tteck (tteckster) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://runtipi.io/ - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -msg_warn "WARNING: This script will run an external installer from a third-party source (https://runtipi.io/)." -msg_warn "The following code is NOT maintained or audited by our repository." -msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:" -msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh" -echo -read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM -if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then - msg_error "Aborted by user. No changes have been made." - exit 10 -fi - -msg_info "Installing Runtipi (Patience)" -DOCKER_CONFIG_PATH='/etc/docker/daemon.json' -mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" -echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH" -cd /opt -curl -fsSL "https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh" -o "install.sh" -chmod +x install.sh -$STD ./install.sh -chmod 666 /opt/runtipi/state/settings.json -rm -f /opt/install.sh -msg_ok "Installed Runtipi" - -motd_ssh -customize -cleanup_lxc diff --git a/tools/addon/coolify.sh b/tools/addon/coolify.sh index 4a257da46..8b8d4c4c5 100644 --- a/tools/addon/coolify.sh +++ b/tools/addon/coolify.sh @@ -6,8 +6,13 @@ # Source: https://coolify.io/ if ! command -v curl &>/dev/null; then printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 - apt-get update >/dev/null 2>&1 - apt-get install -y curl >/dev/null 2>&1 + if [[ -f /etc/alpine-release ]]; then + apk update >/dev/null 2>&1 + apk add --no-cache curl >/dev/null 2>&1 + else + apt-get update >/dev/null 2>&1 + apt-get install -y curl >/dev/null 2>&1 + fi fi source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) @@ -77,25 +82,73 @@ function update() { } # ============================================================================== -# CHECK DOCKER +# PROXMOX HOST CHECK # ============================================================================== -function check_docker() { - if ! command -v docker &>/dev/null; then - msg_warn "Docker is not installed — Coolify installer will set it up." +function check_proxmox_host() { + if command -v pveversion &>/dev/null; then + msg_error "Running on the Proxmox host is NOT recommended!" + msg_error "This should be executed inside an LXC container." + echo "" + echo -n "${TAB}Continue anyway? (y/N): " + read -r confirm + if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then + msg_warn "Aborted. Please run this inside an LXC container." + exit 0 + fi + msg_warn "Proceeding on Proxmox host at your own risk!" + fi +} + +# ============================================================================== +# CHECK / INSTALL DOCKER +# ============================================================================== +function check_or_install_docker() { + if command -v docker &>/dev/null; then + msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available" + if docker compose version &>/dev/null; then + msg_ok "Docker Compose is available" + else + msg_error "Docker Compose plugin is not available. Please install it." + exit 1 + fi return fi - msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available" + + msg_warn "Docker is not installed." + echo -n "${TAB}Install Docker now? (y/N): " + read -r install_docker_prompt + if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then + msg_error "Docker is required for ${APP}. Exiting." + exit 1 + fi + + msg_info "Installing Docker" + if [[ -f /etc/alpine-release ]]; then + $STD apk add docker docker-cli-compose + $STD rc-service docker start + $STD rc-update add docker default + else + DOCKER_CONFIG_PATH='/etc/docker/daemon.json' + mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" + echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH" + $STD sh <(curl -fsSL https://get.docker.com) + fi + msg_ok "Installed Docker" } # ============================================================================== # INSTALL # ============================================================================== function install() { - check_docker + check_or_install_docker msg_info "Installing dependencies" - $STD apt-get update - $STD apt-get install -y git openssl + if [[ -f /etc/alpine-release ]]; then + $STD apk add --no-cache git openssl + else + $STD apt-get update + $STD apt-get install -y git openssl + fi msg_ok "Installed dependencies" msg_warn "WARNING: This will run an external installer from https://coolify.io/" @@ -134,6 +187,7 @@ if [[ "${type:-}" == "update" ]]; then fi header_info +check_proxmox_host get_lxc_ip # Check if already installed diff --git a/tools/addon/dockge.sh b/tools/addon/dockge.sh index 233217dcf..8009ec168 100644 --- a/tools/addon/dockge.sh +++ b/tools/addon/dockge.sh @@ -6,8 +6,13 @@ # Source: https://dockge.kuma.pet/ if ! command -v curl &>/dev/null; then printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 - apt-get update >/dev/null 2>&1 - apt-get install -y curl >/dev/null 2>&1 + if [[ -f /etc/alpine-release ]]; then + apk update >/dev/null 2>&1 + apk add --no-cache curl >/dev/null 2>&1 + else + apt-get update >/dev/null 2>&1 + apt-get install -y curl >/dev/null 2>&1 + fi fi source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) @@ -83,25 +88,65 @@ function update() { } # ============================================================================== -# CHECK DOCKER +# PROXMOX HOST CHECK # ============================================================================== -function check_docker() { - if ! command -v docker &>/dev/null; then - msg_error "Docker is not installed. This addon requires an existing Docker LXC. Exiting." +function check_proxmox_host() { + if command -v pveversion &>/dev/null; then + msg_error "Running on the Proxmox host is NOT recommended!" + msg_error "This should be executed inside an LXC container." + echo "" + echo -n "${TAB}Continue anyway? (y/N): " + read -r confirm + if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then + msg_warn "Aborted. Please run this inside an LXC container." + exit 0 + fi + msg_warn "Proceeding on Proxmox host at your own risk!" + fi +} + +# ============================================================================== +# CHECK / INSTALL DOCKER +# ============================================================================== +function check_or_install_docker() { + if command -v docker &>/dev/null; then + msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available" + if docker compose version &>/dev/null; then + msg_ok "Docker Compose is available" + else + msg_error "Docker Compose plugin is not available. Please install it." + exit 1 + fi + return + fi + + msg_warn "Docker is not installed." + echo -n "${TAB}Install Docker now? (y/N): " + read -r install_docker_prompt + if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then + msg_error "Docker is required for ${APP}. Exiting." exit 1 fi - if ! docker compose version &>/dev/null; then - msg_error "Docker Compose plugin is not available. Please install it before running this script. Exiting." - exit 1 + + msg_info "Installing Docker" + if [[ -f /etc/alpine-release ]]; then + $STD apk add docker docker-cli-compose + $STD rc-service docker start + $STD rc-update add docker default + else + DOCKER_CONFIG_PATH='/etc/docker/daemon.json' + mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" + echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH" + $STD sh <(curl -fsSL https://get.docker.com) fi - msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available" + msg_ok "Installed Docker" } # ============================================================================== # INSTALL # ============================================================================== function install() { - check_docker + check_or_install_docker msg_info "Creating install directories" mkdir -p "$INSTALL_PATH" "$STACKS_PATH" @@ -137,6 +182,7 @@ if [[ "${type:-}" == "update" ]]; then fi header_info +check_proxmox_host get_lxc_ip # Check if already installed diff --git a/tools/addon/dokploy.sh b/tools/addon/dokploy.sh index 64d8beecd..afe7d3fe8 100644 --- a/tools/addon/dokploy.sh +++ b/tools/addon/dokploy.sh @@ -6,8 +6,13 @@ # Source: https://dokploy.com/ if ! command -v curl &>/dev/null; then printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 - apt-get update >/dev/null 2>&1 - apt-get install -y curl >/dev/null 2>&1 + if [[ -f /etc/alpine-release ]]; then + apk update >/dev/null 2>&1 + apk add --no-cache curl >/dev/null 2>&1 + else + apt-get update >/dev/null 2>&1 + apt-get install -y curl >/dev/null 2>&1 + fi fi source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) @@ -76,25 +81,73 @@ function update() { } # ============================================================================== -# CHECK DOCKER +# PROXMOX HOST CHECK # ============================================================================== -function check_docker() { - if ! command -v docker &>/dev/null; then - msg_warn "Docker is not installed — Dokploy installer will set it up." +function check_proxmox_host() { + if command -v pveversion &>/dev/null; then + msg_error "Running on the Proxmox host is NOT recommended!" + msg_error "This should be executed inside an LXC container." + echo "" + echo -n "${TAB}Continue anyway? (y/N): " + read -r confirm + if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then + msg_warn "Aborted. Please run this inside an LXC container." + exit 0 + fi + msg_warn "Proceeding on Proxmox host at your own risk!" + fi +} + +# ============================================================================== +# CHECK / INSTALL DOCKER +# ============================================================================== +function check_or_install_docker() { + if command -v docker &>/dev/null; then + msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available" + if docker compose version &>/dev/null; then + msg_ok "Docker Compose is available" + else + msg_error "Docker Compose plugin is not available. Please install it." + exit 1 + fi return fi - msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available" + + msg_warn "Docker is not installed." + echo -n "${TAB}Install Docker now? (y/N): " + read -r install_docker_prompt + if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then + msg_error "Docker is required for ${APP}. Exiting." + exit 1 + fi + + msg_info "Installing Docker" + if [[ -f /etc/alpine-release ]]; then + $STD apk add docker docker-cli-compose + $STD rc-service docker start + $STD rc-update add docker default + else + DOCKER_CONFIG_PATH='/etc/docker/daemon.json' + mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" + echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH" + $STD sh <(curl -fsSL https://get.docker.com) + fi + msg_ok "Installed Docker" } # ============================================================================== # INSTALL # ============================================================================== function install() { - check_docker + check_or_install_docker msg_info "Installing dependencies" - $STD apt-get update - $STD apt-get install -y git openssl redis + if [[ -f /etc/alpine-release ]]; then + $STD apk add --no-cache git openssl + else + $STD apt-get update + $STD apt-get install -y git openssl redis + fi msg_ok "Installed dependencies" msg_warn "WARNING: This will run an external installer from https://dokploy.com/" @@ -132,6 +185,7 @@ if [[ "${type:-}" == "update" ]]; then fi header_info +check_proxmox_host get_lxc_ip # Check if already installed diff --git a/tools/addon/komodo.sh b/tools/addon/komodo.sh index 9fed8af8a..a3a4b4cd8 100644 --- a/tools/addon/komodo.sh +++ b/tools/addon/komodo.sh @@ -117,25 +117,65 @@ function update() { } # ============================================================================== -# CHECK DOCKER +# PROXMOX HOST CHECK # ============================================================================== -function check_docker() { - if ! command -v docker &>/dev/null; then - msg_error "Docker is not installed. This addon requires an existing Docker LXC. Exiting." +function check_proxmox_host() { + if command -v pveversion &>/dev/null; then + msg_error "Running on the Proxmox host is NOT recommended!" + msg_error "This should be executed inside an LXC container." + echo "" + echo -n "${TAB}Continue anyway? (y/N): " + read -r confirm + if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then + msg_warn "Aborted. Please run this inside an LXC container." + exit 0 + fi + msg_warn "Proceeding on Proxmox host at your own risk!" + fi +} + +# ============================================================================== +# CHECK / INSTALL DOCKER +# ============================================================================== +function check_or_install_docker() { + if command -v docker &>/dev/null; then + msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available" + if docker compose version &>/dev/null; then + msg_ok "Docker Compose is available" + else + msg_error "Docker Compose plugin is not available. Please install it." + exit 1 + fi + return + fi + + msg_warn "Docker is not installed." + echo -n "${TAB}Install Docker now? (y/N): " + read -r install_docker_prompt + if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then + msg_error "Docker is required for ${APP}. Exiting." exit 1 fi - if ! docker compose version &>/dev/null; then - msg_error "Docker Compose plugin is not available. Please install it before running this script. Exiting." - exit 1 + + msg_info "Installing Docker" + if [[ -f /etc/alpine-release ]]; then + $STD apk add docker docker-cli-compose + $STD rc-service docker start + $STD rc-update add docker default + else + DOCKER_CONFIG_PATH='/etc/docker/daemon.json' + mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" + echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH" + $STD sh <(curl -fsSL https://get.docker.com) fi - msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available" + msg_ok "Installed Docker" } # ============================================================================== # INSTALL # ============================================================================== function install() { - check_docker + check_or_install_docker echo -e "${TAB}Choose the database for Komodo:" echo -e "${TAB} 1) MongoDB (recommended)" @@ -220,6 +260,7 @@ if [[ "${type:-}" == "update" ]]; then fi header_info +check_proxmox_host get_lxc_ip # Declare variables used by find_compose_file diff --git a/tools/addon/runtipi.sh b/tools/addon/runtipi.sh new file mode 100644 index 000000000..9d7305333 --- /dev/null +++ b/tools/addon/runtipi.sh @@ -0,0 +1,243 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://runtipi.io/ +if ! command -v curl &>/dev/null; then + printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 + if [[ -f /etc/alpine-release ]]; then + apk update >/dev/null 2>&1 + apk add --no-cache curl >/dev/null 2>&1 + else + apt-get update >/dev/null 2>&1 + apt-get install -y curl >/dev/null 2>&1 + fi +fi +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true + +# Enable error handling +set -Eeuo pipefail +trap 'error_handler' ERR + +# ============================================================================== +# CONFIGURATION +# ============================================================================== +APP="Runtipi" +APP_TYPE="addon" +INSTALL_PATH="/opt/runtipi" +DEFAULT_PORT=80 + +# Initialize all core functions (colors, formatting, icons, STD mode) +load_functions + +# ============================================================================== +# HEADER +# ============================================================================== +function header_info { + clear + cat <<"EOF" + ____ __ _ _ + / __ \__ ______ / /_(_)__ (_) + / /_/ / / / / __ \/ __/ / _ \/ / + / _, _/ /_/ / / / / /_/ / ___/ / +/_/ |_|\__,_/_/ /_/\__/_/_/ /_/ + +EOF +} + +# ============================================================================== +# PROXMOX HOST CHECK +# ============================================================================== +function check_proxmox_host() { + if command -v pveversion &>/dev/null; then + msg_error "Running on the Proxmox host is NOT recommended!" + msg_error "This should be executed inside an LXC container." + echo "" + echo -n "${TAB}Continue anyway? (y/N): " + read -r confirm + if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then + msg_warn "Aborted. Please run this inside an LXC container." + exit 0 + fi + msg_warn "Proceeding on Proxmox host at your own risk!" + fi +} + +# ============================================================================== +# CHECK / INSTALL DOCKER +# ============================================================================== +function check_or_install_docker() { + if command -v docker &>/dev/null; then + msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available" + if docker compose version &>/dev/null; then + msg_ok "Docker Compose is available" + else + msg_error "Docker Compose plugin is not available. Please install it." + exit 1 + fi + return + fi + + msg_warn "Docker is not installed." + echo -n "${TAB}Install Docker now? (y/N): " + read -r install_docker_prompt + if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then + msg_error "Docker is required for ${APP}. Exiting." + exit 1 + fi + + msg_info "Installing Docker" + if [[ -f /etc/alpine-release ]]; then + $STD apk add docker docker-cli-compose + $STD rc-service docker start + $STD rc-update add docker default + else + DOCKER_CONFIG_PATH='/etc/docker/daemon.json' + mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" + echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH" + $STD sh <(curl -fsSL https://get.docker.com) + fi + msg_ok "Installed Docker" +} + +# ============================================================================== +# UNINSTALL +# ============================================================================== +function uninstall() { + msg_info "Uninstalling ${APP}" + + if [[ -f "${INSTALL_PATH}/runtipi-cli" ]]; then + msg_info "Stopping ${APP}" + cd "$INSTALL_PATH" + $STD ./runtipi-cli stop 2>/dev/null || true + msg_ok "Stopped ${APP}" + fi + + if command -v docker &>/dev/null; then + msg_info "Removing Docker containers" + cd "$INSTALL_PATH" 2>/dev/null && $STD docker compose down --remove-orphans 2>/dev/null || true + msg_ok "Removed Docker containers" + fi + + rm -rf "$INSTALL_PATH" + msg_ok "${APP} has been uninstalled" +} + +# ============================================================================== +# UPDATE +# ============================================================================== +function update() { + msg_info "Updating ${APP}" + cd "$INSTALL_PATH" + $STD ./runtipi-cli update latest + msg_ok "Updated ${APP}" + + msg_ok "Updated successfully" + exit +} + +# ============================================================================== +# INSTALL +# ============================================================================== +function install() { + check_or_install_docker + + msg_info "Installing dependencies" + if [[ -f /etc/alpine-release ]]; then + $STD apk add --no-cache openssl gcompat + else + $STD apt-get update + $STD apt-get install -y openssl + fi + msg_ok "Installed dependencies" + + msg_warn "WARNING: This will run an external installer from https://runtipi.io/" + msg_warn "The following code is NOT maintained or audited by our repository." + msg_warn "Review: https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh" + echo "" + echo -n "${TAB}Do you want to continue? (y/N): " + read -r confirm + if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then + msg_warn "Installation cancelled. Exiting." + exit 0 + fi + + msg_info "Installing ${APP} (this pulls Docker containers)" + DOCKER_CONFIG_PATH='/etc/docker/daemon.json' + mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")" + [[ ! -f "$DOCKER_CONFIG_PATH" ]] && echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH" + cd /opt + curl -fsSL "https://raw.githubusercontent.com/runtipi/runtipi/master/scripts/install.sh" -o "install.sh" + chmod +x install.sh + $STD ./install.sh + chmod 666 /opt/runtipi/state/settings.json 2>/dev/null || true + rm -f /opt/install.sh + msg_ok "Installed ${APP}" + + echo "" + msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}" +} + +# ============================================================================== +# MAIN +# ============================================================================== + +# Handle type=update (called from update script) +if [[ "${type:-}" == "update" ]]; then + header_info + if [[ -d "$INSTALL_PATH" ]]; then + update + else + msg_error "${APP} is not installed. Nothing to update." + exit 1 + fi + exit 0 +fi + +header_info +check_proxmox_host +get_lxc_ip + +# Check if already installed +if [[ -d "$INSTALL_PATH" ]]; then + msg_warn "${APP} is already installed." + echo "" + + echo -n "${TAB}Uninstall ${APP}? (y/N): " + read -r uninstall_prompt + if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then + uninstall + exit 0 + fi + + echo -n "${TAB}Update ${APP}? (y/N): " + read -r update_prompt + if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then + update + exit 0 + fi + + msg_warn "No action selected. Exiting." + exit 0 +fi + +# Fresh installation +msg_warn "${APP} is not installed." +echo "" +echo -e "${TAB}${INFO} This will install:" +echo -e "${TAB} - Runtipi (via external installer)" +echo -e "${TAB} - Docker (if not already installed)" +echo "" + +echo -n "${TAB}Install ${APP}? (y/N): " +read -r install_prompt +if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then + install +else + msg_warn "Installation cancelled. Exiting." + exit 0 +fi diff --git a/tools/headers/runtipi b/tools/headers/runtipi new file mode 100644 index 000000000..e34ec09ea --- /dev/null +++ b/tools/headers/runtipi @@ -0,0 +1,5 @@ + ____ __ _ _ + / __ \__ ______ / /_(_)__ (_) + / /_/ / / / / __ \/ __/ / _ \/ / + / _, _/ /_/ / / / / /_/ / ___/ / +/_/ |_|\__,_/_/ /_/\__/_/_/ /_/