One place for hosting & domains

      How to Create a LEMP Stack on Linux

      LEMP stack refers to a development framework for Web and mobile applications based on four open source components:

      1. Linux operating system
      2. NGINX Web server
      3. MySQL relational database management system (RDBMS)
      4. PHP,
        Perl, or
        Python programming language

      NGINX contributes to the acronym “LEMP” because English-speakers pronounce NGINX as “engine-x”, hence an “E”.

      Before You Begin

      1. If you have not already done so, create a Linode account and Compute Instance. See our
        Getting Started with Linode and
        Creating a Compute Instance guides.

      2. Follow our
        Setting Up and Securing a Compute Instance guide to update your system. You may also wish to set the timezone, configure your hostname, create a limited user account, and harden SSH access.


      The steps in this guide require root privileges. Be sure to run the steps below as root or with the sudo prefix. For more information on privileges, see our
      Users and Groups guide.

      How Does LEMP Differ from LAMP?

      LAMP is just like LEMP, except with Apache in place of NGINX.

      LAMP played a crucial role in the Web for
      over twenty years. NGINX was released publicly in 2004, largely to address faults in LAMP. LEMP use spread widely after 2008, and NGINX is now the second
      most popular Web server, after the
      Apache Web server that LAMP uses.

      Both LEMP and LAMP combine open source tools to supply the essentials for a Web application. This includes an underlying Linux operating system which hosts everything else, including:

      • The NGINX or Apache Web server that receives and responds to end-user actions.
      • The MySQL RDBMS which stores information including user profile, event histories, and application-specific content which has a lifespan beyond an individual transaction.
      • A programming language for business logic that defines a particular application.

      Abundant documentation and rich communities of practitioners make both LEMP and LAMP natural choices for development. The difference between them is confined to the Web server part of the stack.

      Apache Versus NGINX

      In broad terms, the two Web servers have much in common.
      NGINX is faster than Apache, but requires more expertise in certain aspects of its configuration and use, and is less robust on Windows than Apache. Apache works usefully “out of the box”, while, as we see below, NGINX demands a couple of additional steps before its installation is truly usable.

      RDBMS and Programming Language

      Two other variations deserve clarity in regard to the initials “M” and “P”.
      MariaDB is a drop-in replacement for MySQL. The differences between the two are explained in
      this tutorial. Everything you do with MySQL applies immediately with MariaDB as well.

      While several different programming languages work well in a LEMP stack, this guide focuses on PHP. However, nearly all the principles of LEMP illustrated below apply with Python or another alternative.

      LEMP Benefits

      LEMP has a deep track record of successful deliveries. Hundreds of millions of working Web applications depend on it.

      LEMP’s suitability extends beyond purely technical dimensions. Its flexible open-source licensing enables development teams to focus on their programming and operations, with few legal constraints to complicate their engineering.

      Install the LEMP Stack

      Linode’s support for LEMP begins with abundant documentation, including
      How to Install the LEMP Stack on Ubuntu 18.04.

      Rich collections of documentation are available to readers
      new to Linux and its command line. This guide assumes familiarity with the command line and Linux filesystems, along with permission to run as root or with sudo privileges. With the “L” (Linux) in place, the installation in this Guide focuses purely on the “EMP” layers of LEMP.

      Install “E”, “M”, and “P” Within “L”

      Different distributions of Linux require subtly different LEMP installations. The sequence below works across a range of Ubuntu versions, and is a good model for other Debian-based distributions.

      1. Update your host package index with:

        sudo apt-get update -y
      2. Now upgrade your installed packages:

        sudo apt-get upgrade -y
      3. Install software-properties-common and apt-transport-httpsto manage the PHP PPA repository:

        sudo apt-get install software-properties-common apt-transport-https -y
      4. Now provide a reference to the current PHP repository:

        sudo add-apt-repository ppa:ondrej/php -y
      5. Update the package index again:

        sudo apt update -y
      6. Install the rest of the LEMP stack:

        sudo apt-get install nginx php-mysql mysql-server php8.1-fpm -y

      The installation demands a small amount of interaction to give information about geographic location and timezone. Depending on circumstances, you may need to verify the country and timezone your server is located in.

      Start Services

      1. Start the “E” (NGINX), “M” (MySQL), and “P” (PHP) services:

        sudo service nginx start
        sudo service mysql start
        sudo service php8.1-fpm start
      2. Check on these services:

        sudo service --status-all

        You should see them all running::

        [ + ]  mysql
        [ + ]  nginx
        [ + ]  php8.1-fpm

      Verify PHP

      Verify the healthy operation of these services.

      1. For PHP, launch:

        php -version

        You should see:

        PHP 8.1.x (cli) (built: ...
        Copyright © The PHP Group ...
      2. Go one step further with verification of the PHP configuration through the command:

        php -m

        The result you see is:

        [PHP Modules]

      This demonstrates that PHP is installed and that the modules needed to communicate with the rest of the LEMP stack are in place.

      Verify NGINX

      Verification of NGINX service is a little more involved. The first step is
      identification of the IP address of the host.

      1. Navigate a browser to a URL such as http://localhost or http://23.77.NNN.NNN, henceforth referred to as $LEMP_HOST

        Your Web browser shows a default display of:

        Welcome to nginx!
        If you see this page, the nginx web server is successfully installed and working.  ...
      2. With the default NGINX configuration verified, update it to enable PHP. Edit the file located at /etc/nginx/sites-enable/default and change this section:

        File: /etc/nginx/sites-enabled/default
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;

        To become:

        File: /etc/nginx/sites-enabled/default
        location / {
               # First attempt to serve request as file, then
               # as directory, then fall back to displaying a 404.
               try_files $uri $uri/ =404;
        location ~ \.php {
               include snippets/fastcgi-php.conf;
               fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
      3. Back at the Linux command line, activate this new configuration with:

        service nginx restart
      4. Next, ensure that NGINX communicates with PHP by creating the file /var/www/html/php-test.php with contents:

        File: /var/www/html/php-test.php
      5. Now direct your browser to http://$LEMP_HOST/php-test.php.

        Your browser shows several pages of diagnostic output, starting with:

        PHP Version 8.1.9
           System Linux ... 5.10.76-linuxkit #1 SMP Mon Nov 8 ...

      The location of /var/www/html/php-test.php is configurable. This means that a particular distribution of Linux and NGINX might designate a different directory. /var/www/html is common, especially for a new Ubuntu instance with NGINX “out of the box”. In practice, it’s common to modify the NGINX default a great deal. You can allow for tasks such as caching, special handling for static requests, virtual hosts, and logging security.

      Verify MySQL

      When you install MySQL according to the directions above, it doesn’t depend on authentication.

      1. No password is required. You only need one command:


        And you see:

        Welcome to the MySQL monitor ...
      2. You can leave the MySQL monitor and return to the Linux command line with:


      Your LEMP stack is now installed, activated, and ready for application development. For a basic LEMP installation, this consists of placing programming source code in the /var/www/html directory, and occasionally updating the configurations of the LEMP layers.

      Use the LEMP Stack to Create an Example Application

      You can create a minimal model application that exercises each component and typical interactions between them. This application collects a record of each Web request made to the server in its backend database. A more refined version of this application could be used to collect:

      • Sightings of a rare bird at different locations.
      • Traffic at voting stations.
      • Requests for customer support.
      • Tracking data for a company automobile.

      The configuration and source below apply to LEMP environments. Even if your LEMP stack used different commands during installation, the directions that follow apply with a minimum amount of customization or disruption.

      Prepare a Database to Receive Data

      Start application development by configuring the database to receive program data.

      1. Re-enter the MySQL monitor with:

      2. While connected to MySQL, create a database instance specific to this development:

        CREATE DATABASE model_application;
      3. Enter that database with:

        USE model_application;
      4. Define a table for the program data:

        CREATE TABLE events (
            client_ip INT(4) UNSIGNED NOT NULL
      5. Create a database account:

        CREATE USER 'automation'@'localhost' IDENTIFIED BY 'abc123';
      6. Now allow PHP to access it:

        GRANT ALL PRIVILEGES ON model_application.* TO 'automation'@'localhost' WITH GRANT OPTION;
      7. Quit MySQL:


      A polished application uses tighter security privileges, but this sample application adopts simple choices to maintain focus on the teamwork between the different LEMP layers.

      Create Application Source Code

      Create /var/www/html/event.php with the following content:

      File: /var/www/html/event.php
          $connection = new mysqli("", "automation", "abc123", "model_application");
          $client_ip = $_SERVER['REMOTE_ADDR'];
          // INET_ATON() packs an IPv4 string representation into
          // four octets in a standard way.
          $query = "INSERT INTO events(client_ip)
          echo 'Your request has successfully created one database record.';

      Verify Operation of the Application

      1. event.php is the only program source code for our minimal model application. With it in place, instruct your browser to visit http://$LEMP_HOST/event.php.

        You should see:

        Your request has successfully created one database record.
      2. You can also exercise the application from different remote browser connections. With a different browser, perhaps from a different desktop, again navigate to http://$LEMP_SERVER/event.php.

      View Collected Data

      The model application exhibits the expected behavior from a Web application and your browser reports success. Viewed through the Web browser, the application does the right thing.

      1. To confirm it updated the database, re-enter the MySQL monitor:

      2. Enter the example application database:

        USE model_application;
      3. Pose the query:

        select timestamp, inet_ntoa(client_ip) from events;

        You should see output such as:

        | timestamp           | inet_ntoa(client_ip) |
        | 2022-08-03 02:26:44 |            |
        | 2022-08-03 02:27:18 |          |
        | 2022-08-05 02:27:23 |        |

      This demonstrates the flow of data from a Web browser to the database server. Each row in the events table reflects one request from a Web browser to connect to the application. As the application goes into practical use, rows accumulate in the table.

      Application Context

      LEMP is a trustworthy basis for Web development, with decades of successful deliveries over a range of requirements. It directly supports only
      server-side processing. The model application above delivers pure HTML to the browser. However, LEMP is equally capable of serving up CSS and
      JavaScript, but does not build in tooling for these client-side technologies. Projects reliant on elaborate user interface effects usually choose a framework focused on the client side.
      React is an example of such a framework.

      Server-side orientation remains adequate for many applications, and LEMP fits these well. Server-side computation typically involves several functions beyond the model application above, including:

      • Account Management
      • Forms Processing
      • Security Restrictions
      • Analytic and Cost Reporting
      • Exception Handling
      • Quality Assurance Instrumentation

      Contemporary applications often build in a
      model-view-controller (MVC) architecture, and/or define a
      representational state transfer (REST) perspective. A commercial-grade installation usually migrates the database server to a separate dedicated host. Additionally, high-volume applications often introduce load balancers, security-oriented proxies,
      content delivery network (CDN) services, and other refinements. These functions are layers over the basic data flow between user, browser, business logic processing, and datastore that the model application embodies. The model application is a good first example.


      You just installed a working LEMP stack, activated it, and created a model application. All the needs of a specific Web application have a place in this same model.

      Source link

      How To Set Up WordPress Multisite with Nginx and LEMP on Ubuntu 20.04


      The WordPress multisite feature is a unique way to host and manage a suite of sites in one place, and is useful for projects or positions that call for the operation of several WordPress sites under one host. Multisite offers the ability to create multiple WordPress websites from a single installation of WordPress, with each site having a separate theme, set of plugins, and collection of content (typically posts and pages). This feature helps to reduce the overhead of maintaining and updating several installations of WordPress, while allowing you to host multiple sites which may be unrelated to one another.

      In this tutorial, you’ll set up a WordPress multisite on an Ubuntu 20.04 Droplet using subdomains. The WordPress sites that you’ll create will have a subdomain web address like, but your subdomain address can be mapped to an external domain like so that each site looks independent to users visiting your multisite suite of addresses.


      This tutorial requires you to have a basic knowledge of WordPress multisite. The following articles might be helpful in deepening your understanding of multisites:

      Step 1 — Installing WordPress

      For this tutorial, you’ll need to have access to a WordPress Droplet running the LEMP stack on Ubuntu 20.04. You can create a WordPress installation on a Droplet in the following ways:

      You can also follow this tutorial using a WordPress installation on a hosting provider, but keep in mind that the steps of this tutorial will reflect a WordPress multisite setup on a DigitalOcean Droplet.

      Before installing WordPress, you’ll need to set up DNS records for each intended WordPress site in your multisite installation. For this tutorial, create the following domain names:

      • Site 1:

        Domain: (Primary domain)

        This is the site that is created when WordPress is installed.

      • Site 2:

        External Domain:


      • Site 3:

        External Domain:


      The first domain is the primary domain name through which WordPress will be referenced. Make sure to set up DNS for all three domains to point to the IP address of the Droplet hosting WordPress.

      While installing, if you’ve chosen to use a Droplet with a LEMP stack, be sure to follow the instructions for setting up your database and users. For DigitalOcean WordPress 1-Click installations, this has already been configured for you.

      After installing WordPress on your Droplet, let’s assign file ownership to the user www-data. This is essential for media uploads and for core/plugin/theme updates to work in WordPress.

      Log in to your Droplet via the command line, then execute the following command, replacing the highlighted path with the full path to your WordPress installation:

      • chown -R www-data:www-data /var/www/wordpress/

      This command will grant read and write access to the www-data user for media uploads and necessary updates.

      In the next step, we’ll further configure the primary domain, then configure our multisite installation from there.

      Step 2 — Setting Up DNS Wildcard Records

      Let’s continue by adding a DNS wildcard record for the primary domain. Adding a wildcard record allows more WordPress sites to be added to your multisite installation at any time, without needing individual A records. Alternatively, you can choose to add a new A record for each subdomain.

      Log in to your DigitalOcean control panel and navigate to the Networking section. Edit the primary domain and create a wildcard A record for this domain pointing to the Droplet’s IP address. A wildcard record is created by entering an asterisk (*) in the hostname input box as shown in the following screenshot.

      DNS Control Panel - wildcard record

      If you host your domain’s DNS on a hosting provider, set the wildcard record using the registrar’s site.

      After setting the wildcard record, DNS queries for any should return the IP address of your Droplet.

      Step 3 — Enable Multisite and Create Additional Sites

      In this section, let’s now enable our WordPress multisite and create the two additional sites as mentioned in Step 1.

      To begin this process, a PHP constant has to be defined in the wp-config.php file to enable the Network Setup page.

      You can edit the wp-config.php file via the command line while logged into your WordPress Droplet. Open the file using your command line editor of choice. Here, we’ll use nano:

      • nano /var/www/wordpress/wp-config.php

      Add the following code before the comment /* That's all, stop editing! Happy blogging. */ or similar text:


          /* Multisite settings */
          define( 'WP_ALLOW_MULTISITE', true );

      Save and close the file. If you’re using nano, you can do that with CTRL+X, then Y and ENTER to confirm.

      Next, log in to the WordPress admin panel and navigate to Tools -> Network Setup. Choose the Subdomains option, modify the Network Title as desired, and then click Install.

      WordPress Network Setup

      You will be presented with two blocks of code to be added in the wp-config.php and .htaccess files. Because we are using Nginx, we won’t need to use the suggested .htaccess code, so you can ignore that for now.

      Copy the wp-config.php code which looks similar to the following:

          define('MULTISITE', true);
          define('SUBDOMAIN_INSTALL', true);
          define('DOMAIN_CURRENT_SITE', '');
          define('PATH_CURRENT_SITE', '/');
          define('SITE_ID_CURRENT_SITE', 1);
          define('BLOG_ID_CURRENT_SITE', 1);

      Next, open the wp-config.php file:

      • nano /var/www/wordpress/wp-config.php

      Include the code snippet you just copied, placing it before the comment that says /* That's all, stop editing! Happy blogging. */ (or a variation of text that advises not to write below it). Save the file when you’re done.

      Log out of the WordPress admin panel, and log in again. From the admin toolbar on the top left, navigate to the My Sites > Network Admin > Sites.

      WordPress Toolbar

      Click the Add New button to open the Add New Site form. The following screenshot shows the filled-in details for the shopping site in our example. The Site Address entered will form the subdomain of this site.

      Creating a new WordPress site

      Click Add Site and the created site will be accessible via

      Repeat these steps to create the second site ( in our example).

      The following three WordPress sites can now have its own content, theme, and active set of plugins:


      Step 4 — Setting Up Domain Mapping

      In this step, let’s enable multisite to use a separate domain name for each WordPress site by downloading and enabling the WordPress MU Domain Mapping plugin. This third-party plugin allows users of WordPress multisite to map their blog/site to another domain.

      To download this plugin,visit My Sites -> Network Admin -> Plugins from your dashboard and select Add New on your primary domain to find the WordPress MU Domain Mapping plugin.


      Install the plugin, then click the Network Activate link under the WordPress MU Domain Mapping plugin. Go to Settings -> Domain Mapping and make changes to the Domain Options as follows:

      • Uncheck Remote Login
      • Check Permanent Redirect
      • Uncheck Redirect administration pages to site’s original domain

      Domain mapping options

      Click Save once done. These settings redirect all requests for subdomains (like to their respective external domains (like including the administration pages (/wp-admin).

      In the next step, let’s map a domain name to each site based on its site ID. There are many ways to find the ID of a site, but for easier administration you’ll create a simple WordPress Must-use plugin that displays an additional ID column on the Sites page.

      Log in to your WordPress Droplet via SSH and create an mu-plugins directory.

      • mkdir /var/www/wordpress/wp-content/mu-plugins

      Create a PHP file inside this directory:

      nano /var/www/wordpress/wp-content/mu-plugins/wpms_blogid.php

      Next, copy the following content to your wpms_blogid.php file:


          add_filter( 'wpmu_blogs_columns', 'do_get_id' );
          add_action( 'manage_sites_custom_column', 'do_add_columns', 10, 2 );
          add_action( 'manage_blogs_custom_column', 'do_add_columns', 10, 2 );
          function do_add_columns( $column_name, $blog_id ) {
              if ( 'blog_id' === $column_name )
                  echo $blog_id;
              return $column_name;
          function do_get_id( $columns ) {
              $columns['blog_id'] = 'ID';
              return $columns;

      The Sites -> All Sites section should now show an additional ID column.


      Note down the ID values for each site and go to the Settings -> Domains page. Enter the site ID followed by the external domain for the site. For example, since companysite has an ID of 3, on this page, the Site ID should be 3, and the domain should be

      Mapping a site ID to a domain

      You may add a “www” prefix if you wish to set the site URL as Repeat these steps for the other domains. Click Save at the bottom of the page.

      Each site will now have its own domain name instead of a subdomain; i.e., entering in your browser will open the My Online Company site. You can check this now by visiting your additional domain names that are mapped. You should see the site title change in the upper left corner of the page.

      Now each site can be maintained separately through its own WordPress admin panel:

      - ``
      - ``
      - ``

      Updates to the core/plugins/themes and installation of plugins/themes should be done from the network admin page of the primary domain:

      - ``


      In this tutorial, you learned how to set up the multisite feature on a WordPress website running on Ubuntu 20.04 with Nginx (LEMP stack). The multisite feature enables you to host multiple WordPress sites on one WordPress installation on your droplet. You also learned how to set up domain mapping, which allows each of your subsites to be reached through a custom domain name.

      For an alternate process to install the WordPress multisite feature, visit our tutorial, Setting up WordPress Multisite on Apache.

      Source link

      What is LEMP?

      LEMP refers to a collection of open-source software that is commonly used together to serve web applications. The term LEMP is an acronym that represents the configuration of a Linux operating system with an nginx (pronounced engine-x, hence the E in the acronym) web server, with site data stored in a MySQL database and dynamic content processed by PHP.

      The LEMP stack represents one way to configure a web server, and is used in a number of highly-scaled applications across the web.

      To learn more about LEMP, our tutorial How To Install Linux, Nginx, MySQL, PHP (LEMP stack) on Ubuntu 20.04 shares additional information and guides you through installing the LEMP stack on your web server.

      Source link