mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-08-03 03:23:04 +02:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 68fb836635 | |||
| a6196990a6 | |||
| 753f74c67d | |||
| aa4cd6a5ba | |||
| 92bc6915b1 | |||
| 915226fa3c | |||
| f8c7af7115 | |||
| 97aa6b39cb |
@@ -524,6 +524,8 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- LibreNMS: Ensure ipmitool dependency is installed [@tremor021](https://github.com/tremor021) ([#16219](https://github.com/community-scripts/ProxmoxVE/pull/16219))
|
||||||
|
- Bitfocus Companion: add libatomic1 dependency [@tremor021](https://github.com/tremor021) ([#16212](https://github.com/community-scripts/ProxmoxVE/pull/16212))
|
||||||
- fix(dispatcharr): add recordings and dvr queues to celery worker [@eXistC](https://github.com/eXistC) ([#16204](https://github.com/community-scripts/ProxmoxVE/pull/16204))
|
- fix(dispatcharr): add recordings and dvr queues to celery worker [@eXistC](https://github.com/eXistC) ([#16204](https://github.com/community-scripts/ProxmoxVE/pull/16204))
|
||||||
- add retry for uv - same as immich [@asylumexp](https://github.com/asylumexp) ([#16203](https://github.com/community-scripts/ProxmoxVE/pull/16203))
|
- add retry for uv - same as immich [@asylumexp](https://github.com/asylumexp) ([#16203](https://github.com/community-scripts/ProxmoxVE/pull/16203))
|
||||||
- Fix for cross-seed node version regression [@TorinFrancis](https://github.com/TorinFrancis) ([#16209](https://github.com/community-scripts/ProxmoxVE/pull/16209))
|
- Fix for cross-seed node version regression [@TorinFrancis](https://github.com/TorinFrancis) ([#16209](https://github.com/community-scripts/ProxmoxVE/pull/16209))
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ function update_script() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ensure_dependencies libatomic1
|
||||||
|
|
||||||
RELEASE_JSON=$(curl -fsSL "https://api.bitfocus.io/v1/product/companion/packages?limit=20")
|
RELEASE_JSON=$(curl -fsSL "https://api.bitfocus.io/v1/product/companion/packages?limit=20")
|
||||||
PACKAGE_JSON=$(echo "$RELEASE_JSON" | jq -c \
|
PACKAGE_JSON=$(echo "$RELEASE_JSON" | jq -c \
|
||||||
--arg target "linux-$(arch_resolve "tgz" "arm64-tgz")" \
|
--arg target "linux-$(arch_resolve "tgz" "arm64-tgz")" \
|
||||||
|
|||||||
+5
-16
@@ -37,20 +37,9 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if docker ps -a --format '{{.Image}}' | grep -q '^portainer/portainer-ce:latest$'; then
|
if docker ps -a --format '{{.Image}}' | grep -q '^portainer/portainer-ce:latest$'; then
|
||||||
msg_info "Updating Portainer"
|
msg_warn "Portainer is now managed by a dedicated addon script and is no longer updated here."
|
||||||
$STD docker pull portainer/portainer-ce:latest
|
echo -e "${TAB}Update/migrate it with:"
|
||||||
$STD docker stop portainer
|
echo -e "${TAB}${TAB}${GN}bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)\"${CL}"
|
||||||
$STD docker rm portainer
|
|
||||||
$STD docker volume create portainer_data >/dev/null 2>&1
|
|
||||||
$STD docker run -d \
|
|
||||||
-p 8000:8000 \
|
|
||||||
-p 9443:9443 \
|
|
||||||
--name=portainer \
|
|
||||||
--restart=always \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v portainer_data:/data \
|
|
||||||
portainer/portainer-ce:latest
|
|
||||||
msg_ok "Updated Portainer"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then
|
if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then
|
||||||
@@ -77,5 +66,5 @@ description
|
|||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} If you installed Portainer, access it at the following URL:${CL}"
|
echo -e "${INFO}${YW} Portainer is available as a separate addon. Install it with:${CL}"
|
||||||
echo -e "${GATEWAY}${BGN}https://${IP}:9443${CL}"
|
echo -e "${GATEWAY}${BGN}bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)\"${CL}"
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ensure_dependencies ipmitool
|
||||||
|
|
||||||
if check_for_gh_release "librenms" "librenms/librenms"; then
|
if check_for_gh_release "librenms" "librenms/librenms"; then
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop php8.4-fpm librenms-scheduler.timer
|
systemctl stop php8.4-fpm librenms-scheduler.timer
|
||||||
|
|||||||
@@ -26,23 +26,21 @@ msg_ok "Installed Docker"
|
|||||||
get_latest_release() {
|
get_latest_release() {
|
||||||
curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4
|
curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4
|
||||||
}
|
}
|
||||||
PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer")
|
|
||||||
DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose")
|
DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose")
|
||||||
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent")
|
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent")
|
||||||
|
|
||||||
read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt
|
read -r -p "${TAB3}Would you like to add Docker Compose? <y/N> " prompt
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Installing Portainer $PORTAINER_LATEST_VERSION"
|
msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
|
||||||
docker volume create portainer_data >/dev/null
|
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
|
||||||
$STD docker run -d \
|
mkdir -p "$DOCKER_CONFIG"/cli-plugins
|
||||||
-p 8000:8000 \
|
curl -fsSL https://github.com/docker/compose/releases/download/"$DOCKER_COMPOSE_LATEST_VERSION"/docker-compose-linux-$(arch_resolve "x86_64" "aarch64") -o ~/.docker/cli-plugins/docker-compose
|
||||||
-p 9443:9443 \
|
chmod +x "$DOCKER_CONFIG"/cli-plugins/docker-compose
|
||||||
--name=portainer \
|
msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
|
||||||
--restart=always \
|
fi
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v portainer_data:/data \
|
if prompt_confirm "${TAB3}Would you like to install Portainer (UI) via the community-scripts addon?" "n" 60; then
|
||||||
portainer/portainer-ce:latest
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)" <<<"y"
|
||||||
msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION"
|
|
||||||
else
|
else
|
||||||
read -r -p "${TAB3}Would you like to add the Portainer Agent? <y/N> " prompt
|
read -r -p "${TAB3}Would you like to add the Portainer Agent? <y/N> " prompt
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
@@ -57,21 +55,12 @@ else
|
|||||||
msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION"
|
msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
read -r -p "${TAB3}Would you like to add Docker Compose? <y/N> " prompt
|
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
|
|
||||||
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
|
|
||||||
mkdir -p "$DOCKER_CONFIG"/cli-plugins
|
|
||||||
curl -fsSL https://github.com/docker/compose/releases/download/"$DOCKER_COMPOSE_LATEST_VERSION"/docker-compose-linux-$(arch_resolve "x86_64" "aarch64") -o ~/.docker/cli-plugins/docker-compose
|
|
||||||
chmod +x "$DOCKER_CONFIG"/cli-plugins/docker-compose
|
|
||||||
msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -r -p "${TAB3}Would you like to expose the Docker TCP socket? <y/N> " prompt
|
read -r -p "${TAB3}Would you like to expose the Docker TCP socket? <y/N> " prompt
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Exposing Docker TCP socket"
|
msg_info "Exposing Docker TCP socket"
|
||||||
$STD mkdir -p /etc/docker
|
$STD mkdir -p /etc/docker
|
||||||
$STD echo '{ "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"] }' > /etc/docker/daemon.json
|
$STD echo '{ "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"] }' >/etc/docker/daemon.json
|
||||||
$STD rc-service docker restart
|
$STD rc-service docker restart
|
||||||
msg_ok "Exposed Docker TCP socket at tcp://+:2375"
|
msg_ok "Exposed Docker TCP socket at tcp://+:2375"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y libusb-1.0-0
|
$STD apt install -y \
|
||||||
|
libusb-1.0-0 \
|
||||||
|
libatomic1
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Fetching Latest Bitfocus Companion Release"
|
msg_info "Fetching Latest Bitfocus Companion Release"
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ update_os
|
|||||||
|
|
||||||
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_github_release "portainer/agent")
|
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_github_release "portainer/agent")
|
||||||
|
|
||||||
read -r -p "${TAB3}Would you like to add Portainer (UI)? <y/N> " prompt
|
setup_docker
|
||||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
|
|
||||||
DOCKER_PORTAINER="true" setup_docker
|
if prompt_confirm "${TAB3}Would you like to install Portainer (UI) via the community-scripts addon?" "n" 60; then
|
||||||
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)" <<<"y"
|
||||||
else
|
else
|
||||||
setup_docker
|
|
||||||
read -r -p "${TAB3}Would you like to install the Portainer Agent (for remote management)? <y/N> " prompt_agent
|
read -r -p "${TAB3}Would you like to install the Portainer Agent (for remote management)? <y/N> " prompt_agent
|
||||||
if [[ ${prompt_agent,,} =~ ^(y|yes)$ ]]; then
|
if [[ ${prompt_agent,,} =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Installing Portainer Agent $PORTAINER_AGENT_LATEST_VERSION"
|
msg_info "Installing Portainer Agent $PORTAINER_AGENT_LATEST_VERSION"
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ get_latest_release() {
|
|||||||
|
|
||||||
CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core")
|
CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core")
|
||||||
|
|
||||||
DOCKER_PORTAINER="true" setup_docker
|
setup_docker
|
||||||
|
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)" <<<"y"
|
||||||
|
|
||||||
msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image"
|
msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image"
|
||||||
$STD docker pull ghcr.io/home-assistant/home-assistant:stable
|
$STD docker pull ghcr.io/home-assistant/home-assistant:stable
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ $STD apt install -y \
|
|||||||
rrdtool \
|
rrdtool \
|
||||||
snmp \
|
snmp \
|
||||||
snmpd \
|
snmpd \
|
||||||
whois
|
whois \
|
||||||
|
ipmitool
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Installing Python Dependencies"
|
msg_info "Installing Python Dependencies"
|
||||||
|
|||||||
+2
-60
@@ -4599,20 +4599,17 @@ setup_composer() {
|
|||||||
# - By default uses distro repository (docker.io) for stability
|
# - By default uses distro repository (docker.io) for stability
|
||||||
# - Optionally uses official Docker repository for latest features
|
# - Optionally uses official Docker repository for latest features
|
||||||
# - Detects and migrates old Docker installations
|
# - Detects and migrates old Docker installations
|
||||||
# - Optional: Installs/Updates Portainer CE
|
|
||||||
# - Updates running containers interactively
|
# - Updates running containers interactively
|
||||||
# - Cleans up legacy repository files
|
# - Cleans up legacy repository files
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# setup_docker # Uses official Docker repo (recommended)
|
# setup_docker # Uses official Docker repo (recommended)
|
||||||
# USE_DOCKER_REPO=false setup_docker # Uses distro docker.io package
|
# USE_DOCKER_REPO=false setup_docker # Uses distro docker.io package
|
||||||
# DOCKER_PORTAINER="true" setup_docker
|
|
||||||
# DOCKER_LOG_DRIVER="json-file" setup_docker
|
# DOCKER_LOG_DRIVER="json-file" setup_docker
|
||||||
#
|
#
|
||||||
# Variables:
|
# Variables:
|
||||||
# USE_DOCKER_REPO - Set to "false" to use distro docker.io package
|
# USE_DOCKER_REPO - Set to "false" to use distro docker.io package
|
||||||
# (default: true, uses official Docker repository)
|
# (default: true, uses official Docker repository)
|
||||||
# DOCKER_PORTAINER - Install Portainer CE (optional, "true" to enable)
|
|
||||||
# DOCKER_LOG_DRIVER - Log driver (optional, default: "journald")
|
# DOCKER_LOG_DRIVER - Log driver (optional, default: "journald")
|
||||||
# DOCKER_SKIP_UPDATES - Skip container update check (optional, "true" to skip)
|
# DOCKER_SKIP_UPDATES - Skip container update check (optional, "true" to skip)
|
||||||
#
|
#
|
||||||
@@ -4623,7 +4620,7 @@ setup_composer() {
|
|||||||
# - Interactive per-container update prompt (Y/N, 60 s auto-no)
|
# - Interactive per-container update prompt (Y/N, 60 s auto-no)
|
||||||
# - Compose-managed containers: full restart via docker compose
|
# - Compose-managed containers: full restart via docker compose
|
||||||
# - Standalone containers: image pull only, no destructive stop/rm
|
# - Standalone containers: image pull only, no destructive stop/rm
|
||||||
# - Portainer installation and update support
|
# - Portainer is no longer managed here; use tools/addon/portainer.sh
|
||||||
# - Set DOCKER_NONINTERACTIVE=1 to skip interactive prompts (CI/unattended)
|
# - Set DOCKER_NONINTERACTIVE=1 to skip interactive prompts (CI/unattended)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
_docker_is_noninteractive() {
|
_docker_is_noninteractive() {
|
||||||
@@ -4632,7 +4629,6 @@ _docker_is_noninteractive() {
|
|||||||
|
|
||||||
setup_docker() {
|
setup_docker() {
|
||||||
local docker_installed=false
|
local docker_installed=false
|
||||||
local portainer_installed=false
|
|
||||||
local USE_DOCKER_REPO="${USE_DOCKER_REPO:-true}"
|
local USE_DOCKER_REPO="${USE_DOCKER_REPO:-true}"
|
||||||
|
|
||||||
# Check if Docker is already installed
|
# Check if Docker is already installed
|
||||||
@@ -4642,12 +4638,6 @@ setup_docker() {
|
|||||||
msg_info "Docker $DOCKER_CURRENT_VERSION detected"
|
msg_info "Docker $DOCKER_CURRENT_VERSION detected"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if Portainer is running
|
|
||||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q '^portainer$'; then
|
|
||||||
portainer_installed=true
|
|
||||||
msg_info "Portainer container detected"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Scenario 1: Use distro repository (opt-out via USE_DOCKER_REPO=false)
|
# Scenario 1: Use distro repository (opt-out via USE_DOCKER_REPO=false)
|
||||||
if [[ "$USE_DOCKER_REPO" != "true" && "$USE_DOCKER_REPO" != "TRUE" && "$USE_DOCKER_REPO" != "1" ]]; then
|
if [[ "$USE_DOCKER_REPO" != "true" && "$USE_DOCKER_REPO" != "TRUE" && "$USE_DOCKER_REPO" != "1" ]]; then
|
||||||
|
|
||||||
@@ -4761,54 +4751,6 @@ EOF
|
|||||||
systemctl enable -q --now docker
|
systemctl enable -q --now docker
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Portainer Management (common for both modes)
|
|
||||||
if [[ "${DOCKER_PORTAINER:-}" == "true" ]]; then
|
|
||||||
if [ "$portainer_installed" = true ]; then
|
|
||||||
msg_info "Checking for Portainer updates"
|
|
||||||
PORTAINER_CURRENT=$(docker inspect portainer --format='{{.Config.Image}}' 2>/dev/null | cut -d':' -f2)
|
|
||||||
PORTAINER_LATEST=$(curl -fsSL https://registry.hub.docker.com/v2/repositories/portainer/portainer-ce/tags?page_size=100 | grep -oP '"name":"\K[0-9]+\.[0-9]+\.[0-9]+"' | head -1 | tr -d '"')
|
|
||||||
|
|
||||||
if [ "$PORTAINER_CURRENT" != "$PORTAINER_LATEST" ]; then
|
|
||||||
if _docker_is_noninteractive; then
|
|
||||||
msg_info "Skipping Portainer update prompt (non-interactive)"
|
|
||||||
else
|
|
||||||
read -r -p "${TAB3}Update Portainer $PORTAINER_CURRENT → $PORTAINER_LATEST? <y/N> " prompt
|
|
||||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_info "Updating Portainer"
|
|
||||||
docker stop portainer
|
|
||||||
docker rm portainer
|
|
||||||
docker pull portainer/portainer-ce:latest
|
|
||||||
docker run -d \
|
|
||||||
-p 9000:9000 \
|
|
||||||
-p 9443:9443 \
|
|
||||||
--name=portainer \
|
|
||||||
--restart=always \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v portainer_data:/data \
|
|
||||||
portainer/portainer-ce:latest
|
|
||||||
msg_ok "Updated Portainer to $PORTAINER_LATEST"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
msg_ok "Portainer is up-to-date ($PORTAINER_CURRENT)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
msg_info "Installing Portainer"
|
|
||||||
docker volume create portainer_data
|
|
||||||
docker run -d \
|
|
||||||
-p 9000:9000 \
|
|
||||||
-p 9443:9443 \
|
|
||||||
--name=portainer \
|
|
||||||
--restart=always \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v portainer_data:/data \
|
|
||||||
portainer/portainer-ce:latest
|
|
||||||
|
|
||||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
|
||||||
msg_ok "Installed Portainer (http://${LOCAL_IP}:9000)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Container Update Check
|
# Container Update Check
|
||||||
# - Skipped entirely when running unattended / non-interactive
|
# - Skipped entirely when running unattended / non-interactive
|
||||||
# - Compose-managed containers: offered via Y/N → docker compose pull + up -d
|
# - Compose-managed containers: offered via Y/N → docker compose pull + up -d
|
||||||
@@ -4824,7 +4766,7 @@ EOF
|
|||||||
name=$(echo "$line" | awk '{print $1}')
|
name=$(echo "$line" | awk '{print $1}')
|
||||||
image=$(echo "$line" | awk '{print $2}')
|
image=$(echo "$line" | awk '{print $2}')
|
||||||
|
|
||||||
# Portainer containers are handled by the dedicated block above
|
# Portainer is managed by its own addon script, not this generic loop
|
||||||
[[ "$name" == "portainer" || "$name" == "portainer_agent" ]] && continue
|
[[ "$name" == "portainer" || "$name" == "portainer_agent" ]] && continue
|
||||||
|
|
||||||
current_digest=$(docker inspect "$name" --format='{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
|
current_digest=$(docker inspect "$name" --format='{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
|
||||||
|
|||||||
@@ -0,0 +1,190 @@
|
|||||||
|
#!/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://github.com/portainer/portainer
|
||||||
|
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
|
||||||
|
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
|
||||||
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "portainer" "addon"
|
||||||
|
|
||||||
|
# Enable error handling
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler' ERR
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# CONFIGURATION
|
||||||
|
# ==============================================================================
|
||||||
|
APP="Portainer"
|
||||||
|
APP_TYPE="addon"
|
||||||
|
INSTALL_PATH="/opt/portainer"
|
||||||
|
COMPOSE_FILE="${INSTALL_PATH}/compose.yaml"
|
||||||
|
DEFAULT_PORT=9443
|
||||||
|
|
||||||
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
|
load_functions
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# UNINSTALL
|
||||||
|
# ==============================================================================
|
||||||
|
function uninstall() {
|
||||||
|
msg_info "Uninstalling ${APP}"
|
||||||
|
|
||||||
|
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||||
|
msg_info "Stopping and removing Docker containers"
|
||||||
|
cd "$INSTALL_PATH"
|
||||||
|
$STD docker compose down --volumes --remove-orphans
|
||||||
|
msg_ok "Stopped and removed Docker containers"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "$INSTALL_PATH"
|
||||||
|
rm -f "/usr/local/bin/update_portainer"
|
||||||
|
msg_ok "${APP} has been uninstalled"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# UPDATE
|
||||||
|
# ==============================================================================
|
||||||
|
function update() {
|
||||||
|
msg_info "Pulling latest ${APP} image"
|
||||||
|
cd "$INSTALL_PATH"
|
||||||
|
$STD docker compose pull
|
||||||
|
msg_ok "Pulled latest image"
|
||||||
|
|
||||||
|
msg_info "Restarting ${APP}"
|
||||||
|
$STD docker compose up -d --remove-orphans
|
||||||
|
msg_ok "Restarted ${APP}"
|
||||||
|
|
||||||
|
msg_ok "Updated successfully"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# CHECK DOCKER
|
||||||
|
# ==============================================================================
|
||||||
|
function check_docker() {
|
||||||
|
if ! command -v docker &>/dev/null; then
|
||||||
|
msg_error "Docker is not installed. This script requires an existing Docker LXC. Exiting."
|
||||||
|
exit 10
|
||||||
|
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 10
|
||||||
|
fi
|
||||||
|
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# CHECK EXISTING CONTAINER
|
||||||
|
# ==============================================================================
|
||||||
|
function check_existing_container() {
|
||||||
|
# Guards against clobbering a Portainer container not managed by this addon
|
||||||
|
# (e.g. Business/Enterprise Edition installed manually or via the legacy docker.sh flow)
|
||||||
|
if docker ps -a --format '{{.Names}}' | grep -q '^portainer$'; then
|
||||||
|
msg_error "A container named 'portainer' already exists but is not managed by this addon."
|
||||||
|
msg_error "This may be a Portainer Business/Enterprise Edition install or a manual setup."
|
||||||
|
msg_error "Remove/rename that container first, or manage it manually. Exiting."
|
||||||
|
exit 10
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# INSTALL
|
||||||
|
# ==============================================================================
|
||||||
|
function install() {
|
||||||
|
check_docker
|
||||||
|
check_existing_container
|
||||||
|
|
||||||
|
msg_info "Creating install directory"
|
||||||
|
mkdir -p "$INSTALL_PATH"
|
||||||
|
msg_ok "Created ${INSTALL_PATH}"
|
||||||
|
|
||||||
|
msg_info "Downloading Docker Compose file"
|
||||||
|
curl -fsSL "https://downloads.portainer.io/ce-sts/portainer-compose.yaml" -o "$COMPOSE_FILE"
|
||||||
|
msg_ok "Downloaded Docker Compose file"
|
||||||
|
|
||||||
|
msg_info "Starting ${APP}"
|
||||||
|
cd "$INSTALL_PATH"
|
||||||
|
$STD docker compose up -d
|
||||||
|
msg_ok "Started ${APP}"
|
||||||
|
|
||||||
|
# Create update script
|
||||||
|
msg_info "Creating update script"
|
||||||
|
cat <<'UPDATEEOF' >/usr/local/bin/update_portainer
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Portainer Update Script
|
||||||
|
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)"
|
||||||
|
UPDATEEOF
|
||||||
|
chmod +x /usr/local/bin/update_portainer
|
||||||
|
msg_ok "Created update script (/usr/local/bin/update_portainer)"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
msg_ok "${APP} is reachable at: ${BL}https://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
||||||
|
echo ""
|
||||||
|
msg_warn "On first access, you'll be prompted to create an admin account."
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# MAIN
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
# Handle type=update (called from update script)
|
||||||
|
if [[ "${type:-}" == "update" ]]; then
|
||||||
|
header_info
|
||||||
|
if [[ -f "$COMPOSE_FILE" ]]; then
|
||||||
|
update
|
||||||
|
else
|
||||||
|
msg_error "${APP} is not installed. Nothing to update."
|
||||||
|
exit 233
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
header_info
|
||||||
|
get_lxc_ip
|
||||||
|
|
||||||
|
# Check if already installed
|
||||||
|
if [[ -f "$COMPOSE_FILE" ]]; 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} - Portainer (via Docker Compose)"
|
||||||
|
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
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
____ __ _
|
||||||
|
/ __ \____ _____/ /_____ _(_)___ ___ _____
|
||||||
|
/ /_/ / __ \/ ___/ __/ __ `/ / __ \/ _ \/ ___/
|
||||||
|
/ ____/ /_/ / / / /_/ /_/ / / / / / __/ /
|
||||||
|
/_/ \____/_/ \__/\__,_/_/_/ /_/\___/_/
|
||||||
|
|
||||||
Reference in New Issue
Block a user