feat: Update deployment script to support root user execution
- 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
This commit is contained in:
157
vps-deploy.sh
157
vps-deploy.sh
@@ -3,6 +3,7 @@
|
|||||||
# 🚀 Laca City Website - Complete VPS Deployment Script
|
# 🚀 Laca City Website - Complete VPS Deployment Script
|
||||||
# This script sets up your entire website on a VPS with domain configuration
|
# This script sets up your entire website on a VPS with domain configuration
|
||||||
# Run this script on your VPS after uploading your project files
|
# 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
|
set -e
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ create_systemd_service() {
|
|||||||
local working_dir="$4"
|
local working_dir="$4"
|
||||||
local user="$5"
|
local user="$5"
|
||||||
|
|
||||||
sudo tee "/etc/systemd/system/$service_name.service" > /dev/null <<EOF
|
$SUDO_CMD tee "/etc/systemd/system/$service_name.service" > /dev/null <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=$description
|
Description=$description
|
||||||
After=network.target
|
After=network.target
|
||||||
@@ -110,31 +111,31 @@ Environment=NODE_ENV=production
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
$SUDO_CMD systemctl daemon-reload
|
||||||
sudo systemctl enable "$service_name"
|
$SUDO_CMD systemctl enable "$service_name"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to setup firewall
|
# Function to setup firewall
|
||||||
setup_firewall() {
|
setup_firewall() {
|
||||||
print_step "Setting up UFW firewall..."
|
print_step "Setting up UFW firewall..."
|
||||||
|
|
||||||
sudo ufw --force reset
|
$SUDO_CMD ufw --force reset
|
||||||
sudo ufw default deny incoming
|
$SUDO_CMD ufw default deny incoming
|
||||||
sudo ufw default allow outgoing
|
$SUDO_CMD ufw default allow outgoing
|
||||||
|
|
||||||
# Allow SSH
|
# Allow SSH
|
||||||
sudo ufw allow ssh
|
$SUDO_CMD ufw allow ssh
|
||||||
sudo ufw allow 22
|
$SUDO_CMD ufw allow 22
|
||||||
|
|
||||||
# Allow HTTP and HTTPS
|
# Allow HTTP and HTTPS
|
||||||
sudo ufw allow 80
|
$SUDO_CMD ufw allow 80
|
||||||
sudo ufw allow 443
|
$SUDO_CMD ufw allow 443
|
||||||
|
|
||||||
# Allow specific ports for development (optional)
|
# Allow specific ports for development (optional)
|
||||||
sudo ufw allow $FRONTEND_PORT
|
$SUDO_CMD ufw allow $FRONTEND_PORT
|
||||||
sudo ufw allow $BACKEND_PORT
|
$SUDO_CMD ufw allow $BACKEND_PORT
|
||||||
|
|
||||||
sudo ufw --force enable
|
$SUDO_CMD ufw --force enable
|
||||||
|
|
||||||
print_success "Firewall configured"
|
print_success "Firewall configured"
|
||||||
}
|
}
|
||||||
@@ -143,14 +144,14 @@ setup_firewall() {
|
|||||||
setup_nginx() {
|
setup_nginx() {
|
||||||
print_step "Setting up Nginx..."
|
print_step "Setting up Nginx..."
|
||||||
|
|
||||||
sudo apt update
|
$SUDO_CMD apt update
|
||||||
sudo apt install -y nginx
|
$SUDO_CMD apt install -y nginx
|
||||||
|
|
||||||
# Remove default configuration
|
# Remove default configuration
|
||||||
sudo rm -f /etc/nginx/sites-enabled/default
|
$SUDO_CMD rm -f /etc/nginx/sites-enabled/default
|
||||||
|
|
||||||
# Create Nginx configuration
|
# Create Nginx configuration
|
||||||
sudo tee "/etc/nginx/sites-available/$NGINX_CONFIG_NAME" > /dev/null <<EOF
|
$SUDO_CMD tee "/etc/nginx/sites-available/$NGINX_CONFIG_NAME" > /dev/null <<EOF
|
||||||
# Upstream servers
|
# Upstream servers
|
||||||
upstream frontend {
|
upstream frontend {
|
||||||
server 127.0.0.1:$FRONTEND_PORT;
|
server 127.0.0.1:$FRONTEND_PORT;
|
||||||
@@ -245,10 +246,10 @@ server {
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Enable the site
|
# Enable the site
|
||||||
sudo ln -sf "/etc/nginx/sites-available/$NGINX_CONFIG_NAME" "/etc/nginx/sites-enabled/"
|
$SUDO_CMD ln -sf "/etc/nginx/sites-available/$NGINX_CONFIG_NAME" "/etc/nginx/sites-enabled/"
|
||||||
|
|
||||||
# Test Nginx configuration
|
# Test Nginx configuration
|
||||||
sudo nginx -t
|
$SUDO_CMD nginx -t
|
||||||
|
|
||||||
print_success "Nginx configured"
|
print_success "Nginx configured"
|
||||||
}
|
}
|
||||||
@@ -258,20 +259,20 @@ setup_ssl() {
|
|||||||
print_step "Setting up SSL certificate with Let's Encrypt..."
|
print_step "Setting up SSL certificate with Let's Encrypt..."
|
||||||
|
|
||||||
# Install Certbot
|
# Install Certbot
|
||||||
sudo apt install -y certbot python3-certbot-nginx
|
$SUDO_CMD apt install -y certbot python3-certbot-nginx
|
||||||
|
|
||||||
# Stop Nginx temporarily
|
# Stop Nginx temporarily
|
||||||
sudo systemctl stop nginx
|
$SUDO_CMD systemctl stop nginx
|
||||||
|
|
||||||
# Obtain SSL certificate
|
# Obtain SSL certificate
|
||||||
sudo certbot --nginx -d "$DOMAIN_NAME" -d "www.$DOMAIN_NAME" --email "$EMAIL" --agree-tos --non-interactive
|
$SUDO_CMD certbot --nginx -d "$DOMAIN_NAME" -d "www.$DOMAIN_NAME" --email "$EMAIL" --agree-tos --non-interactive
|
||||||
|
|
||||||
# Start Nginx
|
# Start Nginx
|
||||||
sudo systemctl start nginx
|
$SUDO_CMD systemctl start nginx
|
||||||
sudo systemctl enable nginx
|
$SUDO_CMD systemctl enable nginx
|
||||||
|
|
||||||
# Setup automatic renewal
|
# Setup automatic renewal
|
||||||
sudo crontab -l 2>/dev/null | { cat; echo "0 3 * * * /usr/bin/certbot renew --quiet"; } | sudo crontab -
|
$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"
|
print_success "SSL certificate configured and auto-renewal setup"
|
||||||
}
|
}
|
||||||
@@ -280,12 +281,12 @@ setup_ssl() {
|
|||||||
setup_postgresql() {
|
setup_postgresql() {
|
||||||
print_step "Setting up PostgreSQL..."
|
print_step "Setting up PostgreSQL..."
|
||||||
|
|
||||||
sudo apt update
|
$SUDO_CMD apt update
|
||||||
sudo apt install -y postgresql postgresql-contrib
|
$SUDO_CMD apt install -y postgresql postgresql-contrib
|
||||||
|
|
||||||
# Start and enable PostgreSQL
|
# Start and enable PostgreSQL
|
||||||
sudo systemctl start postgresql
|
$SUDO_CMD systemctl start postgresql
|
||||||
sudo systemctl enable postgresql
|
$SUDO_CMD systemctl enable postgresql
|
||||||
|
|
||||||
# Generate database password if not provided
|
# Generate database password if not provided
|
||||||
if [ -z "$DB_PASSWORD" ]; then
|
if [ -z "$DB_PASSWORD" ]; then
|
||||||
@@ -294,13 +295,23 @@ setup_postgresql() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Create database and user
|
# Create database and user
|
||||||
sudo -u postgres psql <<EOF
|
if [ "$CURRENT_USER" = "root" ]; then
|
||||||
|
su - postgres -c "psql" <<EOF
|
||||||
CREATE DATABASE $DB_NAME;
|
CREATE DATABASE $DB_NAME;
|
||||||
CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASSWORD';
|
CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASSWORD';
|
||||||
GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
|
GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
|
||||||
ALTER USER $DB_USER CREATEDB;
|
ALTER USER $DB_USER CREATEDB;
|
||||||
\q
|
\q
|
||||||
EOF
|
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"
|
print_success "PostgreSQL configured"
|
||||||
}
|
}
|
||||||
@@ -309,14 +320,14 @@ EOF
|
|||||||
setup_redis() {
|
setup_redis() {
|
||||||
print_step "Setting up Redis..."
|
print_step "Setting up Redis..."
|
||||||
|
|
||||||
sudo apt update
|
$SUDO_CMD apt update
|
||||||
sudo apt install -y redis-server
|
$SUDO_CMD apt install -y redis-server
|
||||||
|
|
||||||
# Configure Redis
|
# Configure Redis
|
||||||
sudo sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
|
$SUDO_CMD sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
|
||||||
|
|
||||||
sudo systemctl restart redis.service
|
$SUDO_CMD systemctl restart redis.service
|
||||||
sudo systemctl enable redis.service
|
$SUDO_CMD systemctl enable redis.service
|
||||||
|
|
||||||
print_success "Redis configured"
|
print_success "Redis configured"
|
||||||
}
|
}
|
||||||
@@ -326,11 +337,11 @@ install_nodejs() {
|
|||||||
print_step "Installing Node.js..."
|
print_step "Installing Node.js..."
|
||||||
|
|
||||||
# Install Node.js 18.x
|
# Install Node.js 18.x
|
||||||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
curl -fsSL https://deb.nodesource.com/setup_18.x | $SUDO_CMD -E bash -
|
||||||
sudo apt-get install -y nodejs
|
$SUDO_CMD apt-get install -y nodejs
|
||||||
|
|
||||||
# Install PM2 globally
|
# Install PM2 globally
|
||||||
sudo npm install -g pm2
|
$SUDO_CMD npm install -g pm2
|
||||||
|
|
||||||
print_success "Node.js and PM2 installed"
|
print_success "Node.js and PM2 installed"
|
||||||
}
|
}
|
||||||
@@ -340,12 +351,12 @@ setup_project() {
|
|||||||
print_step "Setting up project files..."
|
print_step "Setting up project files..."
|
||||||
|
|
||||||
# Create project directory
|
# Create project directory
|
||||||
sudo mkdir -p "$PROJECT_DIR"
|
$SUDO_CMD mkdir -p "$PROJECT_DIR"
|
||||||
sudo mkdir -p "$BACKUP_DIR"
|
$SUDO_CMD mkdir -p "$BACKUP_DIR"
|
||||||
|
|
||||||
# Copy files to project directory (assuming current directory has the project)
|
# Copy files to project directory (assuming current directory has the project)
|
||||||
sudo cp -r ./* "$PROJECT_DIR/" 2>/dev/null || true
|
$SUDO_CMD cp -r ./* "$PROJECT_DIR/" 2>/dev/null || true
|
||||||
sudo chown -R "$CURRENT_USER:$CURRENT_USER" "$PROJECT_DIR"
|
$SUDO_CMD chown -R "$SERVICE_USER:$SERVICE_USER" "$PROJECT_DIR"
|
||||||
|
|
||||||
cd "$PROJECT_DIR"
|
cd "$PROJECT_DIR"
|
||||||
|
|
||||||
@@ -447,7 +458,9 @@ module.exports = {
|
|||||||
out_file: '/var/log/pm2/laca-city-backend-out.log',
|
out_file: '/var/log/pm2/laca-city-backend-out.log',
|
||||||
log_file: '/var/log/pm2/laca-city-backend.log',
|
log_file: '/var/log/pm2/laca-city-backend.log',
|
||||||
max_restarts: 10,
|
max_restarts: 10,
|
||||||
min_uptime: '10s'
|
min_uptime: '10s',
|
||||||
|
uid: '$SERVICE_USER',
|
||||||
|
gid: '$SERVICE_USER'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'laca-city-frontend',
|
name: 'laca-city-frontend',
|
||||||
@@ -464,15 +477,17 @@ module.exports = {
|
|||||||
out_file: '/var/log/pm2/laca-city-frontend-out.log',
|
out_file: '/var/log/pm2/laca-city-frontend-out.log',
|
||||||
log_file: '/var/log/pm2/laca-city-frontend.log',
|
log_file: '/var/log/pm2/laca-city-frontend.log',
|
||||||
max_restarts: 10,
|
max_restarts: 10,
|
||||||
min_uptime: '10s'
|
min_uptime: '10s',
|
||||||
|
uid: '$SERVICE_USER',
|
||||||
|
gid: '$SERVICE_USER'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create log directory
|
# Create log directory
|
||||||
sudo mkdir -p /var/log/pm2
|
$SUDO_CMD mkdir -p /var/log/pm2
|
||||||
sudo chown -R "$CURRENT_USER:$CURRENT_USER" /var/log/pm2
|
$SUDO_CMD chown -R "$SERVICE_USER:$SERVICE_USER" /var/log/pm2
|
||||||
|
|
||||||
# Start applications with PM2
|
# Start applications with PM2
|
||||||
pm2 start ecosystem.config.js
|
pm2 start ecosystem.config.js
|
||||||
@@ -487,10 +502,10 @@ setup_monitoring() {
|
|||||||
print_step "Setting up monitoring..."
|
print_step "Setting up monitoring..."
|
||||||
|
|
||||||
# Install htop and other monitoring tools
|
# Install htop and other monitoring tools
|
||||||
sudo apt install -y htop iotop nethogs
|
$SUDO_CMD apt install -y htop iotop nethogs
|
||||||
|
|
||||||
# Setup logrotate for application logs
|
# Setup logrotate for application logs
|
||||||
sudo tee "/etc/logrotate.d/$PROJECT_NAME" > /dev/null <<EOF
|
$SUDO_CMD tee "/etc/logrotate.d/$PROJECT_NAME" > /dev/null <<EOF
|
||||||
/var/log/pm2/*.log {
|
/var/log/pm2/*.log {
|
||||||
daily
|
daily
|
||||||
missingok
|
missingok
|
||||||
@@ -498,7 +513,7 @@ setup_monitoring() {
|
|||||||
compress
|
compress
|
||||||
delaycompress
|
delaycompress
|
||||||
notifempty
|
notifempty
|
||||||
create 644 $CURRENT_USER $CURRENT_USER
|
create 644 $SERVICE_USER $SERVICE_USER
|
||||||
postrotate
|
postrotate
|
||||||
pm2 reloadLogs
|
pm2 reloadLogs
|
||||||
endscript
|
endscript
|
||||||
@@ -512,7 +527,7 @@ EOF
|
|||||||
create_backup_script() {
|
create_backup_script() {
|
||||||
print_step "Creating backup script..."
|
print_step "Creating backup script..."
|
||||||
|
|
||||||
sudo tee "/usr/local/bin/backup-$PROJECT_NAME" > /dev/null <<EOF
|
$SUDO_CMD tee "/usr/local/bin/backup-$PROJECT_NAME" > /dev/null <<EOF
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
BACKUP_DATE=\$(date +%Y%m%d_%H%M%S)
|
BACKUP_DATE=\$(date +%Y%m%d_%H%M%S)
|
||||||
@@ -540,7 +555,7 @@ find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete
|
|||||||
echo "Backup completed: backup_\$BACKUP_DATE.tar.gz"
|
echo "Backup completed: backup_\$BACKUP_DATE.tar.gz"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
sudo chmod +x "/usr/local/bin/backup-$PROJECT_NAME"
|
$SUDO_CMD chmod +x "/usr/local/bin/backup-$PROJECT_NAME"
|
||||||
|
|
||||||
# Setup daily backup cron job
|
# Setup daily backup cron job
|
||||||
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/backup-$PROJECT_NAME") | crontab -
|
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/backup-$PROJECT_NAME") | crontab -
|
||||||
@@ -560,6 +575,13 @@ set -e
|
|||||||
|
|
||||||
PROJECT_DIR="$PROJECT_DIR"
|
PROJECT_DIR="$PROJECT_DIR"
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [ "\$(whoami)" = "root" ]; then
|
||||||
|
SUDO_CMD=""
|
||||||
|
else
|
||||||
|
SUDO_CMD="sudo"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "🚀 Starting deployment update..."
|
echo "🚀 Starting deployment update..."
|
||||||
|
|
||||||
# Stop applications
|
# Stop applications
|
||||||
@@ -589,9 +611,10 @@ npm run build
|
|||||||
pm2 restart all
|
pm2 restart all
|
||||||
|
|
||||||
# Reload Nginx
|
# Reload Nginx
|
||||||
sudo systemctl reload nginx
|
\$SUDO_CMD systemctl reload nginx
|
||||||
|
|
||||||
echo "✅ Deployment update completed!"
|
echo "✅ Deployment update completed!"
|
||||||
|
EOF
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
chmod +x "$PROJECT_DIR/deploy-update.sh"
|
chmod +x "$PROJECT_DIR/deploy-update.sh"
|
||||||
@@ -641,16 +664,20 @@ final_checks() {
|
|||||||
main() {
|
main() {
|
||||||
print_header "🚀 LACA CITY WEBSITE - VPS DEPLOYMENT"
|
print_header "🚀 LACA CITY WEBSITE - VPS DEPLOYMENT"
|
||||||
|
|
||||||
# Check if running as root
|
# Check execution context and setup appropriate commands
|
||||||
if [ "$CURRENT_USER" = "root" ]; then
|
if [ "$CURRENT_USER" = "root" ]; then
|
||||||
print_error "Please don't run this script as root. Run as a regular user with sudo access."
|
print_warning "Running as root user. Some operations will be adjusted accordingly."
|
||||||
exit 1
|
SUDO_CMD=""
|
||||||
fi
|
# Set a default non-root user for services
|
||||||
|
SERVICE_USER="www-data"
|
||||||
# Check if sudo is available
|
else
|
||||||
if ! sudo -n true 2>/dev/null; then
|
# Check if sudo is available
|
||||||
print_error "This script requires sudo access. Please ensure you can run sudo commands."
|
if ! sudo -n true 2>/dev/null; then
|
||||||
exit 1
|
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
|
fi
|
||||||
|
|
||||||
# Collect configuration
|
# Collect configuration
|
||||||
@@ -685,11 +712,11 @@ main() {
|
|||||||
|
|
||||||
# Update system
|
# Update system
|
||||||
print_step "Updating system packages..."
|
print_step "Updating system packages..."
|
||||||
sudo apt update && sudo apt upgrade -y
|
$SUDO_CMD apt update && $SUDO_CMD apt upgrade -y
|
||||||
|
|
||||||
# Install basic tools
|
# Install basic tools
|
||||||
print_step "Installing 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
|
$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
|
||||||
setup_firewall
|
setup_firewall
|
||||||
@@ -750,8 +777,8 @@ main() {
|
|||||||
echo -e " pm2 list # View running processes"
|
echo -e " pm2 list # View running processes"
|
||||||
echo -e " pm2 restart all # Restart all applications"
|
echo -e " pm2 restart all # Restart all applications"
|
||||||
echo -e " pm2 logs # View application logs"
|
echo -e " pm2 logs # View application logs"
|
||||||
echo -e " sudo systemctl status nginx # Check Nginx status"
|
echo -e " $SUDO_CMD systemctl status nginx # Check Nginx status"
|
||||||
echo -e " sudo certbot renew --dry-run # Test SSL renewal"
|
echo -e " $SUDO_CMD certbot renew --dry-run # Test SSL renewal"
|
||||||
|
|
||||||
print_success "Setup completed! Your website should be accessible at https://$DOMAIN_NAME"
|
print_success "Setup completed! Your website should be accessible at https://$DOMAIN_NAME"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user