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
|
||||
# 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
|
||||
|
||||
@@ -92,7 +93,7 @@ create_systemd_service() {
|
||||
local working_dir="$4"
|
||||
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]
|
||||
Description=$description
|
||||
After=network.target
|
||||
@@ -110,31 +111,31 @@ Environment=NODE_ENV=production
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable "$service_name"
|
||||
$SUDO_CMD systemctl daemon-reload
|
||||
$SUDO_CMD 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
|
||||
$SUDO_CMD ufw --force reset
|
||||
$SUDO_CMD ufw default deny incoming
|
||||
$SUDO_CMD ufw default allow outgoing
|
||||
|
||||
# Allow SSH
|
||||
sudo ufw allow ssh
|
||||
sudo ufw allow 22
|
||||
$SUDO_CMD ufw allow ssh
|
||||
$SUDO_CMD ufw allow 22
|
||||
|
||||
# Allow HTTP and HTTPS
|
||||
sudo ufw allow 80
|
||||
sudo ufw allow 443
|
||||
$SUDO_CMD ufw allow 80
|
||||
$SUDO_CMD ufw allow 443
|
||||
|
||||
# Allow specific ports for development (optional)
|
||||
sudo ufw allow $FRONTEND_PORT
|
||||
sudo ufw allow $BACKEND_PORT
|
||||
$SUDO_CMD ufw allow $FRONTEND_PORT
|
||||
$SUDO_CMD ufw allow $BACKEND_PORT
|
||||
|
||||
sudo ufw --force enable
|
||||
$SUDO_CMD ufw --force enable
|
||||
|
||||
print_success "Firewall configured"
|
||||
}
|
||||
@@ -143,14 +144,14 @@ setup_firewall() {
|
||||
setup_nginx() {
|
||||
print_step "Setting up Nginx..."
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y nginx
|
||||
$SUDO_CMD apt update
|
||||
$SUDO_CMD apt install -y nginx
|
||||
|
||||
# Remove default configuration
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
$SUDO_CMD rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# 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 frontend {
|
||||
server 127.0.0.1:$FRONTEND_PORT;
|
||||
@@ -245,10 +246,10 @@ server {
|
||||
EOF
|
||||
|
||||
# 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
|
||||
sudo nginx -t
|
||||
$SUDO_CMD nginx -t
|
||||
|
||||
print_success "Nginx configured"
|
||||
}
|
||||
@@ -258,20 +259,20 @@ setup_ssl() {
|
||||
print_step "Setting up SSL certificate with Let's Encrypt..."
|
||||
|
||||
# Install Certbot
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
$SUDO_CMD apt install -y certbot python3-certbot-nginx
|
||||
|
||||
# Stop Nginx temporarily
|
||||
sudo systemctl stop nginx
|
||||
$SUDO_CMD systemctl stop nginx
|
||||
|
||||
# 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
|
||||
sudo systemctl start nginx
|
||||
sudo systemctl enable nginx
|
||||
$SUDO_CMD systemctl start nginx
|
||||
$SUDO_CMD systemctl enable nginx
|
||||
|
||||
# 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"
|
||||
}
|
||||
@@ -280,12 +281,12 @@ setup_ssl() {
|
||||
setup_postgresql() {
|
||||
print_step "Setting up PostgreSQL..."
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y postgresql postgresql-contrib
|
||||
$SUDO_CMD apt update
|
||||
$SUDO_CMD apt install -y postgresql postgresql-contrib
|
||||
|
||||
# Start and enable PostgreSQL
|
||||
sudo systemctl start postgresql
|
||||
sudo systemctl enable postgresql
|
||||
$SUDO_CMD systemctl start postgresql
|
||||
$SUDO_CMD systemctl enable postgresql
|
||||
|
||||
# Generate database password if not provided
|
||||
if [ -z "$DB_PASSWORD" ]; then
|
||||
@@ -294,13 +295,23 @@ setup_postgresql() {
|
||||
fi
|
||||
|
||||
# Create database and user
|
||||
sudo -u postgres psql <<EOF
|
||||
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"
|
||||
}
|
||||
@@ -309,14 +320,14 @@ EOF
|
||||
setup_redis() {
|
||||
print_step "Setting up Redis..."
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y redis-server
|
||||
$SUDO_CMD apt update
|
||||
$SUDO_CMD apt install -y redis-server
|
||||
|
||||
# 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 systemctl enable redis.service
|
||||
$SUDO_CMD systemctl restart redis.service
|
||||
$SUDO_CMD systemctl enable redis.service
|
||||
|
||||
print_success "Redis configured"
|
||||
}
|
||||
@@ -326,11 +337,11 @@ 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
|
||||
curl -fsSL https://deb.nodesource.com/setup_18.x | $SUDO_CMD -E bash -
|
||||
$SUDO_CMD apt-get install -y nodejs
|
||||
|
||||
# Install PM2 globally
|
||||
sudo npm install -g pm2
|
||||
$SUDO_CMD npm install -g pm2
|
||||
|
||||
print_success "Node.js and PM2 installed"
|
||||
}
|
||||
@@ -340,12 +351,12 @@ setup_project() {
|
||||
print_step "Setting up project files..."
|
||||
|
||||
# Create project directory
|
||||
sudo mkdir -p "$PROJECT_DIR"
|
||||
sudo mkdir -p "$BACKUP_DIR"
|
||||
$SUDO_CMD mkdir -p "$PROJECT_DIR"
|
||||
$SUDO_CMD 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"
|
||||
$SUDO_CMD cp -r ./* "$PROJECT_DIR/" 2>/dev/null || true
|
||||
$SUDO_CMD chown -R "$SERVICE_USER:$SERVICE_USER" "$PROJECT_DIR"
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
@@ -447,7 +458,9 @@ module.exports = {
|
||||
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'
|
||||
min_uptime: '10s',
|
||||
uid: '$SERVICE_USER',
|
||||
gid: '$SERVICE_USER'
|
||||
},
|
||||
{
|
||||
name: 'laca-city-frontend',
|
||||
@@ -464,15 +477,17 @@ module.exports = {
|
||||
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'
|
||||
min_uptime: '10s',
|
||||
uid: '$SERVICE_USER',
|
||||
gid: '$SERVICE_USER'
|
||||
}
|
||||
]
|
||||
};
|
||||
EOF
|
||||
|
||||
# Create log directory
|
||||
sudo mkdir -p /var/log/pm2
|
||||
sudo chown -R "$CURRENT_USER:$CURRENT_USER" /var/log/pm2
|
||||
$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
|
||||
@@ -487,10 +502,10 @@ setup_monitoring() {
|
||||
print_step "Setting up monitoring..."
|
||||
|
||||
# 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
|
||||
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 {
|
||||
daily
|
||||
missingok
|
||||
@@ -498,7 +513,7 @@ setup_monitoring() {
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 644 $CURRENT_USER $CURRENT_USER
|
||||
create 644 $SERVICE_USER $SERVICE_USER
|
||||
postrotate
|
||||
pm2 reloadLogs
|
||||
endscript
|
||||
@@ -512,7 +527,7 @@ EOF
|
||||
create_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
|
||||
|
||||
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"
|
||||
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
|
||||
(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"
|
||||
|
||||
# Check if running as root
|
||||
if [ "\$(whoami)" = "root" ]; then
|
||||
SUDO_CMD=""
|
||||
else
|
||||
SUDO_CMD="sudo"
|
||||
fi
|
||||
|
||||
echo "🚀 Starting deployment update..."
|
||||
|
||||
# Stop applications
|
||||
@@ -589,9 +611,10 @@ npm run build
|
||||
pm2 restart all
|
||||
|
||||
# Reload Nginx
|
||||
sudo systemctl reload nginx
|
||||
\$SUDO_CMD systemctl reload nginx
|
||||
|
||||
echo "✅ Deployment update completed!"
|
||||
EOF
|
||||
EOF
|
||||
|
||||
chmod +x "$PROJECT_DIR/deploy-update.sh"
|
||||
@@ -641,16 +664,20 @@ final_checks() {
|
||||
main() {
|
||||
print_header "🚀 LACA CITY WEBSITE - VPS DEPLOYMENT"
|
||||
|
||||
# Check if running as root
|
||||
# Check execution context and setup appropriate commands
|
||||
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
|
||||
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
|
||||
@@ -685,11 +712,11 @@ main() {
|
||||
|
||||
# Update system
|
||||
print_step "Updating system packages..."
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
$SUDO_CMD apt update && $SUDO_CMD 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
|
||||
$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
|
||||
@@ -750,8 +777,8 @@ main() {
|
||||
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"
|
||||
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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user