Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save codedeep79/cef8242340024b027233b71b413c2a8f to your computer and use it in GitHub Desktop.

Select an option

Save codedeep79/cef8242340024b027233b71b413c2a8f to your computer and use it in GitHub Desktop.
Install Linux, Nginx, MySQL, PHP (LEMP stack) on Ubuntu 22.04

Step 1 – Installing the Nginx Web Server

sudo apt update
sudo apt install nginx

When prompted, press Y and ENTER to confirm that you want to install Nginx. Once the installation is finished, the Nginx web server will be active and running on your Ubuntu 22.04 server. Nginx registers a few different UFW application profiles upon installation. To check which UFW profiles are available, run: sudo ufw app list Configure HTTP traffic on port 80: sudo ufw allow 'Nginx HTTP' You can verify the change by checking the status: sudo ufw status With the new firewall rule added, you can test if the server is up and running by accessing your server’s domain name or public IP address in your web browser.

Step 2 — Installing MySQL

Now that you have a web server up and running, you need to install the database system to be able to store and manage data for your site: sudo apt install mysql-server When the installation is finished, it’s recommended that you run a security script that comes pre-installed with MySQL. This script will remove some insecure default settings and lock down access to your database system: sudo mysql_secure_installation.

Error appear:

To solve the above error, we do the following:

  • Run command: sudo mysql which logged me in as root without a password Error appear:

    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
    

    To resolve this error do the following:

    • Stop Your Server First: sudo service mysql stop
    • Make MySQL service directory: sudo mkdir /var/run/mysqld
    • Give MySQL permission to work with the created directory: sudo chown mysql: /var/run/mysqld
    • Start MySQL, without permission and network checking: sudo mysqld_safe --skip-grant-tables --skip-networking &
    • Log in to your server without any password: mysql -u root mysql or sudo mysql -u root mysql
  • Enter command:

    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'mynewpassword';
    

    Error appear:

    ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
    

    To resolve this error do the following:

    • Login to mysql: mysql -u root -p
    • Command execute: FLUSH PRIVILEGES;
    • Command execute again:
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'mynewpassword';
    

Run the command again: sudo mysql_secure_installation

sudo mysql_secure_installation
[sudo] password for nguyen: 

Securing the MySQL server deployment.

Enter password for user root: 
The 'validate_password' component is installed on the server.
The subsequent steps will run with the existing configuration
of the component.
Using existing password for root.

Estimated strength of the password: 50 
Change the password for root ? ((Press y|Y for Yes, any other key for No) : n

 ... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done! 

Step 3 – Installing PHP

You have Nginx installed to serve your content and MySQL installed to store and manage your data. Now you can install PHP to process code and generate dynamic content for the web server. To install the php8.1-fpm and php-mysql packages, run: sudo apt install php8.1-fpm php-mysql

Step 4 – Create an Nginx Server Block

An Nginx server block is like a virtual host in Apache. We will not use the default server block because it’s inadequate to run PHP code and if we modify it, it becomes a mess. So remove the default symlink in sites-enabled directory by running the following command. (It’s still available as /etc/nginx/sites-available/default): sudo rm /etc/nginx/sites-enabled/default

Then use a command-line text editor like Nano to create a new server block file under /etc/nginx/conf.d/ directory: sudo nano /etc/nginx/conf.d/default.conf

Paste the following text into the file. The following snippet will make Nginx listen on IPv4 port 80 and IPv6 port 80 with a catch-all server name.

server {
  listen 80;
  listen [::]:80;
  server_name _;
  root /usr/share/nginx/html/;
  index index.php index.html index.htm index.nginx-debian.html;

  location / {
    try_files $uri $uri/ /index.php;
  }

  location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    include snippets/fastcgi-php.conf;
  }

 # A long browser cache lifetime can speed up repeat visits to your page
  location ~* \.(jpg|jpeg|gif|png|webp|svg|woff|woff2|ttf|css|js|ico|xml)$ {
       access_log        off;
       log_not_found     off;
       expires           360d;
  }

  # disable access to hidden files
  location ~ /\.ht {
      access_log off;
      log_not_found off;
      deny all;
  }
}

Then test Nginx configurations: sudo nginx -t

If the test is successful, reload Nginx: sudo systemctl reload nginx

Step 5: Test PHP

To test PHP-FPM with Nginx Web server, we need to create a info.php file in the webroot directory: sudo nano /usr/share/nginx/html/info.php

Paste the following PHP code into the file:

<?php phpinfo(); ?>

Save and close the file. Now in the browser address bar, enter: http://127.0.0.1/info.php

Step 6: Improve PHP Performance

The default PHP configurations (/etc/php/8.1/fpm/php.ini) are made for servers with very few resources (like a 256MB RAM server). To improve web application performance, you should change some of them.

We can edit the PHP config file (php.ini), but it’s a good practice to create a custom PHP config file, so when you upgrade to a new version of PHP8.1, your custom configuration will be preserved.

sudo nano /etc/php/8.1/fpm/conf.d/60-custom.ini

In this file, add the following lines:

; Maximum amount of memory a script may consume. Default is 128M
memory_limit = 512M

; Maximum allowed size for uploaded files. Default is 2M.
upload_max_filesize = 20M

; Maximum size of POST data that PHP will accept. Default is 2M.
post_max_size = 20M

; The OPcache shared memory storage size. Default is 128
opcache.memory_consumption=256

; The amount of memory for interned strings in Mbytes. Default is 8.
opcache.interned_strings_buffer=32

Save and close the file. Then reload PHP8.1-FPM for the changes to take effect: sudo systemctl reload php8.1-fpm

OPcache improves the performance of PHP applications by caching precompiled bytecode. You can view OPcache stats via the info.php page. Below is a before and after comparison on one of my servers.

Before

After

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment