sudo apt update
sudo apt install nginx

sudo ufw app list

sudo ufw allow 'Nginx HTTP'

sudo ufw status

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

sudo mysql_secure_installation.
To solve the above error, we do the following:
-
Run command:
sudo mysqlwhich logged me in asrootwithout 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 mysqlorsudo mysql -u root mysql
- Stop Your Server First:
-
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 statementTo resolve this error do the following:
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!
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
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
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
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.













