Estimated reading time: 15 min
Introduction
This note documents the process of deploying a WordPress website using the LEMP stack. Before we start, let's briefly understand what LEMP and WordPress are.
LEMP is an acronym that stands for Linux, Nginx (pronounced "Engine-X"), MySQL/MariaDB, and PHP. It is a powerful and efficient software stack. Of course, another popular stack is the LAMP stack, which replaces Nginx with Apache, but I went directly with Nginx due to limited resources.
In this deployment, we are using Ubuntu 20.04 as the server operating system. We set up a blog site by building LEMP and then installing WordPress.
WordPress is the world's most popular content management system (CMS). It allows users to create, manage, and publish content online without advanced technical skills. WordPress is known for its simplicity, flexibility, and vast ecosystem of themes and plugins. There are also other options, such as Ghost, or direct hosting on Github.
In this guide, I will walk you through my process of setting up a WordPress site on the LEMP stack and try to avoid potential problems as much as possible.
Let's get started!
Installing and Configuring the LEMP Stack
Before we install WordPress, we need to set up the LEMP stack on our Linux server. Here, I'm skipping over the installation and configuration of Ubuntu, assuming you already have an Ubuntu 20.04 server set up.
Installing and configuring Nginx
To install Nginx on Ubuntu 20.04, follow these steps:
-
Open your terminal or connect to your server via SSH.
-
Update the package lists to ensure you get the latest version of the software by running the following command:
sudo apt update
-
Install Nginx by running the following command:
sudo apt install nginx
-
Once the installation is complete, you can check the status of Nginx to ensure it is running:
sudo systemctl status nginx
If Nginx is not running, you can start it with:
sudo systemctl start nginx
And don't forget to ensure Nginx starts automatically upon server reboot:
sudo systemctl is-enabled nginx
If not, enable it using the following command:
sudo systemctl enable nginx
-
You can now test if Nginx is properly installed and running by navigating to your server's IP address in a web browser. You should see the default Nginx welcome page.
Note: Don't forget to configure the firewall to ensure incoming traffic can access your server normally. While Ubuntu commonly uses UFW (Uncomplicated Firewall), I am more familiar with iptables, so I'll provide the firewall rules using iptables as an example. To allow HTTP traffic on port 80, which is what Nginx uses by default, you can add a rule to iptables by executing the following command:
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
This command tells the firewall to accept incoming TCP traffic on port 80, which is necessary for accessing the Nginx server through a web browser.
-
Configure Nginx to serve your WordPress site. To do this, you'll need to create a new virtual host configuration file in the /etc/nginx/sites-available directory.
cd /etc/nginx/sites-available/
-
Create a new configuration file for your WordPress site. Replace blog.your_domain with your actual domain name:
sudo vim blog.your_domain.conf
This guide assumes familiarity with vim as a text editor. If not, you might want to use a more straightforward editor like nano or refer to a basic vim tutorial before proceeding.
-
In the new file, add the following server block. This configuration is for a basic WordPress site. Be sure to replace your_domain with your actual domain name and /var/www/your_domain or /var/www/html/your_domain with the correct path where WordPress will be installed later on:
server { listen 80; server_name blog.your_domain; # Specify the directory where your WordPress is (or will be) installed. root /var/www/blog.your_domain; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$args; } # PHP processing section: Configure the handling of .php files. location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # Security: Deny access to hidden files and directories (those that begin with a dot). location ~ /\.ht { deny all; } # While Nginx does not use these files, this rule prevents accidental exposure of sensitive information if such files exist. You may use a different set of rules if you prefer. # location ~ /\. { # deny all; # } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } }
-
Save and close the file, then ensure that the nginx.conf includes the configuration
include /etc/nginx/sites-enabled/*;
to read files from this directory. After that, enable the site by creating a symbolic link of your site's configuration file from sites-available to sites-enabled.:sudo ln -s /etc/nginx/sites-available/blog.your_domain /etc/nginx/sites-enabled/
-
Test your Nginx configuration to ensure proper syntax.
sudo nginx -t
-
If the test is successful, reload Nginx and apply the changes, otherwise you should first address any reported syntax errors and retest until the configuration is correct:
sudo systemctl reload nginx
When you use the command
sudo systemctl reload nginx
orsudo nginx -s reload
, you are instructing Nginx to reload it's configuration files without interrupting ongoing connections (soft reload). This is particularly useful for applying changes smoothly without affecting current visitors to your site.
On the other hand, using a restart command (such assudo systemctl restart nginx
) will completely stop and then start the Nginx service again. This approach can briefly interrupt active connections, making it less suitable for changes that need to be applied without impacting site availability.
For updates like modifying configuration files,reload
is usually the preferred method as it updates the configuration without impacting ongoing business or user experience.
Installing and configuring Mysql
MySQL is a popular relational database management system used for storing and managing data. Here we will cover how to install MySQL and perform basic security configurations.
-
Install MySQL server:
sudo apt install mysql-server
-
Once the installation is complete, check if MySQL is running and make sure to enable it to start on boot:
sudo systemctl status mysql sudo systemctl is-enabled mysql
If not started, run the following command to start it and enable it:
sudo systemctl start mysql sudo systemctl enable mysql
-
you can run the security script that comes pre-packaged with MySQL. This script will help you improve the security of your MySQL installation:
sudo mysql_secure_installation
This script will guide you through several security considerations, including setting up a root password(if not set), removing anonymous users, disabling root login remotely, and removing test databases. It is recommended to accept the defaults which are aimed at increasing the security of your database server.
Now that MySQL is installed and secured, the next step is to create a database and user for WordPress. WordPress uses a database to manage and store site and user information, so it's essential to set this up before installing WordPress.
-
Log into the MySQL root administrative account by typing:
sudo mysql -u root -p
Enter the root password you set before.
-
Once logged in, create a new database for WordPress. Replace wordpressdb with the name you want to give to your database:
CREATE DATABASE wordpressdb DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
-
Create a new MySQL user account that will be used exclusively by WordPress. Replace wordpressuser with the username you want to use, and password with a strong password:
CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'password';
-
Grant the newly created user full privileges on the WordPress database, then flush the MySQL privileges to ensure they are applied and saved:
GRANT ALL PRIVILEGES ON wordpressdb.* TO 'wordpressuser'@'localhost'; FLUSH PRIVILEGES; EXIT;
By completing these steps, you should have successfully created a dedicated database and user for your WordPress installation. These credentials will be used during the WordPress configuration to allow WordPress to connect to the database and store your website's data.
Remember to keep the database name, username, and password handy as you will need them when setting up WordPress.
Installing and configuring PHP
WordPress is written in PHP and requires it to execute its scripts. In this section, we'll install PHP along with some common modules that WordPress needs to function properly.
- Install PHP and necessary PHP extensions. On Ubuntu 20.04, you can use the following command to install PHP along with commonly used extensions that WordPress requires:
sudo apt install php-fpm php-mysql php-gd php-xml php-mbstring php-curl php-xmlrpc php-imagick php-zip -y
- Check the PHP version to confirm it's correctly installed:
php -v
You should see the PHP version information displayed, confirming that PHP is successfully installed on your system.
WordPress can usually run well with default PHP settings. However, you can adjust PHP configurations for performance and security in the php.ini file if necessary. But for a standard setup, sticking with the default settings should suffice. - Make sure PHP-FPM (FastCGI Process Manager) is active and running:
sudo systemctl status php{version}-fpm
Replace {version} with your PHP version. If it's not running, you can start it with:
sudo systemctl start php{version}-fpm
- Now, PHP should be set up and ready to support your WordPress installation. It's also important to ensure that PHP-FPM is enabled to start automatically when your server boots up. You can do this with the following command:
sudo systemctl enable php{version}-fpm
Installing and configuring WordPress
Installing WordPress
Now that your LEMP stack is fully configured, it's time to install WordPress and get your website up and running.
-
Download WordPress:
First, navigate to the root directory of your website. Replace blog.your_domain with your actual domain or directory path:cd /var/www/blog.your_domain
Then, use the wget command to download the latest WordPress release:
sudo wget https://wordpress.org/latest.tar.gz
If you don't have wget, you can simply install it with
sudo apt install wget
. If you have curl, you can also use curl to complete the download.sudo curl -O https://wordpress.org/latest.tar.gz
-
Extract WordPress:
Unpack the WordPress archive to the current directory, then clean up the temp file and directory.tar -xzvf latest.tar.gz mv wordpress/* ./ rmdir wordpress mv latest.tar.gz /tmp
-
Adujst ownership and permissions:
Adjust the file ownership and permissions to ensure WordPress can function properly. Replace www-data with your web server's user if different:sudo chown -R www-data:www-data /var/www/blog.your_domain
Configuring WordPress
- Set up WordPress:
Copy the WordPress sample configuration file to create a new configuration:cp wp-config-sample.php wp-config.php
Then edit the wp-config.php file to add your database connection details.
sudo vim wp-config.php
Fill in the database details, such as the name, user, and password, which you created earlier during the MySQL setup steps. Below is an example of how you should modify the wp-config.php file with your actual database details:
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpressdb' ); // Replace 'wordpressdb' with your actual database name
/** MySQL database username */
define( 'DB_USER', 'wordpressuser' ); // Replace 'wordpressuser' with your actual database username
/** MySQL database password */
define( 'DB_PASSWORD', 'password' ); // Replace 'password' with your actual database password
/** MySQL hostname */
define( 'DB_HOST', 'localhost' ); // Generally 'localhost' but modify if different in your setup
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' ); // Recommended to leave as 'utf8'
/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' ); // Usually best to leave this empty
- Almost successfully installed WordPress!
Now, navigate to your website http://blog.your_domain in a web browser. You should see the WordPress installation page. Follow the on-screen instructions to select a language, and fill in the site information and administrator details. After completing these steps, your WordPress website should be installed and ready to use. But before you start posting, you should secure your website.
Securing Your WordPress Site with HTTPS
It's crucial in today's web environment to ensure that your website uses HTTPS, the secure version of HTTP. HTTPS encrypts the data between your user's web browser and your web server, making it more difficult for attackers to intercept and tamper with the data. This is especially important for a site like a WordPress blog, where users may be submitting personal information.
In this guide, we will use a free, automated, and open certificate authority provided by Let's Encrypt. We'll use Certbot, a tool designed to simplify the process of obtaining and renewing certificates from Let's Encrypt.
Installing and configuring Certbot
Plan A
1a. Install Certbot and its Nginx plugin to make this easier:
sudo apt install certbot python3-certbot-nginx
2a. Obtaining a Certificate, you can run it with the --nginx flag to automatically obtain and install a certificate and configure Nginx to use it:
sudo certbot --nginx
Follow the prompts to enter your email address, agree to the terms of service, and decide whether you want to redirect HTTP traffic to HTTPS (which is recommended).
If this not work well, you can try mannually apply for the certificate and configure HTTPS on Nginx, you can use the following approach:
Plan B
1b. Obtaining a Certificate Manually:
sudo certbot certonly
This command will obtain the certificate but will not modify your Nginx configuration. After entering this command, follow the prompts to complete the validation process. You will need to:
- Enter your email address.
- Agree to the terms of service.
- Input your domain name(s) for which you want to obtain the certificate.
Note: The obtained certificates will be stored by default at /etc/letsencrypt/live/your_domain/. Remember this path as you will need it for configuring Nginx to use the SSL certificate.
2b. Configuring Nginx to Use the SSL Certificate
Once you have your certificate, you need to configure Nginx to use it. First, open your domain's Nginx configuration file:
sudo vim /etc/nginx/sites-available/blog.your_domain
Add the following lines inside the server block to enable HTTPS, replacing your_domain with your actual domain name:
server {
listen 443 ssl http2;
server_name blog.your_domain;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
# ... (other configuration)
}
Don't forget your http server and redirect it to https:
server {
listen 80;
server_name blod.your_domain;
return 301 https://$server_name$request_uri;
}
-
Testing and Reloading Nginx Configuration
After updating the configuration, test to make sure there are no syntax errors:sudo nginx -t
If the test is successful, reload Nginx to apply the changes:
sudo systemctl reload nginx
-
Auto-Renewal of SSL Certificates
Let's Encrypt certificates are valid for 90 days. However, Certbot should automatically set up a timer to renew your certificates before they expire.
To verify the automatic renewal process, run the following command:sudo systemctl list-timers | grep certbot
You should see a timer entry like certbot.timer. This indicates that a systemd timer is set up to handle the renewal.
To test the renewal process, you can manually trigger it by running the following command:
sudo certbot renew --dry-run
The --dry-run
option simulates the renewal process without making any actual changes to your certificates. If this command runs without any errors, your automatic renewal setup is likely configured correctly.
Conclusion
And there you have it, a comprehensive step-by-step guide to deploying WordPress with the LEMP stack! By now, you should have a fully functioning WordPress site up and running on your very own LEMP server. I hope you found the instructions clear and straightforward.
Deploying your WordPress site might have seemed like a daunting task at first, but look at you now! You've navigated through the nuances of setting up Linux, Nginx, MySQL, and PHP, and you've tackled the intricacies of server and site configurations with finesse.
Remember, the journey doesn't end here. This is just the beginning of your adventure with your new WordPress site. Experiment with different themes, plugins, and settings to make your site uniquely yours. And most importantly, keep learning and exploring the vast possibilities that WordPress and the LEMP stack offer.
If you ever hit a snag, don't hesitate to look back at this guide or leave a message. Additionally, you can seek out the abundant resources available online. The WordPress and developer communities are incredibly supportive and full of information.
In conclusion, I hope this article has been helpful to you. There's a definite sense of achievement and satisfaction after completing such a task. I hope to persevere, continue to refine, and share more valuable content with those in need. In doing so, I aim to leave a small mark of my existence in this world.
Reference:
https://developer.wordpress.org/advanced-administration/server/web-server/nginx/