| Server IP : 104.129.129.72 / Your IP : 216.73.216.229 Web Server : LiteSpeed System : Linux 123answers 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64 User : answe8064 ( 1002) PHP Version : 8.2.28 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /opt/installer/apps/ |
Upload File : |
#!/bin/bash
if [ -f "include/startup.sh" ]; then
. include/startup.sh
elif [ -f "../include/startup.sh" ]; then
. ../include/startup.sh
fi
DOMAIN="${CWM_DOMAIN}"
IP_ADDR="$(awk '{for (i=1;i<=NF;i++) if ($i ~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) {sub(/.*=/, "", $i); print $i}}' ~/guest.conf)"
EMAIL_ADDR="$(awk -F= '/email=/{print $2}' ~/guest.conf)"
CERT_DIR="/opt/certs"
ADMIN_PASSWORD="${ADMINPASSWORD}"
OFFLINE_APP_URL="https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz"
ONLINE_APP_URL="https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-online-installer-v2.11.1.tgz"
INSTALL_TYPE="online"
declare -a REMOVE_PACKAGES=("docker.io" "docker-doc" "docker-compose" "docker-compose-v2" "podman-docker" "containerd" "runc")
declare -a INSTALL_PACKAGES=("ca-certificates" "certbot" "curl" "ufw")
pre_install() {
echo "Removing possible conflicting packages..." | log
for pkg in "${REMOVE_PACKAGES[@]}"; do
apt remove "$pkg" -y &> /dev/null || echo "Failed to remove $pkg" | log
done
echo "Updating packages..." | log
apt update &> /dev/null
echo "Installing ca-certificates curl ufw..." | log
apt install -y "${INSTALL_PACKAGES[@]}" &> /dev/null
echo "Opening ports for Harbor..." | log
ufw allow 80/tcp &> /dev/null
ufw allow 443/tcp &> /dev/null
ufw allow 4443/tcp &> /dev/null
ufw allow ssh &> /dev/null
echo "Enabling UFW..." | log
echo "y" | ufw enable &> /dev/null
ufw status
}
install_docker() {
echo "Adding GPG Key..."
install -m 0755 -d /etc/apt/keyrings &> /dev/null
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc &> /dev/null
chmod a+r /etc/apt/keyrings/docker.asc &> /dev/null
echo "Adding repository..."
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update &> /dev/null
echo "Installing Docker-CE & Compose..."
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin &> /dev/null
docker -v
}
generate_certs() {
if [[ ! -d $CERT_DIR ]]; then
mkdir -p $CERT_DIR
echo "Created Cert directory: ${CERT_DIR}" | log
fi
if ! command -v certbot &> /dev/null; then
echo "Certbot not found. Installing Certbot..." | log
sudo apt-get update
sudo apt-get install -y certbot
fi
echo "Obtaining Let's Encrypt certificate for ${DOMAIN}..." | log
if systemctl is-active --quiet nginx; then
sudo systemctl stop nginx
NGINX_STOPPED=true
fi
if systemctl is-active --quiet apache2; then
sudo systemctl stop apache2
APACHE_STOPPED=true
fi
echo "DEBUG: Email: ${EMAIL_ADDR}" | log
sudo certbot certonly --standalone -d "${DOMAIN}" \
--non-interactive --agree-tos --email "${EMAIL_ADDR}"
if [ "$NGINX_STOPPED" = true ]; then
sudo systemctl start nginx
fi
if [ "$APACHE_STOPPED" = true ]; then
sudo systemctl start apache2
fi
echo "Copying certificates to ${CERT_DIR}..." | log
CERTBOT_LIVE_DIR="/etc/letsencrypt/live/${DOMAIN}"
sudo cp "${CERTBOT_LIVE_DIR}/fullchain.pem" "${CERT_DIR}"
sudo cp "${CERTBOT_LIVE_DIR}/privkey.pem" "${CERT_DIR}"
sudo chown $(whoami):$(whoami) "${CERT_DIR}"
echo "Creating SAN file..." | log
cat > "$CERT_DIR/v3.ext" <<-EOF
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${DOMAIN}
IP.1 = ${IP_ADDR}
EOF
echo "Certificate generation complete!" | log
}
configure_harbor() {
echo "Configuring harbor YML file..."
cp /opt/harbor/harbor.yml.tmpl /opt/harbor/harbor.yml &> /dev/null
sed -i "s/^hostname:.*/hostname: ${DOMAIN}/" /opt/harbor/harbor.yml &> /dev/null
sed -i "s|^\([ \t]*\)certificate:.*|\1certificate: ${CERT_DIR}/fullchain.pem|" /opt/harbor/harbor.yml &> /dev/null
sed -i "s|^\([ \t]*\)private_key:.*|\1private_key: ${CERT_DIR}/privkey.pem|" /opt/harbor/harbor.yml &> /dev/null
sed -i "s/^harbor_admin_password:.*/harbor_admin_password: ${ADMIN_PASSWORD}/" /opt/harbor/harbor.yml &> /dev/null
sed -i "s/^\([ \t]*\)password:.*/\1password: ${ADMIN_PASSWORD}/" /opt/harbor/harbor.yml &> /dev/null
}
download_and_extract() {
local url=$1
local filename=$(basename "$url")
echo "Downloading $filename..."
if curl -L -O "$url"; then
echo "$filename downloaded successfully."
else
echo "Failed to download $filename. Exiting."
exit 1
fi
echo "Extracting $filename..."
if tar xzvf "$filename" &> /dev/null; then
echo "$filename extracted successfully."
else
echo "Failed to extract $filename. Exiting."
exit 1
fi
echo "Removing tar file..."
if rm "$filename" &> /dev/null; then
echo "Tar file removed successfully."
else
echo "Failed to remove $filename."
fi
}
install_harbor() {
if [ "$INSTALL_TYPE" = "offline" ]; then
download_and_extract "$OFFLINE_APP_URL"
elif [ "$INSTALL_TYPE" = "online" ]; then
download_and_extract "$ONLINE_APP_URL"
else
echo "Invalid INSTALL_TYPE. Please specify 'offline' or 'online'. Exiting."
exit 1
fi
}
prepare_harbor() {
echo "Running harbor prep phase..."
bash /opt/harbor/prepare
}
finalize_harbor_installation() {
timeout=120
interval=10
elapsed=0
cd /opt/harbor
echo "Running harbor install phase..." | log
/usr/bin/bash /opt/harbor/install.sh | while IFS= read -r line; do
echo "$line" | log
if [[ "$line" == *"Clean up the input dir"* ]]; then
echo "Stopping & Removing Apache2..." | log
systemctl stop apache2
apt-get purge apache2 apache2-utils apache2-bin apache2.2-common
rm -rf /etc/apache2
apt-get autoremove -y
apt-get autoclean -y
return 0
echo "Starting container status check in $interval seconds..." | log
sleep $interval
while (( elapsed < timeout )); do
exited_containers=$(/usr/bin/docker ps -a --filter 'status=exited' -q)
if [ -n "$exited_containers" ]; then
echo "Some containers have exited. Container IDs: ${exited_containers}" | log
echo "Attempting to restart exited containers..." | log
/usr/bin/docker compose up -d
sleep $interval
elapsed=$((elapsed + interval))
else
echo "No exited containers found. Checking other container statuses..." | log
other_containers=$(/usr/bin/docker ps -a --filter 'health=unhealthy' --filter 'status=created' -q)
if [ -n "$other_containers" ]; then
restarting=$(/usr/bin/docker ps -a --filter 'status=restarting' -q)
if [ ! -n "$restarting" ]; then
echo "Found problematic containers. Container IDs: ${other_containers}" | log
elapsed=0
sleep 5
/usr/bin/docker compose up -d
sleep $interval
elapsed=$((elapsed + interval))
fi
else
echo "Checking if there are ANY containers at all..." | log
total_containers=$(/usr/bin/docker ps -a -q)
if [ -z "$total_containers" ]; then
echo "No containers found. Deploying..." | log
/usr/bin/docker compose up -d
sleep 10
fi
fi
fi
done
echo "Timeout reached." | log
fi
done
echo "Adding Docker Compose cron job to root's crontab for Ubuntu 24...\n" | log
CRON_JOB="@reboot (cd /opt/harbor && /usr/bin/docker compose up -d)"
(crontab -l 2>/dev/null | grep -F "$CRON_JOB") || (crontab -l 2>/dev/null; echo "$CRON_JOB") | sudo crontab -
echo "Docker Compose cron job added successfully. It will run on next reboot.\n" | log
}
main() {
lines=()
done_lines=()
mark_previous_done() {
for (( i=0; i<${#lines[@]}; i++ )); do
if [[ ! " ${done_lines[@]} " =~ " ${lines[$i]} " ]]; then # Check if the line is not already marked as [DONE]
lines[$i]="${lines[$i]} [DONE]"
done_lines+=("${lines[$i]}") # Add to done_lines to prevent duplicate updates
fi
done
}
display_all_lines() {
"$update_status" "$HTML_PATH" -cp
for line in "${lines[@]}"; do
"$update_status" "$HTML_PATH" -ap "$line"
done
}
update_status="$rootDir/include/updateInstallStatus.sh"
HTML_PATH="/var/www/html/index.html"
lines+=("Getting Ready...")
"$update_status" "$HTML_PATH" -cp
display_all_lines
pre_install
mark_previous_done
lines+=("Installing Docker-CE & Docker-Compose...")
display_all_lines
echo "Installing Docker-CE & Docker-Compose..." | log
install_docker
echo "Switching to /opt..."
cd /opt
echo "Restarting docker..."
systemctl restart docker
mark_previous_done
lines+=("Downloading Harbor 2.11.1...")
display_all_lines
echo "Downloading Harbor 2.11.1..." | log
install_harbor
mark_previous_done
lines+=("Generating certificates...")
display_all_lines
echo "Generating certificates..." | log
generate_certs
mark_previous_done
lines+=("Configuring Harbor 2.11.1...")
display_all_lines
echo "Configuring Harbor 2.11.1..." | log
configure_harbor
mark_previous_done
lines+=("Preparing Harbor 2.11.1...")
display_all_lines
"$update_status" "$HTML_PATH" -ur "You will be re-directed when the installation is complete. if not, please refresh the page every few seconds."
"$update_status" "$HTML_PATH" -sr
echo "Preparing Harbor 2.11.1..." | log
prepare_harbor
mark_previous_done
lines+=("Finalizing Harbor 2.11.1 installation...")
display_all_lines
"$update_status" "$HTML_PATH" -ur "You will be re-directed when the installation is complete. if not, please refresh the page every few seconds."
"$update_status" "$HTML_PATH" -sr
echo "Finalizing Harbor 2.11.1 installation..." | log
finalize_harbor_installation
echo "Install script completed successfully!"
descriptionAppend "Harbor Web UI: https://${CWM_DOMAIN}"
descriptionAppend "Harbor Username: admin"
descriptionAppend "Harbor Password: ${ADMINPASSWORD}"
tag Script.success
exit 0
}
main