- Add Gitea Actions workflow for manual AlexHost deployment - Add docker-compose.alexhost.yml for production deployment - Add deploy-alexhost.sh script with server-side build support - Add Bot Control feature (Start/Stop/Restart) for remote bot management - Add discovery control endpoint in TeleBot - Update TeleBot with StartPollingAsync/StopPolling/RestartPollingAsync - Fix platform architecture issues by building on target server - Update docker-compose configurations for all environments Deployment tested successfully: - TeleShop: healthy at https://teleshop.silentmary.mywire.org - TeleBot: healthy with discovery integration - SilverPay: connectivity verified 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
250 lines
7.1 KiB
Bash
250 lines
7.1 KiB
Bash
#!/bin/bash
|
|
# AlexHost Deployment Script
|
|
# Usage: ./deploy-alexhost.sh [teleshop|telebot|all] [--no-cache]
|
|
#
|
|
# This script transfers source to AlexHost and builds Docker images natively
|
|
# on the server to ensure correct architecture (AMD64).
|
|
#
|
|
# Requirements:
|
|
# - sshpass installed (for password-based SSH)
|
|
# - tar installed
|
|
# - Access to AlexHost server
|
|
|
|
set -e
|
|
|
|
# Configuration - can be overridden by environment variables
|
|
ALEXHOST_IP="${ALEXHOST_IP:-193.233.245.41}"
|
|
ALEXHOST_USER="${ALEXHOST_USER:-sysadmin}"
|
|
ALEXHOST_PASS="${ALEXHOST_PASS:-}"
|
|
REGISTRY="${REGISTRY:-localhost:5000}"
|
|
|
|
# Check for required password
|
|
if [ -z "$ALEXHOST_PASS" ]; then
|
|
echo -e "${RED}Error: ALEXHOST_PASS environment variable is required${NC}"
|
|
echo "Set it with: export ALEXHOST_PASS='your-password'"
|
|
exit 1
|
|
fi
|
|
DEPLOY_DIR="/home/sysadmin/teleshop-source"
|
|
BUILD_DIR="/tmp/littleshop-build"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Parse arguments
|
|
DEPLOY_TARGET="${1:-all}"
|
|
NO_CACHE=""
|
|
if [[ "$2" == "--no-cache" ]] || [[ "$1" == "--no-cache" ]]; then
|
|
NO_CACHE="--no-cache"
|
|
if [[ "$1" == "--no-cache" ]]; then
|
|
DEPLOY_TARGET="all"
|
|
fi
|
|
fi
|
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
echo -e "${BLUE} AlexHost Deployment Script${NC}"
|
|
echo -e "${BLUE} Target: ${DEPLOY_TARGET}${NC}"
|
|
echo -e "${BLUE} Server: ${ALEXHOST_IP}${NC}"
|
|
echo -e "${BLUE} Mode: Server-side build (AMD64)${NC}"
|
|
echo -e "${BLUE}========================================${NC}"
|
|
echo ""
|
|
|
|
# Function to run SSH commands with sudo
|
|
ssh_sudo() {
|
|
sshpass -p "$ALEXHOST_PASS" ssh -o StrictHostKeyChecking=no "$ALEXHOST_USER@$ALEXHOST_IP" "echo '$ALEXHOST_PASS' | sudo -S bash -c '$1'"
|
|
}
|
|
|
|
# Function to copy files to AlexHost
|
|
scp_file() {
|
|
sshpass -p "$ALEXHOST_PASS" scp -o StrictHostKeyChecking=no "$1" "$ALEXHOST_USER@$ALEXHOST_IP:$2"
|
|
}
|
|
|
|
# Get script directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
# Transfer source to server
|
|
transfer_source() {
|
|
echo -e "${YELLOW}=== Transferring source to AlexHost ===${NC}"
|
|
|
|
# Create tarball excluding unnecessary files
|
|
echo "Creating source tarball..."
|
|
tar -czf /tmp/littleshop-source.tar.gz \
|
|
--exclude='.git' \
|
|
--exclude='node_modules' \
|
|
--exclude='bin' \
|
|
--exclude='obj' \
|
|
--exclude='*.tar.gz' \
|
|
-C "$SCRIPT_DIR" .
|
|
|
|
echo "Source tarball size: $(ls -lh /tmp/littleshop-source.tar.gz | awk '{print $5}')"
|
|
|
|
# Transfer to server
|
|
echo "Transferring to AlexHost..."
|
|
scp_file "/tmp/littleshop-source.tar.gz" "/tmp/"
|
|
scp_file "docker-compose.alexhost.yml" "/tmp/"
|
|
|
|
# Extract on server
|
|
echo "Extracting on server..."
|
|
ssh_sudo "rm -rf $BUILD_DIR && mkdir -p $BUILD_DIR && cd $BUILD_DIR && tar -xzf /tmp/littleshop-source.tar.gz"
|
|
|
|
# Cleanup local
|
|
rm -f /tmp/littleshop-source.tar.gz
|
|
|
|
echo -e "${GREEN}Source transferred successfully!${NC}"
|
|
}
|
|
|
|
# Deploy TeleShop
|
|
deploy_teleshop() {
|
|
echo -e "${YELLOW}=== Building TeleShop on AlexHost ===${NC}"
|
|
|
|
ssh_sudo "
|
|
set -e
|
|
cd $BUILD_DIR
|
|
|
|
echo 'Building TeleShop image...'
|
|
docker build $NO_CACHE -t littleshop:latest -f Dockerfile . 2>&1 | tail -15
|
|
|
|
echo 'Tagging and pushing to local registry...'
|
|
docker tag littleshop:latest localhost:5000/littleshop:latest
|
|
docker push localhost:5000/littleshop:latest
|
|
|
|
echo 'Stopping existing container...'
|
|
docker stop teleshop 2>/dev/null || true
|
|
docker rm teleshop 2>/dev/null || true
|
|
|
|
echo 'Copying compose file...'
|
|
mkdir -p $DEPLOY_DIR
|
|
cp /tmp/docker-compose.alexhost.yml $DEPLOY_DIR/docker-compose.yml
|
|
|
|
echo 'Starting TeleShop...'
|
|
cd $DEPLOY_DIR
|
|
docker compose up -d teleshop
|
|
|
|
echo 'Waiting for health check...'
|
|
sleep 30
|
|
docker ps | grep teleshop
|
|
"
|
|
|
|
echo -e "${GREEN}TeleShop deployment complete!${NC}"
|
|
}
|
|
|
|
# Deploy TeleBot
|
|
deploy_telebot() {
|
|
echo -e "${YELLOW}=== Building TeleBot on AlexHost ===${NC}"
|
|
|
|
ssh_sudo "
|
|
set -e
|
|
cd $BUILD_DIR
|
|
|
|
echo 'Building TeleBot image...'
|
|
docker build $NO_CACHE -t telebot:latest -f Dockerfile.telebot . 2>&1 | tail -15
|
|
|
|
echo 'Tagging and pushing to local registry...'
|
|
docker tag telebot:latest localhost:5000/telebot:latest
|
|
docker push localhost:5000/telebot:latest
|
|
|
|
echo 'Stopping existing container...'
|
|
docker stop telebot 2>/dev/null || true
|
|
docker rm telebot 2>/dev/null || true
|
|
|
|
echo 'Copying compose file...'
|
|
mkdir -p $DEPLOY_DIR
|
|
cp /tmp/docker-compose.alexhost.yml $DEPLOY_DIR/docker-compose.yml 2>/dev/null || true
|
|
|
|
echo 'Starting TeleBot...'
|
|
cd $DEPLOY_DIR
|
|
docker compose up -d telebot
|
|
|
|
echo 'Waiting for startup...'
|
|
sleep 20
|
|
docker ps | grep telebot
|
|
"
|
|
|
|
echo -e "${GREEN}TeleBot deployment complete!${NC}"
|
|
}
|
|
|
|
# Verify deployment
|
|
verify_deployment() {
|
|
echo -e "${YELLOW}=== Verifying Deployment ===${NC}"
|
|
|
|
ssh_exec "
|
|
echo ''
|
|
echo 'Container Status:'
|
|
sudo docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' | grep -E 'NAMES|teleshop|telebot'
|
|
echo ''
|
|
|
|
echo 'Testing TeleShop health...'
|
|
if curl -sf http://localhost:5100/health > /dev/null; then
|
|
echo 'TeleShop: OK'
|
|
else
|
|
echo 'TeleShop: FAIL or starting...'
|
|
fi
|
|
|
|
echo ''
|
|
echo 'Testing TeleBot...'
|
|
if sudo docker ps | grep -q 'telebot.*Up'; then
|
|
echo 'TeleBot: Running'
|
|
else
|
|
echo 'TeleBot: Not running'
|
|
fi
|
|
"
|
|
}
|
|
|
|
# Cleanup build directory
|
|
cleanup() {
|
|
echo -e "${YELLOW}=== Cleaning up ===${NC}"
|
|
ssh_sudo "rm -rf $BUILD_DIR /tmp/littleshop-source.tar.gz"
|
|
echo -e "${GREEN}Cleanup complete${NC}"
|
|
}
|
|
|
|
# Main execution
|
|
case "$DEPLOY_TARGET" in
|
|
teleshop)
|
|
transfer_source
|
|
deploy_teleshop
|
|
cleanup
|
|
verify_deployment
|
|
;;
|
|
telebot)
|
|
transfer_source
|
|
deploy_telebot
|
|
cleanup
|
|
verify_deployment
|
|
;;
|
|
all)
|
|
transfer_source
|
|
deploy_teleshop
|
|
deploy_telebot
|
|
cleanup
|
|
verify_deployment
|
|
;;
|
|
verify)
|
|
verify_deployment
|
|
;;
|
|
*)
|
|
echo -e "${RED}Usage: $0 [teleshop|telebot|all|verify] [--no-cache]${NC}"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 all # Deploy both services"
|
|
echo " $0 teleshop # Deploy only TeleShop"
|
|
echo " $0 telebot # Deploy only TeleBot"
|
|
echo " $0 all --no-cache # Deploy both without Docker cache"
|
|
echo " $0 verify # Just verify current deployment"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
echo ""
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo -e "${GREEN} Deployment Complete!${NC}"
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo ""
|
|
echo "Access points:"
|
|
echo " TeleShop Admin: https://teleshop.silentmary.mywire.org/Admin"
|
|
echo " TeleShop API: https://teleshop.silentmary.mywire.org/api"
|
|
echo " TeleBot API: http://${ALEXHOST_IP}:5010"
|