In this guide you’ll go from a completely fresh Ubuntu server to a fully working WordPress site — step by step. We’ll install and configure Nginx as the web server, PHP 8.3-FPM for processing, MySQL for the database, and finish off with a free Let’s Encrypt SSL certificate.
📋 Table of Contents
Before You Begin
Make sure the following are in place before starting:
| Requirement | Details |
|---|---|
| Ubuntu Server | 22.04 LTS or 24.04 LTS (fresh install recommended) |
| Root / Sudo Access | A non-root user with sudo privileges |
| Domain Name | Pointed to your server’s IP via an A record |
| RAM | At least 1 GB (2 GB+ recommended for production) |
All commands should be run as a sudo user. Prefix each command with sudo where shown.
Update Ubuntu & Upgrade Packages
Always start with a fully up-to-date system to ensure the latest security patches and package versions are in place.
# Refresh the package list sudo apt update # Upgrade all installed packages sudo apt upgrade -y # Install common utilities sudo apt install -y curl wget unzip git
If a kernel update was applied, reboot before continuing:
sudo reboot
After rebooting, reconnect via SSH and continue with the next step.
Install & Configure Nginx
Nginx is a high-performance web server that handles static files efficiently and proxies PHP requests to PHP-FPM.
# Install Nginx sudo apt install -y nginx # Start Nginx and enable it on boot sudo systemctl start nginx sudo systemctl enable nginx # Verify it's running sudo systemctl status nginx
Allow Nginx Through the Firewall
# Allow HTTP and HTTPS traffic sudo ufw allow 'Nginx Full' # Enable UFW if not already active sudo ufw enable sudo ufw status
Visit your server’s IP in a browser — you should see the default Nginx welcome page.
Install PHP-FPM & Extensions
WordPress requires PHP-FPM along with several extensions for full functionality.
# Add the PHP PPA for the latest PHP version sudo apt install -y software-properties-common sudo add-apt-repository ppa:ondrej/php -y sudo apt update # Install PHP 8.3 and required WordPress extensions sudo apt install -y php8.3-fpm php8.3-mysql php8.3-xml \ php8.3-mbstring php8.3-curl php8.3-zip php8.3-gd \ php8.3-intl php8.3-bcmath php8.3-imagick # Verify the installation php -v
Tune PHP-FPM Settings
Open the PHP config to raise upload limits and memory:
sudo nano /etc/php/8.3/fpm/php.ini
Find and update these lines:
upload_max_filesize = 64M post_max_size = 64M memory_limit = 256M max_execution_time = 300 max_input_time = 300
# Restart PHP-FPM to apply changes
sudo systemctl restart php8.3-fpm
sudo systemctl enable php8.3-fpmInstall MySQL Server
WordPress stores all its content — posts, pages, users, and settings — in a MySQL database.
# Install MySQL server sudo apt install -y mysql-server # Start and enable MySQL sudo systemctl start mysql sudo systemctl enable mysql # Run the security hardening script sudo mysql_secure_installation
The mysql_secure_installation script will ask several questions. Answer Yes to all: set a strong root password, remove anonymous users, disallow remote root login, and remove the test database.
Create the WordPress Database & User
Log in to MySQL and create a dedicated database and user for WordPress. Never use the root account for your site.
sudo mysql -u root -p
Once inside the MySQL prompt, run these SQL commands:
-- Create the database CREATE DATABASE wordpress_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- Create a dedicated user (use a strong password!) CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'YourStrongPassword123!'; -- Grant all privileges on the WordPress database GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wp_user'@'localhost'; -- Apply the changes and exit FLUSH PRIVILEGES; EXIT;
Note down the database name (wordpress_db), username (wp_user), and password — you’ll need them in the next steps.
Download & Extract WordPress
Download the latest WordPress package from the official website and move it to your web root directory.
# Move to a temp directory and download WordPress cd /tmp wget https://wordpress.org/latest.tar.gz # Extract the archive tar -xzf latest.tar.gz # Move to the web root (replace yourdomain.com) sudo mv wordpress /var/www/yourdomain.com # Create the uploads directory sudo mkdir -p /var/www/yourdomain.com/wp-content/uploads
Configure wp-config.php
Create wp-config.php from the sample file and fill in your database credentials.
# Copy the sample config sudo cp /var/www/yourdomain.com/wp-config-sample.php \ /var/www/yourdomain.com/wp-config.php # Open it for editing sudo nano /var/www/yourdomain.com/wp-config.php
Update these lines with your database credentials:
define( 'DB_NAME', 'wordpress_db' ); define( 'DB_USER', 'wp_user' ); define( 'DB_PASSWORD', 'YourStrongPassword123!' ); define( 'DB_HOST', 'localhost' ); define( 'DB_CHARSET', 'utf8mb4' );
Generate Fresh Secret Keys
Replace the placeholder secret keys with fresh ones from the WordPress.org API:
# Fetch new secret keys
curl -s https://api.wordpress.org/secret-key/1.1/salt/Copy the output and replace the corresponding lines in wp-config.php. Save and close the file.
Create the Nginx Server Block
Create a dedicated Nginx configuration file that tells the server how to handle requests for your domain.
sudo nano /etc/nginx/sites-available/yourdomain.com
Paste this complete server block:
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/yourdomain.com;
index index.php index.html index.htm;
# WordPress pretty permalinks
location / {
try_files $uri $uri/ /index.php?$args;
}
# Pass PHP requests to PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Block access to hidden files
location ~ /\. {
deny all;
}
# Cache static assets
location ~* \.(jpg|jpeg|gif|png|svg|ico|css|js|woff2?)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
client_max_body_size 64M;
}# Enable the site sudo ln -s /etc/nginx/sites-available/yourdomain.com \ /etc/nginx/sites-enabled/ # Test for syntax errors sudo nginx -t # Reload Nginx sudo systemctl reload nginx
Set Correct File Permissions
WordPress needs proper ownership and permissions so it can write to directories like wp-content/uploads.
# Give Nginx's user ownership of the files sudo chown -R www-data:www-data /var/www/yourdomain.com # Directories: 755 sudo find /var/www/yourdomain.com -type d -exec chmod 755 {} \; # Files: 644 sudo find /var/www/yourdomain.com -type f -exec chmod 644 {} \; # Protect wp-config.php sudo chmod 600 /var/www/yourdomain.com/wp-config.php
Never set permissions to 777 on a production server — it is a serious security risk.
Enable SSL with Let’s Encrypt (Certbot)
Every site should run over HTTPS. Let’s Encrypt provides free certificates, and Certbot handles the entire process automatically.
# Install Certbot and the Nginx plugin sudo apt install -y certbot python3-certbot-nginx # Obtain and install the certificate sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com # Test automatic renewal sudo certbot renew --dry-run
Certbot automatically updates your Nginx config to redirect HTTP → HTTPS. Your site will now be live at https://yourdomain.com.
Certbot installs a systemd timer that auto-renews your certificate before it expires. No manual action is needed after the initial setup.
Complete the WordPress Setup Wizard
Open your browser and go to:
https://yourdomain.com/wp-admin/install.php
The setup wizard will walk you through the final steps:
- Select your language
- Enter your site title and admin email address
- Create a secure admin username and password
- Click “Install WordPress”
Once complete, log in to your dashboard at https://yourdomain.com/wp-admin. Your WordPress site is live! 🎉
Recommended Post-Install Steps
- Install a caching plugin (e.g., W3 Total Cache or LiteSpeed Cache)
- Enable automatic updates for WordPress core and plugins
- Set up automated daily database backups
- Install a security plugin such as Wordfence
- Go to Settings → Permalinks and select a clean URL structure
- Change the default login URL to reduce brute-force attacks
If you see a 502 Bad Gateway error, verify the PHP-FPM socket path in your Nginx config matches the installed version. Run ls /run/php/ to confirm the correct socket filename.





