#!/bin/bash # Data Visualization Display Wall - Systemd Installer # Requirements: Node.js, NPM, Systemd (Linux) # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}=== Data Visualization Display Wall Installer ===${NC}" # 1. Permission check (no longer mandatory) if [ "$EUID" -eq 0 ]; then # If run as sudo, get the real user that called it REAL_USER=${SUDO_USER:-$USER} else REAL_USER=$USER fi # 2. Get current directory and user PROJECT_DIR=$(pwd) USER_HOME=$(getent passwd "$REAL_USER" | cut -d: -f6) echo -e "Project Directory: ${GREEN}$PROJECT_DIR${NC}" echo -e "Running User: ${GREEN}$REAL_USER${NC}" # 3. Check for mandatory files if [ ! -f "server/index.js" ]; then echo -e "${RED}Error: server/index.js not found. Please run this script from the project root.${NC}" exit 1 fi # 4. Check for dependencies echo -e "${BLUE}Checking dependencies...${NC}" check_dep() { if ! command -v "$1" &> /dev/null; then echo -e "${RED}$1 is not installed. Please install $1 first.${NC}" exit 1 fi } check_dep node check_dep npm # 5. Check for .env file if [ ! -f ".env" ]; then echo -e "${YELLOW}Warning: .env file not found.${NC}" if [ -f ".env.example" ]; then echo -e "Creating .env from .env.example..." cp .env.example .env echo -e "${GREEN}Created .env file. Please ensure values are correct.${NC}" else echo -e "${RED}Error: .env.example not found. Configuration missing.${NC}" fi fi # 6. Install NPM dependencies echo -e "${BLUE}Installing dependencies...${NC}" npm install if [ $? -ne 0 ]; then echo -e "${RED}NPM install failed.${NC}" exit 1 fi # 7. Create Systemd Service File SERVICE_FILE="/etc/systemd/system/data-wall.service" NODE_PATH=$(command -v node) echo -e "${BLUE}Creating systemd service at $SERVICE_FILE... (May require password)${NC}" sudo bash -c "cat < '$SERVICE_FILE' [Unit] Description=Data Visualization Display Wall After=network.target mysql.service redis-server.service valkey-server.service Wants=mysql.service [Service] Type=simple User=$REAL_USER WorkingDirectory=$PROJECT_DIR ExecStart=$NODE_PATH server/index.js Restart=always RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=data-wall # Pass environment via .env file injection EnvironmentFile=-$PROJECT_DIR/.env Environment=NODE_ENV=production # Security Hardening CapabilityBoundingSet= NoNewPrivileges=true LimitNOFILE=65535 [Install] WantedBy=multi-user.target EOF" # 8. Reload Systemd and Start echo -e "${BLUE}Reloading systemd and restarting service... (May require password)${NC}" sudo systemctl daemon-reload sudo systemctl enable data-wall sudo systemctl restart data-wall # 9. Check Status echo -e "${BLUE}Checking service status...${NC}" sleep 2 if sudo systemctl is-active --quiet data-wall; then echo -e "${GREEN}SUCCESS: Service is now running.${NC}" PORT=$(grep "^PORT=" .env | cut -d'=' -f2) PORT=${PORT:-3000} echo -e "Dashboard URL: ${YELLOW}http://localhost:${PORT}${NC}" echo -e "View logs: ${BLUE}journalctl -u data-wall -f${NC}" else echo -e "${RED}FAILED: Service failed to start.${NC}" echo -e "Check logs with: ${BLUE}journalctl -u data-wall -xe${NC}" fi # 10. Reverse Proxy Configuration echo -ne "${YELLOW}Do you want to configure a reverse proxy (Nginx/Caddy)? (y/n): ${NC}" read -r CONF_PROXY if [[ "$CONF_PROXY" =~ ^[Yy]$ ]]; then echo -e "${BLUE}=== Reverse Proxy Configuration ===${NC}" # Get Domain echo -ne "Enter your domain name (e.g., monitor.example.com): " read -r DOMAIN if [ -z "$DOMAIN" ]; then echo -e "${RED}Error: Domain cannot be empty. Skipping proxy configuration.${NC}" else # Get Port from .env PORT=$(grep "^PORT=" .env | cut -d'=' -f2) PORT=${PORT:-3000} # Choose Proxy echo -e "Select Proxy Type:" echo -e " 1) Caddy (Automatic SSL, easy to use)" echo -e " 2) Nginx (Advanced, manual SSL)" echo -ne "Choose (1/2): " read -r PROXY_TYPE # Enable HTTPS? echo -ne "Enable HTTPS (SSL)? (y/n): " read -r ENABLE_HTTPS if [ "$PROXY_TYPE" == "1" ]; then # Caddy Config CADDY_FILE="Caddyfile" echo -e "${BLUE}Generating Caddyfile...${NC}" if [[ "$ENABLE_HTTPS" =~ ^[Yy]$ ]]; then cat < "$CADDY_FILE" $DOMAIN { reverse_proxy localhost:$PORT } EOF else cat < "$CADDY_FILE" http://$DOMAIN { reverse_proxy localhost:$PORT } EOF fi echo -e "${GREEN}Caddyfile generated at $PROJECT_DIR/$CADDY_FILE${NC}" echo -e "${YELLOW}Tip: Ensure Caddy is installed and pointing to this file.${NC}" elif [ "$PROXY_TYPE" == "2" ]; then # Nginx Config echo -ne "Enter Nginx configuration export path (default: ./${DOMAIN}.conf): " read -r NGINX_PATH NGINX_PATH=${NGINX_PATH:-"./${DOMAIN}.conf"} echo -e "${BLUE}Generating Nginx configuration...${NC}" if [[ "$ENABLE_HTTPS" =~ ^[Yy]$ ]]; then echo -ne "Enter SSL Certificate Path: " read -r SSL_CERT echo -ne "Enter SSL Key Path: " read -r SSL_KEY cat < "$NGINX_PATH" server { listen 80; server_name $DOMAIN; return 301 https://\$host\$request_uri; } server { listen 443 ssl http2; server_name $DOMAIN; ssl_certificate $SSL_CERT; ssl_certificate_key $SSL_KEY; location / { proxy_pass http://localhost:$PORT; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } } EOF else cat < "$NGINX_PATH" server { listen 80; server_name $DOMAIN; location / { proxy_pass http://localhost:$PORT; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } } EOF fi echo -e "${GREEN}Nginx config generated at $NGINX_PATH${NC}" echo -e "${YELLOW}Tip: You can symlink this to /etc/nginx/sites-enabled/ to activate.${NC}" else echo -e "${YELLOW}Unknown proxy type selected. Skipping.${NC}" fi fi fi echo -e "${BLUE}================================================${NC}" echo -e "${GREEN}Setup completed successfully!${NC}"