Files
proxmox-lxc-shell-commands/proxmox-lxc-gotify.sh
devops 07f90da89c feat: Gotify LXC 설치 스크립트 추가
- 푸시 알림 서버 Gotify v2.6.1
- 바이너리 기반 설치 (경량)
- systemd 서비스 등록

🤖 Generated with Claude Code
2026-01-05 22:44:30 +09:00

372 lines
11 KiB
Bash

#!/usr/bin/env bash
# Gotify LXC Installation Script
# Description: Self-hosted push notification server
# OS: Debian 12 (Bookworm) - Auto-detected latest version
# Ports: Web UI/API: 8080
# Repository: https://github.com/gotify/server
# Last Updated: 2026-01-05
set -euo pipefail
#################################################################
# Configuration Variables
#################################################################
# Container Configuration
CT_ID=${CT_ID:-11001} # Container ID
CT_HOSTNAME=${CT_HOSTNAME:-"gotify"} # Container hostname
CT_CORES=${CT_CORES:-1} # CPU cores
CT_MEMORY=${CT_MEMORY:-512} # RAM in MB
CT_SWAP=${CT_SWAP:-256} # Swap in MB
CT_DISK_SIZE=${CT_DISK_SIZE:-8} # Root disk size in GB
# Network Configuration
CT_IP=${CT_IP:-"dhcp"} # IP address (dhcp or static like 192.168.1.100/24)
CT_GATEWAY=${CT_GATEWAY:-""} # Gateway (required for static IP)
CT_BRIDGE=${CT_BRIDGE:-"vmbr0"} # Network bridge
CT_NAMESERVER=${CT_NAMESERVER:-"8.8.8.8"} # DNS server
# Storage Configuration
CT_STORAGE=${CT_STORAGE:-"local-lvm"} # Storage pool for container
TEMPLATE_STORAGE=${TEMPLATE_STORAGE:-"local"} # Storage pool for templates
# Debian Template (will be auto-detected)
DEBIAN_VERSION="12" # Debian version
TEMPLATE_NAME="" # Auto-detected
# Application Configuration
GOTIFY_PORT=${GOTIFY_PORT:-8080} # Web UI/API port
GOTIFY_ADMIN_USER=${GOTIFY_ADMIN_USER:-"admin"} # Admin username
GOTIFY_ADMIN_PASS=${GOTIFY_ADMIN_PASS:-"admin"} # Admin password (change this!)
GOTIFY_VERSION=${GOTIFY_VERSION:-"2.6.1"} # Gotify version
# Container Options
CT_ONBOOT=${CT_ONBOOT:-1} # Start on boot (1=yes, 0=no)
CT_UNPRIVILEGED=${CT_UNPRIVILEGED:-1} # Unprivileged container
CT_FEATURES=${CT_FEATURES:-"nesting=1"} # Container features
#################################################################
# Color Output Functions
#################################################################
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
#################################################################
# Validation Functions
#################################################################
check_root() {
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root"
exit 1
fi
}
check_proxmox() {
if ! command -v pct &> /dev/null; then
error "This script must be run on a Proxmox VE host"
exit 1
fi
}
check_container_exists() {
if pct status "$CT_ID" &> /dev/null; then
error "Container ID $CT_ID already exists"
info "Please choose a different CT_ID or remove the existing container"
exit 1
fi
}
detect_and_download_template() {
info "Updating template database..."
if ! pveam update 2>&1 | grep -q "update successful\|already up to date"; then
warn "Template database update encountered issues, continuing anyway..."
fi
info "Detecting available Debian ${DEBIAN_VERSION} template..."
local available_template
available_template=$(pveam available --section system 2>/dev/null | grep "debian-${DEBIAN_VERSION}" | grep "standard" | tail -1 | awk '{print $2}')
if [[ -z "$available_template" ]]; then
error "No Debian ${DEBIAN_VERSION} template found in available templates"
exit 1
fi
TEMPLATE_NAME="$available_template"
info "Found template: $TEMPLATE_NAME"
if pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -q "$TEMPLATE_NAME"; then
success "Template already downloaded"
return 0
fi
warn "Downloading Debian template (this may take a few minutes)..."
if pveam download "$TEMPLATE_STORAGE" "$TEMPLATE_NAME" 2>&1; then
success "Template downloaded successfully"
else
error "Failed to download template"
exit 1
fi
}
#################################################################
# Container Creation Functions
#################################################################
create_container() {
info "Creating LXC container $CT_ID ($CT_HOSTNAME)..."
local net_config="name=eth0,bridge=${CT_BRIDGE},ip=${CT_IP}"
if [[ "$CT_IP" != "dhcp" ]] && [[ -n "$CT_GATEWAY" ]]; then
net_config="${net_config},gw=${CT_GATEWAY}"
fi
pct create "$CT_ID" \
"${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE_NAME}" \
--hostname "$CT_HOSTNAME" \
--cores "$CT_CORES" \
--memory "$CT_MEMORY" \
--swap "$CT_SWAP" \
--rootfs "${CT_STORAGE}:${CT_DISK_SIZE}" \
--net0 "$net_config" \
--nameserver "$CT_NAMESERVER" \
--onboot "$CT_ONBOOT" \
--unprivileged "$CT_UNPRIVILEGED" \
--features "$CT_FEATURES" \
--ostype debian || {
error "Failed to create container"
exit 1
}
success "Container $CT_ID created successfully"
}
start_container() {
info "Starting container $CT_ID..."
pct start "$CT_ID" || {
error "Failed to start container"
exit 1
}
info "Waiting for container to boot..."
sleep 5
success "Container started successfully"
}
configure_autologin() {
info "Configuring automatic console login..."
pct exec "$CT_ID" -- bash -c "mkdir -p /etc/systemd/system/container-getty@1.service.d"
pct exec "$CT_ID" -- bash -c 'cat > /etc/systemd/system/container-getty@1.service.d/override.conf << EOF
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 \$TERM
EOF'
pct exec "$CT_ID" -- bash -c "systemctl daemon-reload"
pct exec "$CT_ID" -- bash -c "systemctl restart container-getty@1.service" 2>/dev/null || true
success "Automatic console login configured"
}
#################################################################
# Gotify Installation
#################################################################
install_gotify() {
info "Installing Gotify in container $CT_ID..."
info "Updating package list..."
pct exec "$CT_ID" -- bash -c "apt-get update -qq"
info "Installing required packages..."
pct exec "$CT_ID" -- bash -c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
wget \
unzip \
ca-certificates \
curl"
info "Creating Gotify directories..."
pct exec "$CT_ID" -- bash -c "mkdir -p /opt/gotify/data"
info "Downloading Gotify ${GOTIFY_VERSION}..."
pct exec "$CT_ID" -- bash -c "cd /opt/gotify && wget -q https://github.com/gotify/server/releases/download/v${GOTIFY_VERSION}/gotify-linux-amd64.zip"
pct exec "$CT_ID" -- bash -c "cd /opt/gotify && unzip -o gotify-linux-amd64.zip && rm gotify-linux-amd64.zip"
pct exec "$CT_ID" -- bash -c "chmod +x /opt/gotify/gotify-linux-amd64"
info "Creating Gotify configuration..."
pct exec "$CT_ID" -- bash -c "cat > /opt/gotify/config.yml << 'EOF'
server:
port: ${GOTIFY_PORT}
keepaliveperiodseconds: 0
listenaddr: \"\"
ssl:
enabled: false
redirecttohttps: false
listenaddr: \"\"
port: 443
certfile: \"\"
certkey: \"\"
letsencrypt:
enabled: false
accepttos: false
cache: data/certs
hosts:
- domain.tld
responseheaders: {}
cors:
alloworigins:
- \".+\"
allowmethods:
- GET
- POST
allowheaders:
- Authorization
- content-type
stream:
allowedorigins:
- \".+\"
pingperiodseconds: 45
database:
dialect: sqlite3
connection: data/gotify.db
defaultuser:
name: ${GOTIFY_ADMIN_USER}
pass: ${GOTIFY_ADMIN_PASS}
passstrength: 10
uploadedimagesdir: data/images
pluginsdir: data/plugins
registration: false
EOF"
success "Gotify installed successfully"
}
create_gotify_service() {
info "Creating Gotify systemd service..."
pct exec "$CT_ID" -- bash -c 'cat > /etc/systemd/system/gotify.service << EOF
[Unit]
Description=Gotify Push Notification Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/gotify
ExecStart=/opt/gotify/gotify-linux-amd64
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF'
pct exec "$CT_ID" -- bash -c "systemctl daemon-reload"
pct exec "$CT_ID" -- bash -c "systemctl enable gotify"
pct exec "$CT_ID" -- bash -c "systemctl start gotify"
sleep 3
if pct exec "$CT_ID" -- bash -c "systemctl is-active gotify" &>/dev/null; then
success "Gotify service started successfully"
else
warn "Gotify service may not be running, please check logs"
fi
}
#################################################################
# Verification Functions
#################################################################
verify_installation() {
info "Verifying Gotify installation..."
sleep 3
local container_ip
container_ip=$(pct exec "$CT_ID" -- bash -c "hostname -I | awk '{print \$1}'" 2>/dev/null || echo "unknown")
if pct exec "$CT_ID" -- bash -c "curl -s -o /dev/null -w '%{http_code}' http://localhost:${GOTIFY_PORT}/" | grep -q "200\|302"; then
success "Gotify is running and accessible!"
else
warn "Gotify may not be fully ready yet. Please wait a moment and try again."
fi
echo ""
echo "================================================================"
echo -e "${GREEN}Gotify Installation Complete!${NC}"
echo "================================================================"
echo ""
echo "Container Information:"
echo " - Container ID: $CT_ID"
echo " - Hostname: $CT_HOSTNAME"
echo " - IP Address: $container_ip"
echo ""
echo "Access Information:"
echo " - Web UI: http://${container_ip}:${GOTIFY_PORT}"
echo " - Admin User: ${GOTIFY_ADMIN_USER}"
echo " - Admin Password: ${GOTIFY_ADMIN_PASS}"
echo ""
echo "Service Management:"
echo " - pct exec $CT_ID -- systemctl status gotify"
echo " - pct exec $CT_ID -- systemctl restart gotify"
echo ""
echo "Data Directory: /opt/gotify/data"
echo "Config File: /opt/gotify/config.yml"
echo "================================================================"
}
#################################################################
# Main Script Execution
#################################################################
main() {
echo "================================================================"
echo "Gotify LXC Installation Script"
echo "================================================================"
echo ""
check_root
check_proxmox
check_container_exists
detect_and_download_template
create_container
start_container
configure_autologin
install_gotify
create_gotify_service
verify_installation
}
main "$@"