- Modified vps-deploy.sh to run as both root and non-root user - Added dynamic sudo command handling (SUDO_CMD variable) - Set appropriate service user (www-data for root, current user for non-root) - Updated all system commands to use dynamic sudo - Enhanced PostgreSQL setup for root execution - Updated PM2 configuration with proper user permissions - Added deployment update script with root support - Improved security and flexibility for VPS deployment
788 lines
20 KiB
Bash
Executable File
788 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# 🚀 Laca City Website - Complete VPS Deployment Script
|
|
# This script sets up your entire website on a VPS with domain configuration
|
|
# Run this script on your VPS after uploading your project files
|
|
# Can be run as root user or regular user with sudo privileges
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
PURPLE='\033[0;35m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration Variables (Modify these before running)
|
|
DOMAIN_NAME="" # e.g., "yourdomain.com"
|
|
EMAIL="" # Your email for SSL certificate
|
|
PROJECT_NAME="laca-city"
|
|
DB_NAME="laca_city_db"
|
|
DB_USER="laca_admin"
|
|
DB_PASSWORD="" # Will be generated if empty
|
|
FRONTEND_PORT=3000
|
|
BACKEND_PORT=3001
|
|
NGINX_CONFIG_NAME="laca-city"
|
|
|
|
# System Configuration
|
|
UBUNTU_VERSION=$(lsb_release -rs 2>/dev/null || echo "unknown")
|
|
CURRENT_USER=$(whoami)
|
|
PROJECT_DIR="/var/www/$PROJECT_NAME"
|
|
BACKUP_DIR="/var/backups/$PROJECT_NAME"
|
|
|
|
# Function to print colored output
|
|
print_header() {
|
|
echo -e "\n${PURPLE}========================================${NC}"
|
|
echo -e "${PURPLE}$1${NC}"
|
|
echo -e "${PURPLE}========================================${NC}\n"
|
|
}
|
|
|
|
print_status() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
print_step() {
|
|
echo -e "${CYAN}[STEP]${NC} $1"
|
|
}
|
|
|
|
# Function to check if command exists
|
|
command_exists() {
|
|
command -v "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
# Function to prompt for user input
|
|
prompt_input() {
|
|
local prompt="$1"
|
|
local var_name="$2"
|
|
local default="$3"
|
|
|
|
if [ -n "$default" ]; then
|
|
read -p "$prompt [$default]: " input
|
|
eval "$var_name=\${input:-$default}"
|
|
else
|
|
read -p "$prompt: " input
|
|
eval "$var_name=\$input"
|
|
fi
|
|
}
|
|
|
|
# Function to generate random password
|
|
generate_password() {
|
|
openssl rand -base64 32 | tr -d "=+/" | cut -c1-25
|
|
}
|
|
|
|
# Function to create systemd service
|
|
create_systemd_service() {
|
|
local service_name="$1"
|
|
local description="$2"
|
|
local exec_start="$3"
|
|
local working_dir="$4"
|
|
local user="$5"
|
|
|
|
$SUDO_CMD tee "/etc/systemd/system/$service_name.service" > /dev/null <<EOF
|
|
[Unit]
|
|
Description=$description
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=$user
|
|
WorkingDirectory=$working_dir
|
|
ExecStart=$exec_start
|
|
Restart=always
|
|
RestartSec=10
|
|
Environment=NODE_ENV=production
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
$SUDO_CMD systemctl daemon-reload
|
|
$SUDO_CMD systemctl enable "$service_name"
|
|
}
|
|
|
|
# Function to setup firewall
|
|
setup_firewall() {
|
|
print_step "Setting up UFW firewall..."
|
|
|
|
$SUDO_CMD ufw --force reset
|
|
$SUDO_CMD ufw default deny incoming
|
|
$SUDO_CMD ufw default allow outgoing
|
|
|
|
# Allow SSH
|
|
$SUDO_CMD ufw allow ssh
|
|
$SUDO_CMD ufw allow 22
|
|
|
|
# Allow HTTP and HTTPS
|
|
$SUDO_CMD ufw allow 80
|
|
$SUDO_CMD ufw allow 443
|
|
|
|
# Allow specific ports for development (optional)
|
|
$SUDO_CMD ufw allow $FRONTEND_PORT
|
|
$SUDO_CMD ufw allow $BACKEND_PORT
|
|
|
|
$SUDO_CMD ufw --force enable
|
|
|
|
print_success "Firewall configured"
|
|
}
|
|
|
|
# Function to setup Nginx
|
|
setup_nginx() {
|
|
print_step "Setting up Nginx..."
|
|
|
|
$SUDO_CMD apt update
|
|
$SUDO_CMD apt install -y nginx
|
|
|
|
# Remove default configuration
|
|
$SUDO_CMD rm -f /etc/nginx/sites-enabled/default
|
|
|
|
# Create Nginx configuration
|
|
$SUDO_CMD tee "/etc/nginx/sites-available/$NGINX_CONFIG_NAME" > /dev/null <<EOF
|
|
# Upstream servers
|
|
upstream frontend {
|
|
server 127.0.0.1:$FRONTEND_PORT;
|
|
}
|
|
|
|
upstream backend {
|
|
server 127.0.0.1:$BACKEND_PORT;
|
|
}
|
|
|
|
# Redirect HTTP to HTTPS
|
|
server {
|
|
listen 80;
|
|
server_name $DOMAIN_NAME www.$DOMAIN_NAME;
|
|
return 301 https://\$server_name\$request_uri;
|
|
}
|
|
|
|
# Main HTTPS server
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name $DOMAIN_NAME www.$DOMAIN_NAME;
|
|
|
|
# SSL configuration (will be configured by Certbot)
|
|
ssl_certificate /etc/letsencrypt/live/$DOMAIN_NAME/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN_NAME/privkey.pem;
|
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
|
|
|
# Security headers
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-XSS-Protection "1; mode=block" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
|
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
|
|
|
|
# Gzip compression
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_min_length 1024;
|
|
gzip_proxied expired no-cache no-store private must-revalidate auth;
|
|
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript;
|
|
|
|
# API routes
|
|
location /api/ {
|
|
proxy_pass http://backend;
|
|
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;
|
|
proxy_cache_bypass \$http_upgrade;
|
|
}
|
|
|
|
# Socket.IO WebSocket
|
|
location /socket.io/ {
|
|
proxy_pass http://backend;
|
|
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;
|
|
}
|
|
|
|
# Static files from Next.js
|
|
location /_next/static/ {
|
|
proxy_pass http://frontend;
|
|
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
}
|
|
|
|
# Frontend routes
|
|
location / {
|
|
proxy_pass http://frontend;
|
|
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;
|
|
proxy_cache_bypass \$http_upgrade;
|
|
}
|
|
|
|
# Error pages
|
|
error_page 500 502 503 504 /50x.html;
|
|
location = /50x.html {
|
|
root /var/www/html;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Enable the site
|
|
$SUDO_CMD ln -sf "/etc/nginx/sites-available/$NGINX_CONFIG_NAME" "/etc/nginx/sites-enabled/"
|
|
|
|
# Test Nginx configuration
|
|
$SUDO_CMD nginx -t
|
|
|
|
print_success "Nginx configured"
|
|
}
|
|
|
|
# Function to setup SSL with Let's Encrypt
|
|
setup_ssl() {
|
|
print_step "Setting up SSL certificate with Let's Encrypt..."
|
|
|
|
# Install Certbot
|
|
$SUDO_CMD apt install -y certbot python3-certbot-nginx
|
|
|
|
# Stop Nginx temporarily
|
|
$SUDO_CMD systemctl stop nginx
|
|
|
|
# Obtain SSL certificate
|
|
$SUDO_CMD certbot --nginx -d "$DOMAIN_NAME" -d "www.$DOMAIN_NAME" --email "$EMAIL" --agree-tos --non-interactive
|
|
|
|
# Start Nginx
|
|
$SUDO_CMD systemctl start nginx
|
|
$SUDO_CMD systemctl enable nginx
|
|
|
|
# Setup automatic renewal
|
|
$SUDO_CMD crontab -l 2>/dev/null | { cat; echo "0 3 * * * /usr/bin/certbot renew --quiet"; } | $SUDO_CMD crontab -
|
|
|
|
print_success "SSL certificate configured and auto-renewal setup"
|
|
}
|
|
|
|
# Function to setup PostgreSQL
|
|
setup_postgresql() {
|
|
print_step "Setting up PostgreSQL..."
|
|
|
|
$SUDO_CMD apt update
|
|
$SUDO_CMD apt install -y postgresql postgresql-contrib
|
|
|
|
# Start and enable PostgreSQL
|
|
$SUDO_CMD systemctl start postgresql
|
|
$SUDO_CMD systemctl enable postgresql
|
|
|
|
# Generate database password if not provided
|
|
if [ -z "$DB_PASSWORD" ]; then
|
|
DB_PASSWORD=$(generate_password)
|
|
print_status "Generated database password: $DB_PASSWORD"
|
|
fi
|
|
|
|
# Create database and user
|
|
if [ "$CURRENT_USER" = "root" ]; then
|
|
su - postgres -c "psql" <<EOF
|
|
CREATE DATABASE $DB_NAME;
|
|
CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASSWORD';
|
|
GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
|
|
ALTER USER $DB_USER CREATEDB;
|
|
\q
|
|
EOF
|
|
else
|
|
sudo -u postgres psql <<EOF
|
|
CREATE DATABASE $DB_NAME;
|
|
CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASSWORD';
|
|
GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
|
|
ALTER USER $DB_USER CREATEDB;
|
|
\q
|
|
EOF
|
|
fi
|
|
|
|
print_success "PostgreSQL configured"
|
|
}
|
|
|
|
# Function to setup Redis
|
|
setup_redis() {
|
|
print_step "Setting up Redis..."
|
|
|
|
$SUDO_CMD apt update
|
|
$SUDO_CMD apt install -y redis-server
|
|
|
|
# Configure Redis
|
|
$SUDO_CMD sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
|
|
|
|
$SUDO_CMD systemctl restart redis.service
|
|
$SUDO_CMD systemctl enable redis.service
|
|
|
|
print_success "Redis configured"
|
|
}
|
|
|
|
# Function to install Node.js
|
|
install_nodejs() {
|
|
print_step "Installing Node.js..."
|
|
|
|
# Install Node.js 18.x
|
|
curl -fsSL https://deb.nodesource.com/setup_18.x | $SUDO_CMD -E bash -
|
|
$SUDO_CMD apt-get install -y nodejs
|
|
|
|
# Install PM2 globally
|
|
$SUDO_CMD npm install -g pm2
|
|
|
|
print_success "Node.js and PM2 installed"
|
|
}
|
|
|
|
# Function to setup project files
|
|
setup_project() {
|
|
print_step "Setting up project files..."
|
|
|
|
# Create project directory
|
|
$SUDO_CMD mkdir -p "$PROJECT_DIR"
|
|
$SUDO_CMD mkdir -p "$BACKUP_DIR"
|
|
|
|
# Copy files to project directory (assuming current directory has the project)
|
|
$SUDO_CMD cp -r ./* "$PROJECT_DIR/" 2>/dev/null || true
|
|
$SUDO_CMD chown -R "$SERVICE_USER:$SERVICE_USER" "$PROJECT_DIR"
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Install dependencies
|
|
print_status "Installing frontend dependencies..."
|
|
cd "$PROJECT_DIR/frontend"
|
|
npm ci --production
|
|
|
|
print_status "Installing backend dependencies..."
|
|
cd "$PROJECT_DIR/backend"
|
|
npm ci --production
|
|
|
|
print_success "Project dependencies installed"
|
|
}
|
|
|
|
# Function to create environment files
|
|
create_env_files() {
|
|
print_step "Creating environment files..."
|
|
|
|
# Backend environment
|
|
cat > "$PROJECT_DIR/backend/.env" <<EOF
|
|
NODE_ENV=production
|
|
PORT=$BACKEND_PORT
|
|
|
|
# Database Configuration
|
|
DB_HOST=localhost
|
|
DB_PORT=5432
|
|
DB_NAME=$DB_NAME
|
|
DB_USERNAME=$DB_USER
|
|
DB_PASSWORD=$DB_PASSWORD
|
|
|
|
# Redis Configuration
|
|
REDIS_HOST=localhost
|
|
REDIS_PORT=6379
|
|
|
|
# JWT Configuration
|
|
JWT_SECRET=$(generate_password)
|
|
JWT_EXPIRES_IN=7d
|
|
|
|
# API Configuration
|
|
API_PREFIX=api
|
|
API_VERSION=v1
|
|
|
|
# CORS Configuration
|
|
CORS_ORIGIN=https://$DOMAIN_NAME
|
|
|
|
# Rate Limiting
|
|
RATE_LIMIT_TTL=60
|
|
RATE_LIMIT_LIMIT=100
|
|
EOF
|
|
|
|
# Frontend environment
|
|
cat > "$PROJECT_DIR/frontend/.env.production" <<EOF
|
|
NODE_ENV=production
|
|
NEXT_PUBLIC_API_URL=https://$DOMAIN_NAME/api
|
|
NEXT_PUBLIC_SOCKET_URL=https://$DOMAIN_NAME
|
|
NEXT_PUBLIC_DOMAIN=$DOMAIN_NAME
|
|
EOF
|
|
|
|
print_success "Environment files created"
|
|
}
|
|
|
|
# Function to build applications
|
|
build_applications() {
|
|
print_step "Building applications..."
|
|
|
|
# Build backend
|
|
cd "$PROJECT_DIR/backend"
|
|
npm run build
|
|
|
|
# Build frontend
|
|
cd "$PROJECT_DIR/frontend"
|
|
npm run build
|
|
|
|
print_success "Applications built successfully"
|
|
}
|
|
|
|
# Function to setup PM2 processes
|
|
setup_pm2() {
|
|
print_step "Setting up PM2 processes..."
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Create PM2 ecosystem file
|
|
cat > ecosystem.config.js <<EOF
|
|
module.exports = {
|
|
apps: [
|
|
{
|
|
name: 'laca-city-backend',
|
|
script: './backend/dist/main.js',
|
|
cwd: './backend',
|
|
instances: 1,
|
|
exec_mode: 'cluster',
|
|
env: {
|
|
NODE_ENV: 'production',
|
|
PORT: $BACKEND_PORT
|
|
},
|
|
error_file: '/var/log/pm2/laca-city-backend-error.log',
|
|
out_file: '/var/log/pm2/laca-city-backend-out.log',
|
|
log_file: '/var/log/pm2/laca-city-backend.log',
|
|
max_restarts: 10,
|
|
min_uptime: '10s',
|
|
uid: '$SERVICE_USER',
|
|
gid: '$SERVICE_USER'
|
|
},
|
|
{
|
|
name: 'laca-city-frontend',
|
|
script: 'npm',
|
|
args: 'start',
|
|
cwd: './frontend',
|
|
instances: 1,
|
|
exec_mode: 'cluster',
|
|
env: {
|
|
NODE_ENV: 'production',
|
|
PORT: $FRONTEND_PORT
|
|
},
|
|
error_file: '/var/log/pm2/laca-city-frontend-error.log',
|
|
out_file: '/var/log/pm2/laca-city-frontend-out.log',
|
|
log_file: '/var/log/pm2/laca-city-frontend.log',
|
|
max_restarts: 10,
|
|
min_uptime: '10s',
|
|
uid: '$SERVICE_USER',
|
|
gid: '$SERVICE_USER'
|
|
}
|
|
]
|
|
};
|
|
EOF
|
|
|
|
# Create log directory
|
|
$SUDO_CMD mkdir -p /var/log/pm2
|
|
$SUDO_CMD chown -R "$SERVICE_USER:$SERVICE_USER" /var/log/pm2
|
|
|
|
# Start applications with PM2
|
|
pm2 start ecosystem.config.js
|
|
pm2 save
|
|
pm2 startup
|
|
|
|
print_success "PM2 processes configured"
|
|
}
|
|
|
|
# Function to setup monitoring
|
|
setup_monitoring() {
|
|
print_step "Setting up monitoring..."
|
|
|
|
# Install htop and other monitoring tools
|
|
$SUDO_CMD apt install -y htop iotop nethogs
|
|
|
|
# Setup logrotate for application logs
|
|
$SUDO_CMD tee "/etc/logrotate.d/$PROJECT_NAME" > /dev/null <<EOF
|
|
/var/log/pm2/*.log {
|
|
daily
|
|
missingok
|
|
rotate 52
|
|
compress
|
|
delaycompress
|
|
notifempty
|
|
create 644 $SERVICE_USER $SERVICE_USER
|
|
postrotate
|
|
pm2 reloadLogs
|
|
endscript
|
|
}
|
|
EOF
|
|
|
|
print_success "Monitoring tools installed"
|
|
}
|
|
|
|
# Function to create backup script
|
|
create_backup_script() {
|
|
print_step "Creating backup script..."
|
|
|
|
$SUDO_CMD tee "/usr/local/bin/backup-$PROJECT_NAME" > /dev/null <<EOF
|
|
#!/bin/bash
|
|
|
|
BACKUP_DATE=\$(date +%Y%m%d_%H%M%S)
|
|
BACKUP_PATH="$BACKUP_DIR/backup_\$BACKUP_DATE"
|
|
|
|
mkdir -p "\$BACKUP_PATH"
|
|
|
|
# Backup database
|
|
pg_dump -h localhost -U $DB_USER -d $DB_NAME > "\$BACKUP_PATH/database.sql"
|
|
|
|
# Backup application files
|
|
cp -r "$PROJECT_DIR" "\$BACKUP_PATH/app"
|
|
|
|
# Backup Nginx configuration
|
|
cp -r /etc/nginx/sites-available/$NGINX_CONFIG_NAME "\$BACKUP_PATH/nginx.conf"
|
|
|
|
# Compress backup
|
|
cd "$BACKUP_DIR"
|
|
tar -czf "backup_\$BACKUP_DATE.tar.gz" "backup_\$BACKUP_DATE"
|
|
rm -rf "backup_\$BACKUP_DATE"
|
|
|
|
# Keep only last 7 days of backups
|
|
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete
|
|
|
|
echo "Backup completed: backup_\$BACKUP_DATE.tar.gz"
|
|
EOF
|
|
|
|
$SUDO_CMD chmod +x "/usr/local/bin/backup-$PROJECT_NAME"
|
|
|
|
# Setup daily backup cron job
|
|
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/backup-$PROJECT_NAME") | crontab -
|
|
|
|
print_success "Backup script created and scheduled"
|
|
}
|
|
|
|
# Function to setup deployment script
|
|
create_deployment_script() {
|
|
print_step "Creating deployment script for future updates..."
|
|
|
|
tee "$PROJECT_DIR/deploy-update.sh" > /dev/null <<EOF
|
|
#!/bin/bash
|
|
|
|
# Update deployment script for Laca City
|
|
set -e
|
|
|
|
PROJECT_DIR="$PROJECT_DIR"
|
|
|
|
# Check if running as root
|
|
if [ "\$(whoami)" = "root" ]; then
|
|
SUDO_CMD=""
|
|
else
|
|
SUDO_CMD="sudo"
|
|
fi
|
|
|
|
echo "🚀 Starting deployment update..."
|
|
|
|
# Stop applications
|
|
pm2 stop all
|
|
|
|
# Backup current version
|
|
/usr/local/bin/backup-$PROJECT_NAME
|
|
|
|
# Pull latest changes (if using git)
|
|
# git pull origin main
|
|
|
|
# Install dependencies
|
|
cd "\$PROJECT_DIR/frontend"
|
|
npm ci --production
|
|
|
|
cd "\$PROJECT_DIR/backend"
|
|
npm ci --production
|
|
|
|
# Build applications
|
|
cd "\$PROJECT_DIR/frontend"
|
|
npm run build
|
|
|
|
cd "\$PROJECT_DIR/backend"
|
|
npm run build
|
|
|
|
# Restart applications
|
|
pm2 restart all
|
|
|
|
# Reload Nginx
|
|
\$SUDO_CMD systemctl reload nginx
|
|
|
|
echo "✅ Deployment update completed!"
|
|
EOF
|
|
EOF
|
|
|
|
chmod +x "$PROJECT_DIR/deploy-update.sh"
|
|
|
|
print_success "Deployment script created"
|
|
}
|
|
|
|
# Function to perform final checks
|
|
final_checks() {
|
|
print_step "Performing final checks..."
|
|
|
|
# Check if services are running
|
|
if systemctl is-active --quiet nginx; then
|
|
print_success "✅ Nginx is running"
|
|
else
|
|
print_error "❌ Nginx is not running"
|
|
fi
|
|
|
|
if systemctl is-active --quiet postgresql; then
|
|
print_success "✅ PostgreSQL is running"
|
|
else
|
|
print_error "❌ PostgreSQL is not running"
|
|
fi
|
|
|
|
if systemctl is-active --quiet redis; then
|
|
print_success "✅ Redis is running"
|
|
else
|
|
print_error "❌ Redis is not running"
|
|
fi
|
|
|
|
# Check PM2 processes
|
|
if pm2 list | grep -q "online"; then
|
|
print_success "✅ PM2 applications are running"
|
|
else
|
|
print_error "❌ PM2 applications are not running"
|
|
fi
|
|
|
|
# Check domain accessibility
|
|
if curl -s -o /dev/null -w "%{http_code}" "https://$DOMAIN_NAME" | grep -q "200\|301\|302"; then
|
|
print_success "✅ Website is accessible at https://$DOMAIN_NAME"
|
|
else
|
|
print_warning "⚠️ Website might not be fully accessible yet. Please check DNS and SSL configuration."
|
|
fi
|
|
}
|
|
|
|
# Main deployment function
|
|
main() {
|
|
print_header "🚀 LACA CITY WEBSITE - VPS DEPLOYMENT"
|
|
|
|
# Check execution context and setup appropriate commands
|
|
if [ "$CURRENT_USER" = "root" ]; then
|
|
print_warning "Running as root user. Some operations will be adjusted accordingly."
|
|
SUDO_CMD=""
|
|
# Set a default non-root user for services
|
|
SERVICE_USER="www-data"
|
|
else
|
|
# Check if sudo is available
|
|
if ! sudo -n true 2>/dev/null; then
|
|
print_error "This script requires sudo access. Please ensure you can run sudo commands."
|
|
exit 1
|
|
fi
|
|
SUDO_CMD="sudo"
|
|
SERVICE_USER="$CURRENT_USER"
|
|
fi
|
|
|
|
# Collect configuration
|
|
if [ -z "$DOMAIN_NAME" ]; then
|
|
prompt_input "Enter your domain name (e.g., yourdomain.com)" DOMAIN_NAME
|
|
fi
|
|
|
|
if [ -z "$EMAIL" ]; then
|
|
prompt_input "Enter your email for SSL certificate" EMAIL
|
|
fi
|
|
|
|
if [ -z "$DB_PASSWORD" ]; then
|
|
prompt_input "Enter database password (leave empty to generate)" DB_PASSWORD
|
|
fi
|
|
|
|
print_status "Configuration:"
|
|
print_status "Domain: $DOMAIN_NAME"
|
|
print_status "Email: $EMAIL"
|
|
print_status "Project Directory: $PROJECT_DIR"
|
|
print_status "Frontend Port: $FRONTEND_PORT"
|
|
print_status "Backend Port: $BACKEND_PORT"
|
|
|
|
read -p "Continue with deployment? (y/N): " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
print_status "Deployment cancelled."
|
|
exit 0
|
|
fi
|
|
|
|
# Start deployment
|
|
print_header "STARTING DEPLOYMENT"
|
|
|
|
# Update system
|
|
print_step "Updating system packages..."
|
|
$SUDO_CMD apt update && $SUDO_CMD apt upgrade -y
|
|
|
|
# Install basic tools
|
|
print_step "Installing basic tools..."
|
|
$SUDO_CMD apt install -y curl wget git unzip software-properties-common apt-transport-https ca-certificates gnupg lsb-release openssl
|
|
|
|
# Setup firewall
|
|
setup_firewall
|
|
|
|
# Install Node.js
|
|
install_nodejs
|
|
|
|
# Setup databases
|
|
setup_postgresql
|
|
setup_redis
|
|
|
|
# Setup project
|
|
setup_project
|
|
|
|
# Create environment files
|
|
create_env_files
|
|
|
|
# Build applications
|
|
build_applications
|
|
|
|
# Setup Nginx
|
|
setup_nginx
|
|
|
|
# Setup SSL
|
|
setup_ssl
|
|
|
|
# Setup PM2
|
|
setup_pm2
|
|
|
|
# Setup monitoring
|
|
setup_monitoring
|
|
|
|
# Create backup script
|
|
create_backup_script
|
|
|
|
# Create deployment script
|
|
create_deployment_script
|
|
|
|
# Final checks
|
|
final_checks
|
|
|
|
print_header "🎉 DEPLOYMENT COMPLETED SUCCESSFULLY!"
|
|
|
|
echo -e "\n${GREEN}Your Laca City website is now deployed!${NC}\n"
|
|
echo -e "🌐 Website URL: ${CYAN}https://$DOMAIN_NAME${NC}"
|
|
echo -e "📊 PM2 Monitor: ${CYAN}pm2 monit${NC}"
|
|
echo -e "📝 Logs: ${CYAN}pm2 logs${NC}"
|
|
echo -e "🔄 Update: ${CYAN}$PROJECT_DIR/deploy-update.sh${NC}"
|
|
echo -e "💾 Backup: ${CYAN}/usr/local/bin/backup-$PROJECT_NAME${NC}"
|
|
|
|
echo -e "\n${YELLOW}Important Information:${NC}"
|
|
echo -e "📧 Database Password: ${RED}$DB_PASSWORD${NC} (save this!)"
|
|
echo -e "📁 Project Directory: $PROJECT_DIR"
|
|
echo -e "📁 Backup Directory: $BACKUP_DIR"
|
|
echo -e "🔧 Nginx Config: /etc/nginx/sites-available/$NGINX_CONFIG_NAME"
|
|
|
|
echo -e "\n${BLUE}Useful Commands:${NC}"
|
|
echo -e " pm2 list # View running processes"
|
|
echo -e " pm2 restart all # Restart all applications"
|
|
echo -e " pm2 logs # View application logs"
|
|
echo -e " $SUDO_CMD systemctl status nginx # Check Nginx status"
|
|
echo -e " $SUDO_CMD certbot renew --dry-run # Test SSL renewal"
|
|
|
|
print_success "Setup completed! Your website should be accessible at https://$DOMAIN_NAME"
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|