LEMP stack for a Forge-like Ubuntu server
After getting a fresh Ubuntu server from here, I often install the LEMP stack to run my PHP/Laravel applications with these simple scripts.
Nginx Setup
Install Nginx and use h5bp configs.
wget -O nginx-setup.sh https://raw.githubusercontent.com/confetticode/forge-like-setup/main/scripts/nginx-setup.sh
bash nginx-setup.sh
When finishing, verify if nginx is running.
systemctl status nginx
PHP Setup
Install PHP 8.3 with Composer. It currently supports PHP 8.3 only.
wget -O php-setup.sh https://raw.githubusercontent.com/confetticode/forge-like-setup/main/scripts/php-setup.sh
bash php-setup.sh 8.3
When finishing, verity PHP and Composer.
forge@server-host:~$ php -v
PHP 8.3.13 (cli) (built: Oct 30 2024 11:28:41) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.13, Copyright (c) Zend Technologies
with Zend OPcache v8.3.13, Copyright (c), by Zend Technologies
forge@server-host:~$ composer --version
Composer version 2.8.2 2024-10-29 16:12:11
PHP version 8.3.13 (/usr/bin/php8.3)
Run the "diagnose" command to get more detailed diagnostics output.
Allow forge
to reload|restart|status php*-fpm services by creating /etc/sudoers.d/forge
file with the following content.
forge ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload php*-fpm
forge ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart php*-fpm
forge ALL=(ALL) NOPASSWD: /usr/bin/systemctl status php*-fpm
Change PHP FPM pool name by opening /etc/php/8.3/fpm/pool.d/www.conf
and replacing [www] with [PHP 8.3]
; Start a new pool named 'www'.
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('www' here)
; [www] -> [PHP 8.3]
[PHP 8.3]
Check PHP process names
ps aux | grep php
Restart PHP FPM service and check it status
systemctl restart php8.3-fpm
systemctl status php8.3-fpm
MySQL Setup
The default root password is “secret”. I’ll use mysql_secure_installation
command to change it.
wget -O mysql-setup.sh https://raw.githubusercontent.com/confetticode/forge-like-setup/main/scripts/mysql-setup.sh
bash mysql-setup.sh
When finishing, verify if MySQL is running.
systemctl status nginx
Configure a PHP site
Replace laravel-demo with your domain.
Create a specific log directory
mkdir -p /var/log/nginx/laravel-demo.com
Create a vhost file at /etc/nginx/conf.d/laravel-demo.com.conf
server {
listen [::]:80;
listen 80;
# The host name to respond to
server_name laravel-demo.com;
# The root directory
root /home/forge/laravel-demo.com/public;
# Write logs to specific files
access_log /var/log/nginx/laravel-demo.com/access.log;
error_log /var/log/nginx/laravel-demo.com/error.log;
# Run index.php with a specific PHP-FPM version.
location ~ \.php$ {
include extra/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
# The file should be served by default
index index.html index.htm index.php;
# Let index.php handle 404 error.
error_page 404 /index.php;
# Include the basic h5bp config set
include h5bp/basic.conf;
# Ignore /favicon.ico and /robots.txt requests
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; }
# Deny requests to .ht files.
location ~ /\.ht {
deny all;
}
# If a directory or file exists, serve it.
# Else, try to run index.php.
# Otherwise, fail with 404 status code.
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
}
Ensure Nginx configuration is OK
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Reload the Nginx service
systemctl reload nginx
Install Laravel
Clone the Laravel repository
pwd
/home/forge
git clone https://github.com/laravel/laravel.git laravel-demo.com
Cloning into 'laravel-demo.com'...
remote: Enumerating objects: 34591, done.
remote: Counting objects: 100% (75/75), done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 34591 (delta 30), reused 38 (delta 12), pack-reused 34516 (from 1)
Receiving objects: 100% (34591/34591), 10.51 MiB | 14.82 MiB/s, done.
Resolving deltas: 100% (20457/20457), done.
cd laravel-demo.com
Copy .env
from .env.example
cp .env.example .env
Install Composer packages
composer install --prefer-dist --no-dev
Generate an application key
php artisan key:generate
Run database migrations
php artisan migrate --forge
Setup DNS
Point the domain to the server IP address. Wait for a while and then visit http://laravel-demo.com
to verify it works.
Clean setup files
I place *-setup.sh in /root
directory. So I need to go there to delete them.
cd ~ # Go to /root directory
rm *-setup.sh
Summary
Here are steps, scripts or commands I use to set up the LEMP for a Forge-like Ubuntu server. They are installing Nginx, PHP, MySQL and configuring things. It’s a really helpful note for me. I’ll try to update and make more automation stuff later.
Subscribe to my newsletter
Read articles from Quynh Nguyen directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Quynh Nguyen
Quynh Nguyen
Full Stack Web Developer