Docker & Portainer Update

Overview

For any new Helmut4 installation, the latest versions of Docker and Portainer CE (community version) will always be downloaded and installed.

For more information, please refer to the Helmut4 Server documentation.

Updates

Subsequent updates or upgrades of Docker and Portainer are the responsibility of the customer or hosting support. Helmut4 updates do not manage the current versions of Docker and Portainer.

When performing updates, please review the specific release notes for Docker and Portainer to ensure compatibility. It's important to test updates first in a staging environment before applying them to the production environment.

For more information, refer to:

Portainer Update

With the release of Docker v26, Portainer has introduced a new release principle for its product: https://www.portainer.io/blog/2024-release-principle

  • LTS (Long-Term Support) versions can be identified by the tag :lts

  • STS (Short-Term Support) versions can be identified by the tag :sts

Remove and re-deploy latest Portainer CE

Please use the provided script with caution, as Portainer is not within Helmut4's scope / support.

#!/bin/bash

# Update Portainer to the latest community edition

# moovIT GmbH - B. Dimmel

# Version 3.0
# Changelog: Jan 31st 2025
# Update Portainer from v1.x to 2.x
# Can also be used to update 2.x to a newer version
# Get container ID by 'names', making it more dynamically
# Add option to pick LTS or new STS Short-Term version
# changed tag latest to lts
# fixed syntax error in docker pull command
# added check if script is run with sudo permissions
# added check if the existing container is CE or EE
# Improved error handling
# Refactored deployment process
# Refactored the stopping and purging of deprecated Portainer images + containers

# Check if the script is run with sudo permissions
if [ "$EUID" -ne 0 ]; then
    echo "Please run this script as root (e.g., 'sudo ./script.sh')"
    exit 1
fi

portainerTargetCode="ce"
portainerTargetName="Community Edition"
portainerWrongCode="ee"
portainerWrongName="Business Edition"

# Find the running container ID for Portainer
container_id=$(docker ps --filter "name=portainer" --format "{{.ID}}")

# If no running Portainer container is found, notify and continue
if [[ -z "$container_id" ]]; then
    echo "No running Portainer container found. Skipping version check."
else
    # Get the image name of the existing container
    existing_image=$(docker inspect --format='{{.Config.Image}}' "$container_id")
    echo -e "\nFound running Portainer container using image: $existing_image"

    # Check if it's an EE version
    if [[ "$existing_image" == *"portainer-$portainerWrongCode"* ]]; then
        echo -e "\n!!!!!!!!!!!!\nYou are trying to replace portainer $portainerWrongCode ($portainerWrongName) with $portainerTargetCode ($portainerTargetName)\n\nExiting.\n\n"
        exit 1
    fi
fi

# Prompt user for LTS, STS, or quit option
while true; do
    echo -e "\nDo you want to update to the latest LTS (Long-Term) or STS (Short-Term Support) version?\n"
    read -p "Enter 'lts', 'sts', or 'quit': " version_choice

    case "$version_choice" in
        lts)
            docker_tag="portainer/portainer-$portainerTargetCode:lts"
            break
            ;;
        sts)
            docker_tag="portainer/portainer-$portainerTargetCode:sts"
            break
            ;;
        quit)
            echo -e "Portainer update aborted!\n"
            exit 0
            ;;
        *)
            echo -e "Invalid choice!\nPlease enter 'lts', 'sts', or 'quit'.\n"
            ;;
    esac
done

# Confirm before proceeding
while true; do
    echo -e "\n==> You have chosen: $version_choice <==\n"
    read -p "Proceed with this version? (y/n): " confirm_choice

    case "$confirm_choice" in
        [yY]) break ;;
        [nN])
            echo -e "Please choose again.\n"
            continue
            ;;
        *) echo "Invalid input. Please enter 'y' or 'n'." ;;
    esac
done

# Stop and remove all existing Portainer containers
portainer_containers=$(docker ps -a --filter "name=portainer" --format "{{.ID}}")

if [[ -n "$portainer_containers" ]]; then
    echo -e "\nFound the following Portainer containers: $portainer_containers"

    # Stop all running Portainer containers
    echo -e "\nStopping all running Portainer containers ...\n"
    for container_id in $portainer_containers; do
        if docker ps --filter "id=$container_id" --format "{{.ID}}" | grep -q .; then
            if docker stop "$container_id" >/dev/null 2>&1; then
                echo "Stopped Portainer container: $container_id"
            else
                echo "Failed to stop Portainer container: $container_id. Continuing ..."
            fi
        fi
    done

    # Remove all Portainer containers
    echo -e "\nRemoving all Portainer containers ..."
    for container_id in $portainer_containers; do
        if docker ps -a --filter "id=$container_id" --format "{{.ID}}" | grep -q .; then
            if docker rm "$container_id" >/dev/null 2>&1; then
                echo -e "\nRemoved Portainer container: $container_id"
            else
                echo -e "\nFailed to remove Portainer container: $container_id. Exiting."
                exit 1
            fi
        fi
    done
else
    echo -e "\nNo existing Portainer containers found. Proceeding with deployment."
fi

# Ensure no stopped Portainer containers remain before deployment
if docker ps -a --filter "name=portainer" --format "{{.ID}}" | grep -q .; then
    echo -e "\nForce removing any remaining Portainer containers ..."
    docker rm -f $(docker ps -a --filter "name=portainer" --format "{{.ID}}")
fi

# Find and remove all Portainer images
echo -e "\nSearching for all Portainer images to remove ..."
portainer_images=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "portainer/portainer(-$portainerTargetCode)?" || true)

if [[ -n "$portainer_images" ]]; then
    echo -e "\nRemoving the following Portainer images: $portainer_images"
    
    while IFS= read -r image; do
        if [[ -n "$image" ]]; then
            echo -e "\nRemoving image: $image"
            if docker rmi -f "$image" >/dev/null 2>&1; then
                echo -e "\nRemoved Portainer image: $image"
            else
                echo -e "\nFailed to remove Portainer image: $image. Continuing ..."
            fi
        fi
    done <<< "$portainer_images"
else
    echo -e "\nNo Portainer images found to remove."
fi

# Pull the latest Portainer Community Edition image
echo -e "\nPulling the specified Portainer-$portainerTargetCode image: $docker_tag ..."
if docker pull --quiet "$docker_tag" >/dev/null 2>&1; then
    echo -e "\nLatest Portainer-$portainerTargetCode image pulled successfully."
else
    echo -e "\nFailed to pull the latest Portainer-$portainerTargetCode image. Exiting."
    exit 1
fi

# Deploy the new Portainer container
echo -e "\nDeploying the new Portainer-$portainerTargetCode container ..."
if docker run -it -d --restart=always -p 9000:9000 --name=portainer -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data "$docker_tag">/dev/null 2>&1; then
    echo -e "\n\n => Portainer $portainerTargetName has been successfully deployed. <=\n\n"
else
    echo -e "\nFailed to deploy Portainer $portainerTargetName. Exiting.\n"
    exit 1
fi

Docker Update

To update the Docker environment or engine, please refer to the documentation provided by your host operating system manufacturer, such as Ubuntu.

The update commands can vary depending on the distribution running on your server.

For guidance, you can consult the official Docker installation guide specific to Ubuntu: https://docs.docker.com/engine/install/ubuntu

Update Docker on Ubuntu / Debian
sudo apt update
sudo apt upgrade docker-ce
Update Docker on RHEL
sudo yum check-update
sudo yum update docker-ce

Last updated