🚀 Complete Laca City Website with VPS Deployment
- Added complete Next.js frontend with responsive design - Added NestJS backend with PostgreSQL and Redis - Added comprehensive VPS deployment script (vps-deploy.sh) - Added deployment guide and documentation - Added all assets and static files - Configured SSL, Nginx, PM2, and monitoring - Ready for production deployment on any VPS
This commit is contained in:
760
vps-deploy.sh
Executable file
760
vps-deploy.sh
Executable file
@@ -0,0 +1,760 @@
|
||||
#!/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
|
||||
|
||||
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 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 systemctl daemon-reload
|
||||
sudo systemctl enable "$service_name"
|
||||
}
|
||||
|
||||
# Function to setup firewall
|
||||
setup_firewall() {
|
||||
print_step "Setting up UFW firewall..."
|
||||
|
||||
sudo ufw --force reset
|
||||
sudo ufw default deny incoming
|
||||
sudo ufw default allow outgoing
|
||||
|
||||
# Allow SSH
|
||||
sudo ufw allow ssh
|
||||
sudo ufw allow 22
|
||||
|
||||
# Allow HTTP and HTTPS
|
||||
sudo ufw allow 80
|
||||
sudo ufw allow 443
|
||||
|
||||
# Allow specific ports for development (optional)
|
||||
sudo ufw allow $FRONTEND_PORT
|
||||
sudo ufw allow $BACKEND_PORT
|
||||
|
||||
sudo ufw --force enable
|
||||
|
||||
print_success "Firewall configured"
|
||||
}
|
||||
|
||||
# Function to setup Nginx
|
||||
setup_nginx() {
|
||||
print_step "Setting up Nginx..."
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y nginx
|
||||
|
||||
# Remove default configuration
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Create Nginx configuration
|
||||
sudo 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 ln -sf "/etc/nginx/sites-available/$NGINX_CONFIG_NAME" "/etc/nginx/sites-enabled/"
|
||||
|
||||
# Test Nginx configuration
|
||||
sudo 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 apt install -y certbot python3-certbot-nginx
|
||||
|
||||
# Stop Nginx temporarily
|
||||
sudo systemctl stop nginx
|
||||
|
||||
# Obtain SSL certificate
|
||||
sudo certbot --nginx -d "$DOMAIN_NAME" -d "www.$DOMAIN_NAME" --email "$EMAIL" --agree-tos --non-interactive
|
||||
|
||||
# Start Nginx
|
||||
sudo systemctl start nginx
|
||||
sudo systemctl enable nginx
|
||||
|
||||
# Setup automatic renewal
|
||||
sudo crontab -l 2>/dev/null | { cat; echo "0 3 * * * /usr/bin/certbot renew --quiet"; } | sudo crontab -
|
||||
|
||||
print_success "SSL certificate configured and auto-renewal setup"
|
||||
}
|
||||
|
||||
# Function to setup PostgreSQL
|
||||
setup_postgresql() {
|
||||
print_step "Setting up PostgreSQL..."
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y postgresql postgresql-contrib
|
||||
|
||||
# Start and enable PostgreSQL
|
||||
sudo systemctl start postgresql
|
||||
sudo 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
|
||||
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
|
||||
|
||||
print_success "PostgreSQL configured"
|
||||
}
|
||||
|
||||
# Function to setup Redis
|
||||
setup_redis() {
|
||||
print_step "Setting up Redis..."
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y redis-server
|
||||
|
||||
# Configure Redis
|
||||
sudo sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
|
||||
|
||||
sudo systemctl restart redis.service
|
||||
sudo 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 -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
# Install PM2 globally
|
||||
sudo 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 mkdir -p "$PROJECT_DIR"
|
||||
sudo mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Copy files to project directory (assuming current directory has the project)
|
||||
sudo cp -r ./* "$PROJECT_DIR/" 2>/dev/null || true
|
||||
sudo chown -R "$CURRENT_USER:$CURRENT_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'
|
||||
},
|
||||
{
|
||||
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'
|
||||
}
|
||||
]
|
||||
};
|
||||
EOF
|
||||
|
||||
# Create log directory
|
||||
sudo mkdir -p /var/log/pm2
|
||||
sudo chown -R "$CURRENT_USER:$CURRENT_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 apt install -y htop iotop nethogs
|
||||
|
||||
# Setup logrotate for application logs
|
||||
sudo tee "/etc/logrotate.d/$PROJECT_NAME" > /dev/null <<EOF
|
||||
/var/log/pm2/*.log {
|
||||
daily
|
||||
missingok
|
||||
rotate 52
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 644 $CURRENT_USER $CURRENT_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 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 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"
|
||||
|
||||
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 systemctl reload nginx
|
||||
|
||||
echo "✅ Deployment update completed!"
|
||||
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 if running as root
|
||||
if [ "$CURRENT_USER" = "root" ]; then
|
||||
print_error "Please don't run this script as root. Run as a regular user with sudo access."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
# 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 apt update && sudo apt upgrade -y
|
||||
|
||||
# Install basic tools
|
||||
print_step "Installing basic tools..."
|
||||
sudo 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 systemctl status nginx # Check Nginx status"
|
||||
echo -e " sudo certbot renew --dry-run # Test SSL renewal"
|
||||
|
||||
print_success "Setup completed! Your website should be accessible at https://$DOMAIN_NAME"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user