Deploy Node.js App: PM2 and Nginx Guide
Complete guide to deploying Node.js applications on a VPS. Node.js installation with nvm, PM2 process manager, Nginx reverse proxy, SSL certificate, and environment variables management.
Guide to installing and optimizing WordPress on a VPS. LEMP stack setup, wp-config.php settings, file permissions, SSL, OPcache performance optimization, and security hardening.
WordPress is the most widely used content management system in the world. Running WordPress on a VPS instead of shared hosting gives you more control, better performance, and customization options. This guide covers WordPress installation, configuration, and optimization on a LEMP stack.
LEMP stack (Linux + Nginx + MySQL + PHP) is recommended for WordPress.
# System update
sudo apt update && sudo apt upgrade -y
# Install Nginx
sudo apt install nginx -y
sudo systemctl enable nginx
# Install MariaDB
sudo apt install mariadb-server -y
sudo systemctl enable mariadb
sudo mysql_secure_installation
# Install PHP 8.2 and required extensions for WordPress
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install php8.2 php8.2-fpm php8.2-mysql php8.2-xml php8.2-curl \
php8.2-mbstring php8.2-zip php8.2-gd php8.2-imagick php8.2-intl \
php8.2-bcmath php8.2-soap -y
sudo systemctl enable php8.2-fpm
sudo mysql -u root -p
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strong-password-here';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
# Download WordPress
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
# Move to web directory
sudo mv wordpress /var/www/mysite.com
# Set file permissions
sudo chown -R www-data:www-data /var/www/mysite.com
sudo find /var/www/mysite.com -type d -exec chmod 755 {} \;
sudo find /var/www/mysite.com -type f -exec chmod 644 {} \;
cd /var/www/mysite.com
sudo cp wp-config-sample.php wp-config.php
sudo nano wp-config.php
// Database settings
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wpuser' );
define( 'DB_PASSWORD', 'strong-password-here' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', 'utf8mb4_unicode_ci' );
// Security keys (get from https://api.wordpress.org/secret-key/1.1/salt/)
define('AUTH_KEY', 'unique-value-1');
define('SECURE_AUTH_KEY', 'unique-value-2');
// ... (add all 8 keys)
// Force SSL admin
define('FORCE_SSL_ADMIN', true);
// Disable file editing (security)
define('DISALLOW_FILE_EDIT', true);
// Memory limit
define('WP_MEMORY_LIMIT', '256M');
sudo nano /etc/nginx/sites-available/mysite.com
server {
listen 80;
server_name mysite.com www.mysite.com;
root /var/www/mysite.com;
index index.php;
# WordPress permalink structure
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Security: block xmlrpc.php
location = /xmlrpc.php {
deny all;
}
# Security: block wp-config.php
location = /wp-config.php {
deny all;
}
# Block hidden files
location ~ /\. {
deny all;
}
# Cache for static files
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
log_not_found off;
}
client_max_body_size 64M;
}
sudo ln -s /etc/nginx/sites-available/mysite.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d mysite.com -d www.mysite.com
; OPcache settings
opcache.enable = 1
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 2
opcache.save_comments = 1
; Recommended settings for WordPress
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_vars = 3000
sudo systemctl restart php8.2-fpm
# Secure wp-config.php permissions
sudo chmod 600 /var/www/mysite.com/wp-config.php
# Restrict wp-login.php by IP in Nginx
location = /wp-login.php {
allow 1.2.3.4; # Your IP address
deny all;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}
Set wp-config.php permissions to 600. This file contains your database password.
On REXE servers, at least 2 GB RAM is recommended for WordPress. For high-traffic sites, prefer 4 GB+ RAM and SSD storage.
Your WordPress site is now running on a LEMP stack on a VPS, secured with SSL and optimized with OPcache. Keep your site healthy with regular backups, security updates, and performance monitoring.
Check the DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST values in wp-config.php. Verify MySQL is running with 'sudo systemctl status mariadb'. Check that the user has access to the database with the SQL command 'SHOW GRANTS FOR wpuser@localhost;'.
Check that the try_files directive in your Nginx configuration is correct. Verify PHP-FPM is running with 'sudo systemctl status php8.2-fpm'. Review the Nginx error log with 'sudo tail -f /var/log/nginx/mysite.com.error.log'. If you have IP restrictions on wp-login.php, whitelist your own IP.
Increase upload_max_filesize and post_max_size in php.ini (e.g., 64M). Also increase client_max_body_size in Nginx to the same value. Restart PHP-FPM and Nginx. Add 'define("WP_MAX_MEMORY_LIMIT", "256M");' to wp-config.php.
Enable OPcache, use Nginx FastCGI cache. Install W3 Total Cache or WP Super Cache plugin. Use a CDN (Cloudflare). Add Smush or ShortPixel plugin for image optimization. Regularly optimize the database: 'wp db optimize' (with WP-CLI).
Complete guide to deploying Node.js applications on a VPS. Node.js installation with nvm, PM2 process manager, Nginx reverse proxy, SSL certificate, and environment variables management.
Complete guide to deploying PHP applications on a VPS. LAMP vs LEMP comparison, Apache/Nginx + PHP-FPM + MySQL setup, virtual host configuration, and PHP version management.
Guide to deploying Python/Django applications on a VPS. Virtualenv setup, Django production settings, Gunicorn WSGI server, Nginx reverse proxy, systemd service, and static file management.