Files
apxtri/setup/init.sh.backup
T
2026-05-11 11:16:47 +02:00

730 lines
24 KiB
Bash
Executable File

#!/bin/bash
# Unified installation script for apXtri (dev and prod)
# Launching command for any environment:
# sudo apt install wget -y && sudo wget -O init.sh https://gitea.ndda.fr/apxtri/apxtri/raw/branch/main/setup/init.sh && sudo chmod +x init.sh && ./init.sh
# If you have already an install, add "--clean" at the end of the command above.
set -eEuo pipefail
trap 'err_handler $LINENO $?' ERR
# ==== CONFIG ====
URL_REPO="https://gitea.ndda.fr/apxtri"
REPO_APXTRI="$URL_REPO/apxtri.git"
REPO_OBJECTS="$URL_REPO/objects.git"
DATAPATH="/var/lib/apxtowns"
NODEPATH="/opt/apxtowns"
LOGPATH="/var/log/apxtowns"
APXTRI_USER="apxtri"
NODE_VERSION="lts"
URLBACKUP="https://app1.smatchit.io"
# Variables to be configured
NATION=""
TOWN=""
DOMAIN=""
APIPORT=""
MODE=""
# ==== LOGGING ====
sudo touch /var/log/apxtri_install.log
sudo chown "$USER":"$USER" /var/log/apxtri_install.log
exec > >(tee -i /var/log/apxtri_install.log)
exec 2>&1
# ==== ERROR HANDLER ====
err_handler() {
local lineno="$1"
local code="$2"
if [[ "$code" -eq 99 ]]; then
echo "[INFO] Installation voluntarily stopped at line $lineno (exit 99)."
exit 99
fi
echo "[ERROR] Failure at line $lineno (code $code). Starting cleanup..."
echo "[INFO] The script has stopped due to an error. Please check the logs above for details."
exit "$code"
}
# ==== CLEANING ====
cleaning() {
echo "[CLEAN] Starting cleanup..."
echo "If you need help or give back suggestion about init.sh please feel free to join in discord https://discord.gg/89Ucsnej"
# Kill any lingering process on the API port
if [[ -n "${APIPORT}" ]]; then
echo "[CLEAN] Checking for lingering processes on API port ${APIPORT}..."
sudo fuser -k "${APIPORT}/tcp" 2>/dev/null || true
fi
# Stop and disable services if they exist
sudo systemctl stop apxtri 2>/dev/null || true
sudo systemctl disable apxtri 2>/dev/null || true
sudo systemctl stop caddy 2>/dev/null || true
sudo systemctl disable caddy 2>/dev/null || true
# Remove service files
sudo rm -f /etc/systemd/system/apxtri.service
sudo rm -f /etc/systemd/system/caddy.service.d/override.conf 2>/dev/null || true
sudo systemctl daemon-reload
# Cleanup apxtri-specific files
CURRENT_USER=${SUDO_USER:-$(whoami)}
if sudo -u "$APXTRI_USER" crontab -l 2>/dev/null | grep -Fq "backup.sh"; then
sudo -u "$APXTRI_USER" crontab -l 2>/dev/null | grep -v "backup.sh" | sudo -u "$APXTRI_USER" crontab -
fi
if id -nG "$CURRENT_USER" | grep -qw "$APXTRI_USER"; then
sudo gpasswd -d "$CURRENT_USER" "$APXTRI_USER" || true
fi
if id "$APXTRI_USER" &>/dev/null; then
sudo userdel -r "$APXTRI_USER" 2>/dev/null || true
fi
if getent group "$APXTRI_USER" &>/dev/null; then
sudo groupdel "$APXTRI_USER" 2>/dev/null || true
fi
sudo rm -rf "$DATAPATH" "$NODEPATH" "$LOGPATH" /etc/apxtowns
# Clean up hosts entries
if [[ -n "${DOMAIN}" ]]; then
sudo sed -i "/${DOMAIN}/d" /etc/hosts || true
fi
# Complete Caddy cleanup
if command -v caddy &>/dev/null; then
echo "[CLEAN] Removing Caddy and its configuration..."
sudo apt-get purge -y caddy
sudo rm -rf /etc/caddy /var/lib/caddy /usr/share/caddy
sudo rm -f /etc/apt/sources.list.d/caddy-stable.list
sudo rm -f /usr/share/keyrings/caddy-stable-archive-keyring.gpg
fi
# Cleanup permissions and sudoers files
sudo rm -f /etc/sudoers.d/apxtri-caddy
sudo rm -rf /run/caddy
echo "[CLEAN] Cleanup complete."
}
# ==== UTILITY FUNCTIONS ====
find_free_port() {
local port=$1
while sudo lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1 ; do
echo "[INFO] Port $port is in use, trying next port..."
port=$((port + 1))
done
echo "$port"
}
# ==== ARGUMENT PARSING ====
clean_install=false
# Function to display usage
usage() {
echo "Usage: $0 [--town <name>] [--nation <name>] [--domain <domain>] [--datapath <path>] [--nodepath <path>] [--apiport <port>] [--clean] [--help]"
echo " --town Set the town name. If not set, prompts interactively."
echo " --nation Set the nation name. If not set, prompts interactively."
echo " Use 'test' for dev mode, any other value for prod mode."
echo " --domain Set the domain name. Required for prod, auto-generated for dev."
echo " --datapath Set the data path (default: '/var/lib/apxtowns')."
echo " --nodepath Set the node path (default: '/opt/apxtowns')."
echo " --apiport Set the API port (default: auto-detect from 3000)."
echo " --clean Force removal of any existing installation before proceeding."
echo " --help Display this help message."
exit 1
}
# Parse command-line arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--town)
if [[ -z "$2" || "$2" == --* ]]; then echo "Error: Missing value for --town" >&2; usage; fi
TOWN="$2"
shift 2
;;
--nation)
if [[ -z "$2" || "$2" == --* ]]; then echo "Error: Missing value for --nation" >&2; usage; fi
NATION="$2"
shift 2
;;
--domain)
if [[ -z "$2" || "$2" == --* ]]; then echo "Error: Missing value for --domain" >&2; usage; fi
DOMAIN="$2"
shift 2
;;
--datapath)
if [[ -z "$2" || "$2" == --* ]]; then echo "Error: Missing value for --datapath" >&2; usage; fi
DATAPATH="$2"
shift 2
;;
--nodepath)
if [[ -z "$2" || "$2" == --* ]]; then echo "Error: Missing value for --nodepath" >&2; usage; fi
NODEPATH="$2"
shift 2
;;
--apiport)
if [[ -z "$2" || "$2" == --* ]]; then echo "Error: Missing value for --apiport" >&2; usage; fi
APIPORT="$2"
shift 2
;;
--clean)
clean_install=true
shift 1
;;
--help|-h)
usage
;;
*)
echo "Error: Unknown option $1" >&2
usage
;;
esac
done
# ==== CHECK EXISTING INSTALLATION ====
if [ -d "$NODEPATH" ] || [ -d "$DATAPATH" ] || { [ "$(id -u 2>/dev/null || echo)" -eq 0 ] && id "$APXTRI_USER" &>/dev/null; }; then
if [ "$clean_install" = true ]; then
echo "Existing installation detected and --clean flag was provided."
echo "Removing existing installation..."
cleaning
else
echo "[WARN] Existing apxtri installation detected."
echo "To perform a clean re-installation, please run the script again with the --clean flag."
echo "Example: $0 --clean"
echo "Aborting installation to prevent accidental data loss."
exit 99
fi
fi
# ==== INTERACTIVE PROMPTS ====
echo "============================================"
echo "apXtri Installation Configuration"
echo "============================================"
echo ""
# Prompt for TOWN if not provided
if [[ -z "$TOWN" ]]; then
read -p "Enter town name [farm]: " TOWN
TOWN=${TOWN:-farm}
fi
# Prompt for NATION if not provided
if [[ -z "$NATION" ]]; then
read -p "Enter nation name (use 'test' for dev mode) [ants]: " NATION
NATION=${NATION:-ants}
fi
# Auto-detect mode based on NATION
if [[ "$NATION" == "test" ]]; then
MODE="dev"
echo "[INFO] Detected DEV mode (nation=test)"
# Auto-generate domain for dev
if [[ -z "$DOMAIN" ]]; then
DOMAIN="admin.apxtri.${TOWN}.test"
echo "[INFO] Using local domain: $DOMAIN"
fi
else
MODE="prod"
echo "[INFO] Detected PROD mode (nation=$NATION)"
# Domain is mandatory for prod
if [[ -z "$DOMAIN" ]]; then
while [[ -z "$DOMAIN" ]]; do
read -p "Enter domain name (e.g., mytown.example.com): " DOMAIN
if [[ -z "$DOMAIN" ]]; then
echo "[ERROR] Domain is mandatory for production mode."
fi
done
fi
fi
# Auto-detect free port if not provided
if [[ -z "$APIPORT" ]]; then
APIPORT=$(find_free_port 3000)
echo "[INFO] Using API port: $APIPORT"
fi
echo ""
echo "---"
echo "Final configuration:"
echo " Mode: $MODE"
echo " Town: $TOWN"
echo " Nation: $NATION"
echo " Domain: $DOMAIN"
echo " API Port: $APIPORT"
echo " Data Path: $DATAPATH"
echo " Node Path: $NODEPATH"
echo "---"
echo ""
read -p "Continue with this configuration? [Y/n]: " confirm
if [[ "$confirm" =~ ^[Nn]$ ]]; then
echo "Installation cancelled."
exit 0
fi
# ==== INSTALL TOOLS ====
echo "[STEP 1/10] Installing system dependencies..."
sudo apt update --fix-missing
sudo apt install -y curl git gnupg jq build-essential locales vim libcap2-bin p7zip-full p7zip-rar unzip psmisc
# Check if no locale (can be the case with an lxc container or basic ubuntu server install)
if ! locale -a 2>/dev/null | grep -q '\.UTF-8'; then
echo "[INFO] No UTF-8 locale found, generating en_US.UTF-8..."
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8
else
echo "[INFO] UTF-8 locale already exists, no modification needed."
fi
# ==== INSTALL CADDY ====
echo "[STEP 2/10] Installing Caddy..."
if ! command -v caddy &>/dev/null; then
echo "Installing Caddy..."
sudo mkdir -p /usr/share/keyrings
sudo chmod 755 /usr/share/keyrings
sudo curl -fsSL https://dl.cloudsmith.io/public/caddy/stable/gpg.key -o /tmp/caddy-key.gpg
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg /tmp/caddy-key.gpg
sudo chmod 644 /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo rm -f /tmp/caddy-key.gpg
echo "deb [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main" | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy
else
echo "Caddy already installed."
fi
# ==== HOSTS CONFIGURATION ====
echo "[STEP 3/10] Configuring /etc/hosts..."
if [[ "$NATION" == "test" ]]; then
# For dev mode, add local domain to /etc/hosts
if ! grep -q "$DOMAIN" /etc/hosts; then
echo "127.0.0.1 $DOMAIN" | sudo tee -a /etc/hosts
echo "[INFO] Added $DOMAIN to /etc/hosts"
else
echo "[INFO] $DOMAIN already in /etc/hosts"
fi
else
# For prod mode, verify DNS resolution
if host "$DOMAIN" &>/dev/null; then
echo "[INFO] Domain $DOMAIN resolves correctly"
else
echo "[WARN] Domain $DOMAIN does not resolve. Make sure DNS is configured correctly."
echo "[INFO] Adding to /etc/hosts for local testing..."
if ! grep -q "$DOMAIN" /etc/hosts; then
echo "127.0.0.1 $DOMAIN" | sudo tee -a /etc/hosts
fi
fi
fi
# ==== CREATE USER ====
echo "[STEP 4/10] Creating system user..."
if ! id "$APXTRI_USER" &>/dev/null; then
echo "Creating system user $APXTRI_USER..."
sudo useradd --system --no-create-home --shell /usr/sbin/nologin "$APXTRI_USER"
echo "$APXTRI_USER:$APXTRI_USER" | sudo chpasswd
else
echo "User $APXTRI_USER already exists."
fi
# ==== CONFIGURE CADDY SERVICE ====
echo "[STEP 5/10] Configuring Caddy service..."
sudo rm -f /etc/systemd/system/caddy.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl start caddy || true
# ==== ADD USERS TO APXTRI GROUP ====
CURRENT_USER=${SUDO_USER:-$(whoami)}
sudo usermod -aG "$APXTRI_USER" "$CURRENT_USER"
sudo usermod -aG "$APXTRI_USER" caddy
# ==== CREATE DIRECTORIES ====
echo "[STEP 6/10] Creating directories..."
sudo mkdir -p "$NODEPATH/$TOWN-$NATION" "$LOGPATH" "$DATAPATH/data/apxtri/logs" "$DATAPATH/data/apxtri/tmp" "$NODEPATH/$TOWN-$NATION/apxtri/tmp"
sudo chown -R "$APXTRI_USER:$APXTRI_USER" "$DATAPATH" "$NODEPATH" "$LOGPATH" "$NODEPATH/$TOWN-$NATION/apxtri/tmp"
sudo chmod -R g+rwX "$NODEPATH" "$DATAPATH"
# ==== SET GROUP INHERITANCE FOR WWWS ====
echo "Configuring group permission inheritance for Caddy on wwws directories..."
sudo find "$DATAPATH" -type d -name "wwws" -exec chmod g+s {} + 2>/dev/null || true
sudo find "$DATAPATH" -type d -name "wwws" -exec chmod -R g+rX {} + 2>/dev/null || true
# ==== CLONE REPOSITORIES ====
echo "[STEP 7/10] Cloning repositories..."
# Clone objects repo first
sudo -u "$APXTRI_USER" mkdir -p "$DATAPATH/data/apxtri/objects"
sudo -u "$APXTRI_USER" git clone "$REPO_OBJECTS" "$DATAPATH/data/apxtri/objects" || {
echo "[WARN] Objects repository clone failed or already exists, continuing..."
}
sudo -u "$APXTRI_USER" git config --global --add safe.directory "$DATAPATH/data/apxtri/objects" || true
# Download and extract setup files
TAR_URL="$URL_REPO/apxtri/raw/branch/main/setup/setup.apxtri.objects.tar.gz"
TAR_FILE="$DATAPATH/data/apxtri/setup.apxtri.objects.tar.gz"
sudo -u "$APXTRI_USER" bash -c "cd /tmp && wget -O '$TAR_FILE' '$TAR_URL'" || {
echo "[WARN] Failed to download setup zip, continuing..."
}
sudo -u "$APXTRI_USER" bash -c "
mkdir -p '$DATAPATH/data/apxtri/objects' && \
tar -xzf '$TAR_FILE' -C '$DATAPATH/data/apxtri/objects'" || {
echo "[WARN] Failed to extract .tar.gz, continuing..."
}
sudo rm -f "$TAR_FILE"
# Clone main repo
if [ -d "$NODEPATH/$TOWN-$NATION/apxtri" ]; then
echo "[INFO] Removing existing apxtri directory for clean clone..."
sudo rm -rf "$NODEPATH/$TOWN-$NATION/apxtri"
fi
sudo -u "$APXTRI_USER" git clone "$REPO_APXTRI" "$NODEPATH/$TOWN-$NATION/apxtri"
sudo -u "$APXTRI_USER" git config --global --add safe.directory "$NODEPATH/$TOWN-$NATION/apxtri" || true
# ==== CREATE ENV FILE ====
echo "[STEP 8/10] Creating environment configuration..."
sudo tee "$NODEPATH/$TOWN-$NATION/apxtri/.env" > /dev/null <<EOL
URL_REPO="$URL_REPO"
VERSION="1.0.0"
MODE="$MODE"
TOWN="$TOWN"
NATION="$NATION"
DOMAIN="$DOMAIN"
UBUNTU="server"
ETCCONF="/etc/apxtowns/apxtowns"
DATAPATH="$DATAPATH"
NODEPATH="$NODEPATH"
LOGPATH="$LOGPATH"
APIPORT="$APIPORT"
ACTIVELOG=apxtri,isAuthenticated,checkHeaders,Odmdb,Pagans,Persons,Wwws,Trackings,Notifications
##debug,info,warn,error, debug and info will be shown only if a name.js is in ACTIVELOG to help to be focus in debugging
LOG_LEVEL=debug
EXPOSEDHEADERS="xdays,xalias,xlang,xtribe,xapp,xuuid"
SOCKETPORT="$((APIPORT + 1))"
BACKENDURL="localhost"
CADDYAPIURL="http://localhost:2019"
BLOCKCHAIN_CONNECT=false
PRIVKMAYOR=""
EOL
sudo chown "$APXTRI_USER:$APXTRI_USER" "$NODEPATH/$TOWN-$NATION/apxtri/.env"
# ==== INSTALL NVM + NODE ====
echo "[STEP 9/10] Installing Node.js via NVM..."
npm_config_cache="${DATAPATH:-/tmp}/.npm"
sudo mkdir -p "$npm_config_cache"
sudo chown -R "$APXTRI_USER:$APXTRI_USER" "$npm_config_cache"
NVM_DIR="$NODEPATH/$TOWN-$NATION/apxtri/.nvm"
sudo -u "$APXTRI_USER" HOME="$NODEPATH/$TOWN-$NATION/apxtri" DATAPATH="$DATAPATH" NODE_VERSION="$NODE_VERSION" npm_config_cache="$npm_config_cache" NVM_DIR="$NVM_DIR" bash <<EOF
set -euo pipefail
if [ ! -d "$NVM_DIR" ]; then
echo "Installing NVM..."
git clone https://github.com/nvm-sh/nvm.git "$NVM_DIR"
cd "$NVM_DIR"
git checkout master
else
echo "NVM already installed in $NVM_DIR"
fi
chmod +x "$NVM_DIR/nvm.sh"
export NVM_DIR="$NVM_DIR"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install --lts
nvm alias default 'lts/*'
nvm use default
npm install -g npm@latest
cd "$NODEPATH/$TOWN-$NATION/apxtri"
if [ -f package.json ]; then
echo "Installing npm dependencies..."
npm install
fi
EOF
#=== Add symlink to main_modules for tailwindcss to work properly
ln -s "$NODEPATH/$TOWN-$NATION/apxtri/node_modules/" "$NODEPATH/main_modules"
#==
# ==== CREATE SYSTEMD SERVICE (BOTH DEV AND PROD) ====
echo "[STEP 10/10] Creating systemd service..."
SERVICE_PATH="/etc/systemd/system/apxtri.service"
if [[ "$MODE" == "dev" ]]; then
# Dev mode: tee output to log file for easier access
LOG_FILE="$DATAPATH/data/apxtri/logs/dev.log"
sudo tee "$SERVICE_PATH" > /dev/null <<EOF
[Unit]
Description=apXtri development service
After=network.target
[Service]
Type=simple
User=$APXTRI_USER
Group=$APXTRI_USER
WorkingDirectory=$NODEPATH/$TOWN-$NATION/apxtri
EnvironmentFile=$NODEPATH/$TOWN-$NATION/apxtri/.env
ExecStart=/bin/bash -lc "source $NODEPATH/$TOWN-$NATION/apxtri/.nvm/nvm.sh && npm run dev 2>&1 | tee -a $LOG_FILE"
ExecStop=/bin/bash -lc "pkill -u $APXTRI_USER -f 'node.*apxtri.js'"
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
else
# Prod mode: also tee output to log file
LOG_FILE="$DATAPATH/data/apxtri/logs/prod.log"
sudo tee "$SERVICE_PATH" > /dev/null <<EOF
[Unit]
Description=apXtri production service
After=network.target
[Service]
Type=simple
User=$APXTRI_USER
Group=$APXTRI_USER
WorkingDirectory=$NODEPATH/$TOWN-$NATION/apxtri
EnvironmentFile=$NODEPATH/$TOWN-$NATION/apxtri/.env
ExecStart=/bin/bash -lc "source $NODEPATH/$TOWN-$NATION/apxtri/.nvm/nvm.sh && npm run prod 2>&1 | tee -a $LOG_FILE"
ExecStop=/bin/bash -lc "pkill -u $APXTRI_USER -f 'node.*apxtri.js'"
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
fi
sudo systemctl daemon-reload
sudo systemctl enable apxtri
sudo systemctl start apxtri
# ==== CREATE HELPER SCRIPTS ====
echo "Creating helper scripts..."
# Create apxdev script (works for both modes but most useful in dev)
SCRIPT_PATH="/usr/local/bin/apxdev"
cat <<EOF | sudo tee $SCRIPT_PATH > /dev/null
#!/bin/bash
# apxdev - apXtri development helper
# Usage: apxdev [command]
# Commands:
# start - Start the apxtri service
# stop - Stop the apxtri service
# restart - Restart the apxtri service
# logs - Show logs (file and journalctl)
# status - Show service status
# (no arg) - Restart and follow logs
MODE="\$(grep MODE= $NODEPATH/$TOWN-$NATION/apxtri/.env | cut -d= -f2 | tr -d '"')"
LOG_FILE="$DATAPATH/data/apxtri/logs/\${MODE}.log"
case "\${1:-restart}" in
start)
sudo systemctl start apxtri
echo "apXtri started. View logs with: apxdev logs"
;;
stop)
sudo systemctl stop apxtri
echo "apXtri stopped."
;;
restart)
echo "Restarting apXtri..."
sudo systemctl restart apxtri
sleep 2
tail -f "\$LOG_FILE"
;;
logs)
echo "=== Recent journalctl logs ==="
sudo journalctl -u apxtri -n 50 --no-pager
echo ""
echo "=== Following log file: \$LOG_FILE ==="
tail -f "\$LOG_FILE"
;;
status)
sudo systemctl status apxtri --no-pager
;;
*)
echo "Usage: apxdev [start|stop|restart|logs|status]"
echo " start - Start the service"
echo " stop - Stop the service"
echo " restart - Restart and follow logs (default)"
echo " logs - Show recent logs and follow"
echo " status - Show service status"
exit 1
;;
esac
EOF
sudo chmod +x $SCRIPT_PATH
# Create apxgeminicli script
SCRIPT_PATH="/usr/local/bin/apxgeminicli"
cat <<EOF | sudo tee $SCRIPT_PATH > /dev/null
#!/bin/bash
# apxgeminicli - Run Gemini CLI in apxtri context
# Add your gemini key in $NODEPATH/$TOWN-$NATION/apxtri/.env
# GEMINI_API_KEY=your_key_here
sudo -u apxtri env HOME="$NODEPATH/$TOWN-$NATION/apxtri" bash -c 'cd "$NODEPATH/$TOWN-$NATION/apxtri" && source .nvm/nvm.sh && nvm use default && npx @google/gemini-cli'
EOF
sudo chmod +x $SCRIPT_PATH
# Create apxtailwind script
SCRIPT_PATH="/usr/local/bin/apxtailwind"
cat <<'EOF' | sudo tee $SCRIPT_PATH > /dev/null
#!/bin/bash
# apxtailwind - Run Tailwind CSS compiler
# Usage: apxtailwind <tribe> <appname> [extra args...]
set -euo pipefail
if [[ $# -lt 2 ]]; then
echo "Usage: $0 <tribe> <appname> [extra args...]"
exit 1
fi
TRIBE="$1"
APPNAME="$2"
shift 2
BASE_DIR="__NODEPATH__/__TOWN__-__NATION__/${TRIBE}"
CSS_IN="__DATAPATH__/data/${TRIBE}/objects/wwws/${APPNAME}/src/static/css/input.css"
CSS_OUT="__DATAPATH__/data/${TRIBE}/objects/wwws/${APPNAME}/src/static/css/output.css"
sudo -u apxtri env HOME="${BASE_DIR}" bash -c '
cd ~ &&
source .nvm/nvm.sh &&
nvm use default &&
npx @tailwindcss/cli -i "'"${CSS_IN}"'" -o "'"${CSS_OUT}"'" "$@"
' _ "$@"
EOF
# Replace placeholders with actual values from the main script
sudo sed -i "s|__NODEPATH__|$NODEPATH|g" "$SCRIPT_PATH"
sudo sed -i "s|__DATAPATH__|$DATAPATH|g" "$SCRIPT_PATH"
sudo sed -i "s|__NATION__|$NATION|g" "$SCRIPT_PATH"
sudo sed -i "s|__TOWN__|$TOWN|g" "$SCRIPT_PATH"
sudo chmod +x $SCRIPT_PATH
# ==== CONFIGURE CRONTABS ====
echo "Configuring crontab for automated tasks..."
# Make scripts executable
sudo chmod +x "$NODEPATH/$TOWN-$NATION/apxtri/setup/update.sh"
sudo chmod +x "$NODEPATH/$TOWN-$NATION/apxtri/setup/backup.sh"
# Get current user (the one who ran sudo)
CRON_USER=${SUDO_USER:-$(whoami)}
# Define cron jobs (will run as current user with sudo)
UPDATE_CRON="0 3 * * * $NODEPATH/$TOWN-$NATION/apxtri/setup/update.sh >> $DATAPATH/data/apxtri/logs/update.log 2>&1"
BACKUP_CRON="0 1 * * * $NODEPATH/$TOWN-$NATION/apxtri/setup/backup.sh apxtri setup nations,towns,pagans >> $DATAPATH/data/apxtri/logs/backup.log 2>&1"
# Get existing crontab
TEMP_CRON=$(mktemp)
crontab -l 2>/dev/null > "$TEMP_CRON" || true
# Remove all existing /opt/apxtowns entries
sed -i '\|/opt/apxtowns|d' "$TEMP_CRON"
echo "[INFO] Removed all existing /opt/apxtowns cron entries"
# Add new cron jobs
echo "$UPDATE_CRON" >> "$TEMP_CRON"
echo "[INFO] Added update.sh cron job (daily at 03:00) for user $CRON_USER"
echo "$BACKUP_CRON" >> "$TEMP_CRON"
echo "[INFO] Added backup.sh cron job (daily at 01:00) for user $CRON_USER"
# Install the crontab for current user
crontab "$TEMP_CRON"
rm -f "$TEMP_CRON"
echo "[INFO] Crontab configured successfully for user $CRON_USER"
echo " - Update check: Daily at 03:00 AM"
echo " - Backup: Daily at 01:00 AM (setup backup)"
# ==== FINAL MESSAGE ====
echo
echo "============================================"
echo "INSTALLATION COMPLETE"
echo "============================================"
echo ""
echo "Configuration Summary:"
echo " Mode: $MODE"
echo " Town: $TOWN"
echo " Nation: $NATION"
echo " Domain: $DOMAIN"
echo " API Port: $APIPORT"
echo " Data Path: $DATAPATH"
echo " Node Path: $NODEPATH"
echo ""
# Get network info
LAN_IP=$(hostname -I | awk '{print $1}')
PUBLIC_IP=$(curl -s http://icanhazip.com || echo "Failed to retrieve")
echo "Network Information:"
echo " LAN IP: $LAN_IP"
echo " Public IP: $PUBLIC_IP"
echo ""
echo "Service Management:"
echo " Start: sudo systemctl start apxtri"
echo " Stop: sudo systemctl stop apxtri"
echo " Restart: sudo systemctl restart apxtri"
echo " Status: sudo systemctl status apxtri"
echo ""
echo "Log Access:"
echo " File: tail -f $DATAPATH/data/apxtri/logs/${MODE}.log"
echo " Journal: sudo journalctl -u apxtri -f"
echo ""
echo "Helper Commands:"
echo " apxdev - Quick restart and log viewing"
echo " apxgeminicli - Run Gemini CLI"
echo " apxtailwind - Run Tailwind CSS compiler"
echo ""
if [[ "$MODE" == "dev" ]]; then
echo "[DEV MODE SETUP]"
echo "1. Exit this terminal to refresh your group permissions"
echo "2. Open VS Code: code $NODEPATH"
echo "3. Add workspace folder: File > Add Folder to Workspace > $DATAPATH"
echo "4. Start development: apxdev"
echo ""
echo "Development URL: http://$DOMAIN:$APIPORT"
echo ""
echo "⚠️ User $CURRENT_USER was added to group $APXTRI_USER"
echo " Run 'newgrp $APXTRI_USER' or log out/in for permissions to take effect"
else
echo "[PROD MODE SETUP]"
echo "apXtri is now running as a systemd service"
echo "Access your application at: https://$DOMAIN"
echo ""
echo "⚠️ IMPORTANT SECURITY STEPS:"
echo " 1. Change the password for user $APXTRI_USER: sudo passwd $APXTRI_USER"
echo " 2. Configure firewall rules if needed"
echo " 3. Review and secure $NODEPATH/$TOWN-$NATION/apxtri/.env"
fi
echo ""
echo "Automated Tasks (Crontab for user $CURRENT_USER):"
echo " Update: Daily at 03:00 AM - Checks for updates and applies minor/patch versions"
echo " Backup: Daily at 01:00 AM - Creates setup backup"
echo " View crons: crontab -l"
echo " Update log: tail -f $DATAPATH/data/apxtri/logs/update.log"
echo " Backup log: tail -f $DATAPATH/data/apxtri/logs/backup.log"
echo ""
echo "Next Steps:"
echo "1. Complete the town setup by accessing the admin interface"
echo "2. Monitor automated backups in $DATAPATH/data/apxtri/backups/"
echo "3. Check logs for any issues"
echo ""
echo "For help or feedback: https://discord.gg/89Ucsnej"
echo "============================================"