279 lines
9.3 KiB
Bash
Executable File
279 lines
9.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# GNX-WEB Service Startup Script
|
|
# Starts backend on port 1086 and frontend on port 1087
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Get script directory
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
BACKEND_DIR="$SCRIPT_DIR/backEnd"
|
|
FRONTEND_DIR="$SCRIPT_DIR/frontEnd"
|
|
|
|
# Ports
|
|
BACKEND_PORT=1086
|
|
FRONTEND_PORT=1087
|
|
|
|
echo -e "${BLUE}=========================================="
|
|
echo "GNX-WEB Service Startup"
|
|
echo "==========================================${NC}"
|
|
|
|
# Check if PM2 is installed
|
|
if ! command -v pm2 &> /dev/null; then
|
|
echo -e "${YELLOW}PM2 is not installed. Installing PM2...${NC}"
|
|
npm install -g pm2
|
|
fi
|
|
|
|
# Function to check if port is in use
|
|
check_port() {
|
|
local port=$1
|
|
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1 || netstat -tlnp 2>/dev/null | grep -q ":$port " || ss -tlnp 2>/dev/null | grep -q ":$port "; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Check if ports are available
|
|
if check_port $BACKEND_PORT; then
|
|
echo -e "${YELLOW}Port $BACKEND_PORT is already in use. Stopping existing service...${NC}"
|
|
pm2 delete gnxsoft-backend 2>/dev/null || true
|
|
sleep 2
|
|
fi
|
|
|
|
if check_port $FRONTEND_PORT; then
|
|
echo -e "${YELLOW}Port $FRONTEND_PORT is already in use. Stopping existing service...${NC}"
|
|
pm2 delete gnxsoft-frontend 2>/dev/null || true
|
|
sleep 2
|
|
fi
|
|
|
|
# Check if backend directory exists
|
|
if [ ! -d "$BACKEND_DIR" ]; then
|
|
echo -e "${RED}Error: Backend directory not found at $BACKEND_DIR${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if frontend directory exists
|
|
if [ ! -d "$FRONTEND_DIR" ]; then
|
|
echo -e "${RED}Error: Frontend directory not found at $FRONTEND_DIR${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Function to generate secure random key
|
|
generate_secret_key() {
|
|
python3 -c "import secrets; print(secrets.token_urlsafe($1))" 2>/dev/null || \
|
|
openssl rand -base64 $((($1 * 3) / 4)) | tr -d '\n' | head -c $1
|
|
}
|
|
|
|
# Check if backend .env exists
|
|
if [ ! -f "$BACKEND_DIR/.env" ]; then
|
|
echo -e "${YELLOW}Warning: Backend .env file not found. Creating from example...${NC}"
|
|
if [ -f "$BACKEND_DIR/production.env.example" ]; then
|
|
cp "$BACKEND_DIR/production.env.example" "$BACKEND_DIR/.env"
|
|
|
|
# Generate and update keys automatically
|
|
echo -e "${BLUE}Generating secure keys...${NC}"
|
|
SECRET_KEY=$(generate_secret_key 50)
|
|
INTERNAL_API_KEY=$(generate_secret_key 32)
|
|
|
|
# Update keys in .env file
|
|
sed -i "s|^SECRET_KEY=.*|SECRET_KEY=$SECRET_KEY|" "$BACKEND_DIR/.env"
|
|
sed -i "s|^INTERNAL_API_KEY=.*|INTERNAL_API_KEY=$INTERNAL_API_KEY|" "$BACKEND_DIR/.env"
|
|
sed -i "s|^STATIC_ROOT=.*|STATIC_ROOT=$BACKEND_DIR/staticfiles|" "$BACKEND_DIR/.env"
|
|
sed -i "s|^MEDIA_ROOT=.*|MEDIA_ROOT=$BACKEND_DIR/media|" "$BACKEND_DIR/.env"
|
|
|
|
echo -e "${GREEN}✓ Generated and updated SECRET_KEY and INTERNAL_API_KEY${NC}"
|
|
echo -e "${YELLOW}Please update other values in $BACKEND_DIR/.env${NC}"
|
|
else
|
|
echo -e "${RED}Error: production.env.example not found${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
# Check if keys need to be generated
|
|
if grep -q "your-super-secret\|your-secure-api-key\|PLACEHOLDER" "$BACKEND_DIR/.env"; then
|
|
echo -e "${BLUE}Generating secure keys for existing .env file...${NC}"
|
|
SECRET_KEY=$(generate_secret_key 50)
|
|
INTERNAL_API_KEY=$(generate_secret_key 32)
|
|
|
|
# Update keys in .env file
|
|
sed -i "s|^SECRET_KEY=.*|SECRET_KEY=$SECRET_KEY|" "$BACKEND_DIR/.env"
|
|
sed -i "s|^INTERNAL_API_KEY=.*|INTERNAL_API_KEY=$INTERNAL_API_KEY|" "$BACKEND_DIR/.env"
|
|
|
|
echo -e "${GREEN}✓ Updated SECRET_KEY and INTERNAL_API_KEY${NC}"
|
|
|
|
# Update nginx config if it exists
|
|
if [ -f "/etc/nginx/sites-available/gnxsoft" ]; then
|
|
echo -e "${BLUE}Updating nginx configuration with INTERNAL_API_KEY...${NC}"
|
|
escaped_key=$(echo "$INTERNAL_API_KEY" | sed 's/[[\.*^$()+?{|]/\\&/g')
|
|
sudo sed -i "s|set \$api_key \".*\";|set \$api_key \"$escaped_key\";|g" /etc/nginx/sites-available/gnxsoft
|
|
echo -e "${GREEN}✓ Updated nginx config with INTERNAL_API_KEY${NC}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Start Backend
|
|
echo -e "${GREEN}[1/2] Starting Backend on port $BACKEND_PORT...${NC}"
|
|
cd "$BACKEND_DIR"
|
|
|
|
# Check if virtual environment exists
|
|
if [ ! -d "venv" ]; then
|
|
echo -e "${YELLOW}Virtual environment not found. Creating...${NC}"
|
|
python3 -m venv venv
|
|
fi
|
|
|
|
# Activate virtual environment
|
|
source venv/bin/activate
|
|
|
|
# Install/update dependencies
|
|
if [ ! -f "venv/.deps_installed" ]; then
|
|
echo -e "${BLUE}Installing Python dependencies...${NC}"
|
|
pip install -r requirements.txt
|
|
touch venv/.deps_installed
|
|
fi
|
|
|
|
# Run migrations
|
|
echo -e "${BLUE}Running database migrations...${NC}"
|
|
python manage.py migrate --noinput
|
|
|
|
# Collect static files
|
|
echo -e "${BLUE}Collecting static files...${NC}"
|
|
python manage.py collectstatic --noinput
|
|
|
|
# Create logs directory
|
|
mkdir -p logs
|
|
|
|
# Start backend with PM2
|
|
pm2 start gunicorn \
|
|
--name "gnxsoft-backend" \
|
|
--interpreter "$BACKEND_DIR/venv/bin/python" \
|
|
-- \
|
|
gnx.wsgi:application \
|
|
--bind 127.0.0.1:$BACKEND_PORT \
|
|
--workers 3 \
|
|
--timeout 120 \
|
|
--access-logfile "$BACKEND_DIR/logs/gunicorn_access.log" \
|
|
--error-logfile "$BACKEND_DIR/logs/gunicorn_error.log"
|
|
|
|
# Start Frontend
|
|
echo -e "${GREEN}[2/2] Starting Frontend on port $FRONTEND_PORT...${NC}"
|
|
cd "$FRONTEND_DIR"
|
|
|
|
# Check if node_modules exists
|
|
if [ ! -d "node_modules" ]; then
|
|
echo -e "${YELLOW}Node modules not found. Installing...${NC}"
|
|
npm install
|
|
fi
|
|
|
|
# Check if .next exists (build directory)
|
|
if [ ! -d ".next" ]; then
|
|
echo -e "${YELLOW}Frontend not built. Building...${NC}"
|
|
# Use production environment for build
|
|
NODE_ENV=production PORT=$FRONTEND_PORT npm run build
|
|
fi
|
|
|
|
# Create .env.production if it doesn't exist
|
|
if [ ! -f ".env.production" ]; then
|
|
echo -e "${BLUE}Creating .env.production file...${NC}"
|
|
cat > .env.production << EOF
|
|
NEXT_PUBLIC_SITE_URL=https://gnxsoft.com
|
|
NEXT_PUBLIC_API_URL=
|
|
PORT=$FRONTEND_PORT
|
|
NODE_ENV=production
|
|
NEXT_TELEMETRY_DISABLED=1
|
|
EOF
|
|
echo -e "${GREEN}✓ Created .env.production${NC}"
|
|
else
|
|
# Update PORT if it exists but is different
|
|
if ! grep -q "^PORT=$FRONTEND_PORT" .env.production; then
|
|
echo -e "${BLUE}Updating PORT in .env.production...${NC}"
|
|
if grep -q "^PORT=" .env.production; then
|
|
sed -i "s|^PORT=.*|PORT=$FRONTEND_PORT|" .env.production
|
|
else
|
|
echo "PORT=$FRONTEND_PORT" >> .env.production
|
|
fi
|
|
echo -e "${GREEN}✓ Updated PORT in .env.production${NC}"
|
|
fi
|
|
|
|
# Ensure NODE_ENV is set to production
|
|
if ! grep -q "^NODE_ENV=production" .env.production; then
|
|
if grep -q "^NODE_ENV=" .env.production; then
|
|
sed -i "s|^NODE_ENV=.*|NODE_ENV=production|" .env.production
|
|
else
|
|
echo "NODE_ENV=production" >> .env.production
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
<<<<<<< HEAD
|
|
# Set PORT environment variable and start with PM2
|
|
PORT=$FRONTEND_PORT NODE_ENV=production pm2 start npm \
|
|
--name "gnxsoft-frontend" \
|
|
-- start
|
|
=======
|
|
# Check if Next.js is using standalone output mode
|
|
if grep -q '"output":\s*"standalone"' next.config.js 2>/dev/null || grep -q "output:.*'standalone'" next.config.js 2>/dev/null; then
|
|
echo -e "${BLUE}Detected standalone mode. Starting with standalone server...${NC}"
|
|
|
|
# Check if standalone server exists
|
|
if [ ! -f ".next/standalone/server.js" ]; then
|
|
echo -e "${YELLOW}Standalone server not found. Rebuilding...${NC}"
|
|
NODE_ENV=production PORT=$FRONTEND_PORT npm run build
|
|
fi
|
|
|
|
# Ensure public folder is copied to standalone directory
|
|
if [ ! -d ".next/standalone/public" ]; then
|
|
echo -e "${BLUE}Copying public folder to standalone directory...${NC}"
|
|
cp -r public .next/standalone/
|
|
fi
|
|
|
|
# Ensure static folder symlink exists for image optimization
|
|
if [ ! -L ".next/standalone/.next/static" ] && [ ! -d ".next/standalone/.next/static" ]; then
|
|
echo -e "${BLUE}Creating symlink for static files...${NC}"
|
|
mkdir -p .next/standalone/.next
|
|
ln -s ../../static .next/standalone/.next/static
|
|
fi
|
|
|
|
# Start standalone server with PM2
|
|
PORT=$FRONTEND_PORT NODE_ENV=production pm2 start node \
|
|
--name "gnxsoft-frontend" \
|
|
--cwd "$FRONTEND_DIR" \
|
|
-- \
|
|
".next/standalone/server.js"
|
|
else
|
|
# Standard Next.js start
|
|
PORT=$FRONTEND_PORT NODE_ENV=production pm2 start npm \
|
|
--name "gnxsoft-frontend" \
|
|
-- start
|
|
fi
|
|
>>>>>>> d7d7a2757a183aa1abd9dbabff804c45298df4e5
|
|
|
|
# Save PM2 configuration
|
|
pm2 save
|
|
|
|
echo ""
|
|
echo -e "${GREEN}=========================================="
|
|
echo "Services Started Successfully!"
|
|
echo "==========================================${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}Backend:${NC} http://127.0.0.1:$BACKEND_PORT"
|
|
echo -e "${BLUE}Frontend:${NC} http://127.0.0.1:$FRONTEND_PORT"
|
|
echo ""
|
|
echo "PM2 Commands:"
|
|
echo " pm2 status - Check service status"
|
|
echo " pm2 logs gnxsoft-backend - View backend logs"
|
|
echo " pm2 logs gnxsoft-frontend - View frontend logs"
|
|
echo " pm2 restart all - Restart all services"
|
|
echo " pm2 stop all - Stop all services"
|
|
echo " pm2 delete all - Remove all services"
|
|
echo ""
|
|
echo -e "${YELLOW}Note: Make sure to configure nginx to proxy to these ports${NC}"
|
|
echo ""
|
|
|