init
This commit is contained in:
commit
1637cbdd96
4 changed files with 231 additions and 0 deletions
14
Dockerfile
Normal file
14
Dockerfile
Normal file
|
@ -0,0 +1,14 @@
|
|||
FROM alpine:3.21.3
|
||||
|
||||
LABEL maintainer="Alexander Zhirov <alexander@zhirov.kz>"
|
||||
|
||||
COPY deploy /usr/bin/deploy
|
||||
|
||||
RUN <<EOF
|
||||
echo "http://mirror.yandex.ru/mirrors/alpine/edge/main" > /etc/apk/repositories
|
||||
echo "http://mirror.yandex.ru/mirrors/alpine/edge/community" >> /etc/apk/repositories
|
||||
apk update
|
||||
apk upgrade --no-cache
|
||||
apk add --no-cache hugo rsync wget nodejs npm git openssh-client
|
||||
wget -O - https://github.com/CloudCannon/pagefind/releases/download/v1.3.0/pagefind-v1.3.0-x86_64-unknown-linux-musl.tar.gz | tar -xz -C /usr/bin
|
||||
EOF
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Hugo Builder
|
||||
|
||||
Сборка Hugo блога
|
137
build.sh
Normal file
137
build.sh
Normal file
|
@ -0,0 +1,137 @@
|
|||
#!/bin/sh
|
||||
|
||||
usage() {
|
||||
echo "✏️ Использование: $0 -n <имя> -v <версия> [-a <адрес>] [-p <порт>] [-r]"
|
||||
echo "🔧 Опции:"
|
||||
echo " -n, --name Имя образа (обязательно)"
|
||||
echo " -v, --version Версия образа в формате X.Y.Z (обязательно)"
|
||||
echo " -a, --address Адрес registry (требуется с -r)"
|
||||
echo " -p, --port Порт registry (опционально)"
|
||||
echo " -r, --push-to-registry Создать теги и отправить образы в registry"
|
||||
echo ""
|
||||
echo "📌 Примеры:"
|
||||
echo " Только сборка: $0 -n myapp -v 2.5.7"
|
||||
echo " Сборка и отправка: $0 -n myapp -v 2.5.7 -a registry.example.com -p 5000 -r"
|
||||
exit 1
|
||||
}
|
||||
|
||||
validate_version() {
|
||||
echo "$1" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' || {
|
||||
echo "❌ Ошибка: Версия должна быть в формате X.Y.Z (например, 2.5.7)"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
validate_address() {
|
||||
if [ -z "$1" ]; then
|
||||
echo "❌ Ошибка: Адрес не может быть пустым"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_port() {
|
||||
if [ -n "$1" ]; then
|
||||
echo "$1" | grep -Eq '^[0-9]+$' || {
|
||||
echo "❌ Ошибка: Порт должен быть числом"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
push_to_registry=false
|
||||
name=""
|
||||
version=""
|
||||
address=""
|
||||
port=""
|
||||
|
||||
while getopts ":n:v:a:p:r" opt; do
|
||||
case $opt in
|
||||
n) name="$OPTARG" ;;
|
||||
v) version="$OPTARG" ;;
|
||||
a) address="$OPTARG" ;;
|
||||
p) port="$OPTARG" ;;
|
||||
r) push_to_registry=true ;;
|
||||
\?) echo "❌ Неверный аргумент -$OPTARG" >&2; usage ;;
|
||||
:) echo "❌ Опция -$OPTARG требует аргумент" >&2; usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$name" ] || [ -z "$version" ]; then
|
||||
echo "❌ Ошибка: Не указаны обязательные аргументы (-n и -v)"
|
||||
usage
|
||||
fi
|
||||
|
||||
validate_version "$version"
|
||||
|
||||
if [ "$push_to_registry" = true ]; then
|
||||
if [ -z "$address" ]; then
|
||||
echo "❌ Ошибка: Для отправки в registry необходимо указать адрес (-a)"
|
||||
usage
|
||||
fi
|
||||
|
||||
validate_address "$address"
|
||||
validate_port "$port"
|
||||
fi
|
||||
|
||||
echo "🐳 Сборка образа $name:$version..."
|
||||
docker build . -t "${name}:${version}" || {
|
||||
echo "❌ Ошибка при сборке образа"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "$push_to_registry" = true ]; then
|
||||
if [ -z "$port" ]; then
|
||||
registry="$address"
|
||||
else
|
||||
registry="$address:$port"
|
||||
fi
|
||||
|
||||
echo "🏷 Создание тегов для registry..."
|
||||
|
||||
docker tag "${name}:${version}" "${registry}/${name}:latest" || {
|
||||
echo "❌ Ошибка при создании тега latest"
|
||||
exit 1
|
||||
}
|
||||
|
||||
major=$(echo "$version" | cut -d. -f1)
|
||||
minor=$(echo "$version" | cut -d. -f1-2)
|
||||
full="$version"
|
||||
|
||||
docker tag "${name}:${version}" "${registry}/${name}:$full" || {
|
||||
echo "❌ Ошибка при создании тега $full"
|
||||
exit 1
|
||||
}
|
||||
docker tag "${name}:${version}" "${registry}/${name}:$minor" || {
|
||||
echo "❌ Ошибка при создании тега $minor"
|
||||
exit 1
|
||||
}
|
||||
docker tag "${name}:${version}" "${registry}/${name}:$major" || {
|
||||
echo "❌ Ошибка при создании тега $major"
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo " ✅ Созданы теги: latest, $full, $minor, $major"
|
||||
|
||||
echo "🚀 Отправка образов в registry..."
|
||||
docker push "${registry}/${name}:latest" || {
|
||||
echo "❌ Ошибка при отправке тега latest"
|
||||
exit 1
|
||||
}
|
||||
docker push "${registry}/${name}:$full" || {
|
||||
echo "❌ Ошибка при отправке тега $full"
|
||||
exit 1
|
||||
}
|
||||
docker push "${registry}/${name}:$minor" || {
|
||||
echo "❌ Ошибка при отправке тега $minor"
|
||||
exit 1
|
||||
}
|
||||
docker push "${registry}/${name}:$major" || {
|
||||
echo "❌ Ошибка при отправке тега $major"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
echo "🎉 Готово! Образ ${name}:${version} успешно:"
|
||||
echo " ✅ Собран"
|
||||
[ "$push_to_registry" = true ] && echo " ✅ Размечен"
|
||||
[ "$push_to_registry" = true ] && echo " ✅ Отправлен в registry"
|
77
deploy
Executable file
77
deploy
Executable file
|
@ -0,0 +1,77 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Парсинг аргументов командной строки
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--ssh-host) SSH_HOST="$2"; shift 2 ;;
|
||||
--ssh-port) SSH_PORT="$2"; shift 2 ;;
|
||||
--ssh-user) SSH_USER="$2"; shift 2 ;;
|
||||
--deploy-path) DEPLOY_PATH="$2"; shift 2 ;;
|
||||
--private-key) USER_PRIVATE_KEY="$2"; shift 2 ;;
|
||||
*) echo "❌ Ошибка: Неизвестный параметр: $1"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Функция для проверки наличия аргумента
|
||||
check_arg() {
|
||||
arg_name="$1"
|
||||
arg_value="$2"
|
||||
if [ -z "$arg_value" ]; then
|
||||
echo "❌ Ошибка: Не указан обязательный параметр --$arg_name"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Проверка каждого аргумента отдельно
|
||||
check_arg "ssh-host" "$SSH_HOST"
|
||||
check_arg "ssh-user" "$SSH_USER"
|
||||
check_arg "deploy-path" "$DEPLOY_PATH"
|
||||
check_arg "private-key" "$USER_PRIVATE_KEY"
|
||||
|
||||
# Проверка формата SSH-порта (если указан)
|
||||
if [ -n "$SSH_PORT" ]; then
|
||||
if ! echo "$SSH_PORT" | grep -Eq '^[0-9]+$' || [ "$SSH_PORT" -lt 1 ] || [ "$SSH_PORT" -gt 65535 ]; then
|
||||
echo "❌ Ошибка: Порт должен быть числом от 1 до 65535"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
SSH_PORT=22 # Значение по умолчанию
|
||||
fi
|
||||
|
||||
# Проверка формата приватного ключа
|
||||
if ! echo "$USER_PRIVATE_KEY" | grep -q "PRIVATE KEY"; then
|
||||
echo "❌ Ошибка: Указанный приватный ключ не содержит 'PRIVATE KEY' (возможно, некорректный формат)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Создаем папку .ssh, если её нет
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
|
||||
# Сохраняем приватный ключ
|
||||
echo "$USER_PRIVATE_KEY" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
|
||||
# Добавляем хост в known_hosts
|
||||
echo "🔑 Добавляем $SSH_HOST в known_hosts..."
|
||||
ssh-keyscan -p "$SSH_PORT" -H "$SSH_HOST" > ~/.ssh/known_hosts 2>/dev/null || {
|
||||
echo "❌ Ошибка: Не удалось добавить хост $SSH_HOST в known_hosts"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Запускаем ssh-agent и добавляем ключ
|
||||
echo "🔐 Запускаем ssh-agent..."
|
||||
eval "$(ssh-agent -s)" >/dev/null
|
||||
ssh-add ~/.ssh/id_rsa 2>/dev/null || {
|
||||
echo "❌ Ошибка: Не удалось добавить SSH-ключ в агент (проверьте ключ и пароль)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Деплой через rsync
|
||||
echo "🚀 Начинаем деплой в $SSH_USER@$SSH_HOST:$DEPLOY_PATH..."
|
||||
rsync -avz --progress -e "ssh -p $SSH_PORT -i ~/.ssh/id_rsa" public/ "$SSH_USER@$SSH_HOST:$DEPLOY_PATH" || {
|
||||
echo "❌ Ошибка: Деплой не удался (проверьте путь, права или подключение)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "✅ Деплой успешно завершен!"
|
Loading…
Add table
Add a link
Reference in a new issue