harbor offline shell 수정

진웅·2025년 8월 19일

네, Podman + docker-compose 환경에 맞게 세 파일을 수정해드리겠습니다.

🐳 현재 환경 정리

  • ✅ Podman 실행 중
  • ✅ docker-compose → podman 소켓 연동
  • ❌ Docker 미설치
  • 🎯 Harbor를 Podman 환경에서 실행

📁 파일 1: prepare (수정버전)

cd /opt/harbor
cp prepare prepare.original

cat > prepare << 'EOF'
#!/bin/bash
set -e

# If compiling source code this dir is harbor's make dir.
# If installing harbor via package, this dir is harbor's root dir.
if [[ -n "$HARBOR_BUNDLE_DIR" ]]; then
    harbor_prepare_path=$HARBOR_BUNDLE_DIR
else
    harbor_prepare_path="$( cd "$(dirname "$0")" ; pwd -P )"
fi
echo "prepare base dir is set to ${harbor_prepare_path}"

# Clean up input dir
rm -rf ${harbor_prepare_path}/input
# Create a input dirs
mkdir -p ${harbor_prepare_path}/input
input_dir=${harbor_prepare_path}/input

# Copy harbor.yml to input dir
if [[ ! "$1" =~ ^\-\- ]] && [ -f "$1" ]
then
    cp $1 $input_dir/harbor.yml
    shift
else
    if [ -f "${harbor_prepare_path}/harbor.yml" ];then
        cp ${harbor_prepare_path}/harbor.yml $input_dir/harbor.yml
    else
        echo "no config file: ${harbor_prepare_path}/harbor.yml"
        exit 1
    fi
fi

data_path=$(grep '^[^#]*data_volume:' $input_dir/harbor.yml | awk '{print $NF}')

# If previous secretkeys exist, move it to new location
previous_secretkey_path=/data/secretkey
previous_defaultalias_path=/data/defaultalias

if [ -f $previous_secretkey_path ]; then
    mkdir -p $data_path/secret/keys
    mv $previous_secretkey_path $data_path/secret/keys
fi
if [ -f $previous_defaultalias_path ]; then
    mkdir -p $data_path/secret/keys
    mv $previous_defaultalias_path $data_path/secret/keys
fi

# Create secret dir
secret_dir=${data_path}/secret
config_dir=$harbor_prepare_path/common/config

# 🔧 PODMAN FIX: Create common/config directory
echo "Creating config directory: $config_dir"
mkdir -p $config_dir

# 🔧 PODMAN FIX: Use harbor_prepare_path instead of / for security
prepare_base_dir=$harbor_prepare_path
if [ "$(uname)" == "Darwin" ]; then
    prepare_base_dir=$HOME
fi

echo "Using prepare_base_dir: $prepare_base_dir"

# 🔧 PODMAN FIX: Check if using podman or docker
CONTAINER_ENGINE="docker"
if command -v podman >/dev/null 2>&1 && ! command -v docker >/dev/null 2>&1; then
    CONTAINER_ENGINE="podman"
    echo "Using Podman as container engine"
elif command -v docker >/dev/null 2>&1; then
    echo "Using Docker as container engine"
else
    echo "Neither Docker nor Podman found!"
    exit 1
fi

# Run prepare script
$CONTAINER_ENGINE run --rm -v $input_dir:/input \
                    -v $data_path:/data \
                    -v $harbor_prepare_path:/compose_location \
                    -v $config_dir:/config \
                    -v ${prepare_base_dir}:/hostfs \
                    --privileged \
                    goharbor/prepare:v2.13.2 prepare $@

echo "Clean up the input dir"
# Clean up input dir
rm -rf ${harbor_prepare_path}/input
EOF

chmod +x prepare

📁 파일 2: install.sh (Podman 환경 수정버전)

cp install.sh install.sh.original

cat > install.sh << 'EOF'
#!/bin/bash

set -e

DIR="$(cd "$(dirname "$0")" && pwd)"
source $DIR/common.sh

set +o noglob

usage=$'Please set hostname and other necessary attributes in harbor.yml first. DO NOT use localhost or 127.0.0.1 for hostname, because Harbor needs to be accessed by external clients.
Please set --with-trivy if needs enable Trivy in Harbor.
Please do NOT set --with-chartmuseum, as chartmusuem has been deprecated and removed.
Please do NOT set --with-notary, as notary has been deprecated and removed.'
item=0

# clair is deprecated
with_clair=$false
# trivy is not enabled by default
with_trivy=$false

# flag to using docker compose v1 or v2, default would using v1 docker-compose
DOCKER_COMPOSE=docker-compose

while [ $# -gt 0 ]; do
        case $1 in
            --help)
            note "$usage"
            exit 0;;
            --with-trivy)
            with_trivy=true;;
            *)
            note "$usage"
            exit 1;;
        esac
        shift || true
done

workdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $workdir

# 🔧 PODMAN FIX: Check container engine and compose
h2 "[Step $item]: checking container engine (Docker/Podman) ..."; let item+=1
check_container_engine

h2 "[Step $item]: checking docker-compose is installed ..."; let item+=1
check_dockercompose

# 🔧 PODMAN FIX: Load images using detected container engine
if [ -f harbor*.tar.gz ]
then
    h2 "[Step $item]: loading Harbor images ..."; let item+=1
    $CONTAINER_ENGINE load -i ./harbor*.tar.gz
fi
echo ""

h2 "[Step $item]: preparing environment ...";  let item+=1
if [ -n "$host" ]
then
    sed "s/^hostname: .*/hostname: $host/g" -i ./harbor.yml
fi

h2 "[Step $item]: preparing harbor configs ...";  let item+=1
prepare_para=
if [ $with_trivy ]
then
    prepare_para="${prepare_para} --with-trivy"
fi

# 🔧 PODMAN FIX: Run prepare and check for errors
echo "Running prepare with parameters: $prepare_para"
if ! ./prepare $prepare_para; then
    error "prepare script failed!"
    exit 1
fi

# 🔧 PODMAN FIX: Verify common/config was created
if [ ! -d "./common/config" ]; then
    error "common/config directory was not created by prepare script!"
    exit 1
fi

echo ""

# 🔧 PODMAN FIX: Check existing Harbor instance properly
harbor_running=$($DOCKER_COMPOSE ps -q 2>/dev/null || echo "")
if [ -n "$harbor_running" ]; then
    note "stopping existing Harbor instance ..." 
    $DOCKER_COMPOSE down -v
fi
echo ""

h2 "[Step $item]: starting Harbor ..."
if ! $DOCKER_COMPOSE up -d; then
    error "Failed to start Harbor containers!"
    echo "Debug: Check Podman socket connection:"
    echo "DOCKER_HOST: $DOCKER_HOST"
    echo "Container engine: $CONTAINER_ENGINE"
    exit 1
fi

success $"----Harbor has been installed and started successfully.----"
success $"Harbor Portal: http://$(grep '^[^#]*hostname:' harbor.yml | awk '{print $2}')"
success $"Default admin user: admin"
success $"Check status: $DOCKER_COMPOSE ps"
EOF

chmod +x install.sh

📁 파일 3: common.sh (Podman 지원 수정버전)

cp common.sh common.sh.original

cat > common.sh << 'EOF'
#!/bin/bash
#docker version: 20.10.10+ or podman version: 3.0+
#docker-compose version: 1.18.0+
#golang version: 1.12.0+

set +e
set -o noglob

#
# Set Colors
#

bold=$(tput bold)
underline=$(tput sgr 0 1)
reset=$(tput sgr0)

red=$(tput setaf 1)
green=$(tput setaf 76)
white=$(tput setaf 7)
tan=$(tput setaf 202)
blue=$(tput setaf 25)

#
# Headers and Logging
#

underline() { printf "${underline}${bold}%s${reset}\n" "$@"
}
h1() { printf "\n${underline}${bold}${blue}%s${reset}\n" "$@"
}
h2() { printf "\n${underline}${bold}${white}%s${reset}\n" "$@"
}
debug() { printf "${white}%s${reset}\n" "$@"
}
info() { printf "${white}➜ %s${reset}\n" "$@"
}
success() { printf "${green}✓ %s${reset}\n" "$@"
}
error() { printf "${red}✖ %s${reset}\n" "$@"
}
warn() { printf "${tan}➜ %s${reset}\n" "$@"
}
bold() { printf "${bold}%s${reset}\n" "$@"
}
note() { printf "\n${underline}${bold}${blue}Note:${reset} ${blue}%s${reset}\n" "$@"
}

set -e

function check_golang {
	if ! go version &> /dev/null
	then
		warn "No golang package in your environment. You should use golang docker image build binary."
		return
	fi

	# golang has been installed and check its version
	if [[ $(go version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]
	then
		golang_version=${BASH_REMATCH[1]}
		golang_version_part1=${BASH_REMATCH[2]}
		golang_version_part2=${BASH_REMATCH[3]}

		# the version of golang does not meet the requirement
		if [ "$golang_version_part1" -lt 1 ] || ([ "$golang_version_part1" -eq 1 ] && [ "$golang_version_part2" -lt 12 ])
		then
			warn "Better to upgrade golang package to 1.12.0+ or use golang docker image build binary."
			return
		else
			note "golang version: $golang_version"
		fi
	else
		warn "Failed to parse golang version."
		return
	fi
}

# 🔧 PODMAN FIX: New function to detect container engine
function check_container_engine {
	CONTAINER_ENGINE=""
	
	# Check for Podman first (since user specified Podman environment)
	if command -v podman &> /dev/null; then
		if [[ $(podman --version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]; then
			podman_version=${BASH_REMATCH[1]}
			podman_version_part1=${BASH_REMATCH[2]}
			
			note "podman version: $podman_version"
			if [ "$podman_version_part1" -lt 3 ]; then
				warn "Podman version 3.0+ recommended for better docker-compose compatibility."
			fi
			CONTAINER_ENGINE="podman"
			export CONTAINER_ENGINE
			return 0
		fi
	fi
	
	# Check for Docker as fallback
	if command -v docker &> /dev/null; then
		if [[ $(docker --version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]; then
			docker_version=${BASH_REMATCH[1]}
			docker_version_part1=${BASH_REMATCH[2]}
			docker_version_part2=${BASH_REMATCH[3]}

			note "docker version: $docker_version"
			if [ "$docker_version_part1" -lt 17 ] || ([ "$docker_version_part1" -eq 17 ] && [ "$docker_version_part2" -lt 6 ]); then
				error "Need to upgrade docker package to 20.10.10+."
				exit 1
			fi
			CONTAINER_ENGINE="docker"
			export CONTAINER_ENGINE
			return 0
		fi
	fi
	
	error "Need to install either Docker (20.10.10+) or Podman (3.0+) first and run this script again."
	exit 1
}

function check_docker {
	# Legacy function - redirect to container engine check
	check_container_engine
}

# 🔧 PODMAN FIX: Improved docker-compose check with Podman support
function check_dockercompose {
	# Check DOCKER_HOST for Podman socket
	if [[ -n "$DOCKER_HOST" ]]; then
		note "Using DOCKER_HOST: $DOCKER_HOST"
	fi
	
	# Check for docker compose plugin first
	if docker compose version &> /dev/null 2>&1; then
		note "$(docker compose version)"
		DOCKER_COMPOSE="docker compose"
		export DOCKER_COMPOSE
		return 0
	fi

	# Check for standalone docker-compose
	if docker-compose --version &> /dev/null 2>&1; then
		if [[ $(docker-compose --version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]; then
			docker_compose_version=${BASH_REMATCH[1]}
			docker_compose_version_part1=${BASH_REMATCH[2]}
			docker_compose_version_part2=${BASH_REMATCH[3]}

			note "docker-compose version: $docker_compose_version"
			# the version of docker-compose does not meet the requirement
			if [ "$docker_compose_version_part1" -lt 1 ] || ([ "$docker_compose_version_part1" -eq 1 ] && [ "$docker_compose_version_part2" -lt 18 ]); then
				error "Need to upgrade docker-compose package to 1.18.0+."
				exit 1
			fi
			DOCKER_COMPOSE="docker-compose"
			export DOCKER_COMPOSE
			return 0
		else
			error "Failed to parse docker-compose version."
			exit 1
		fi
	fi

	error "Need to install docker-compose(1.18.0+) or docker-compose-plugin first and run this script again."
	error "For Podman setup, ensure DOCKER_HOST is set to Podman socket:"
	error "export DOCKER_HOST=unix:///run/user/\$UID/podman/podman.sock"
	exit 1
}
EOF

🚀 Podman 환경 설정 확인 및 실행

1단계: Podman 소켓 확인

# Podman 소켓이 실행 중인지 확인
systemctl --user status podman.socket

# DOCKER_HOST 환경변수 확인
echo $DOCKER_HOST

# 만약 설정되지 않았다면
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock

# docker-compose 연동 테스트
docker-compose version

2단계: Harbor 설치 실행

cd /opt/harbor

# harbor.yml 설정 확인
cat harbor.yml | grep -E "hostname|harbor_admin_password|data_volume"

# 수정된 스크립트로 Harbor 설치
sudo -E ./install.sh --with-trivy

3단계: 설치 확인

# Harbor 컨테이너 확인 (Podman으로)
podman ps
# 또는 docker-compose로
docker-compose ps

# Harbor 웹 접속 테스트
curl -I http://localhost  # harbor.yml의 hostname 확인

🎯 주요 수정 사항 요약

prepare 스크립트:

  • prepare_base_dir=/prepare_base_dir=$harbor_prepare_path
  • common/config 디렉토리 자동 생성
  • ✅ Podman/Docker 자동 감지

install.sh 스크립트:

  • ✅ Docker Compose 조건문 버그 수정
  • ✅ 에러 처리 강화
  • ✅ Podman 환경 지원

common.sh 스크립트:

  • ✅ Podman 우선 감지
  • ✅ docker-compose 체크 개선
  • ✅ DOCKER_HOST 소켓 지원

이제 Podman + docker-compose 환경에서 안전하게 Harbor를 설치할 수 있습니다!

profile
bytebliss

0개의 댓글