Skip to main content

Command Palette

Search for a command to run...

Step-by-Step Guide to Deploying a Laravel App on Ubuntu Server Using NGINX

Simple Steps for Hosting a Laravel App on an Ubuntu Server with NGINX

Updated
8 min read
Step-by-Step Guide to Deploying a Laravel App on Ubuntu Server Using NGINX
M

I am a born-again Christian and a software engineer at Korlie Limited. I'm an ALX graduate and I'm studying software engineering at Limkokwing University. I like chess ❤️

Hello, fellow developers! If you're looking to deploy a Laravel application on a reliable server setup, you're in the right place. Laravel is a powerful PHP framework known for its elegant syntax and robust features, making it ideal for building web apps. Pairing it with NGINX on Ubuntu provides a fast, secure, and scalable environment—NGINX excels at handling high traffic efficiently, while Ubuntu is user-friendly and widely supported.

In this blog post, I'll walk you through the entire process of hosting a Laravel app on an Ubuntu Server with NGINX, from setting up the server to handling frontend assets and scheduling tasks. I'll explain why each step is important, so you understand the reasoning behind it. This guide assumes you're starting with a fresh Ubuntu server (like 24.04 LTS) and have root access. Let's dive in!

Prerequisites: Getting Ready for Success

Before we start, ensure you have:

  • An Ubuntu server with root or sudo privileges. Why? You'll need elevated access to install packages and configure system services.

  • A domain name pointed to your server's IP (optional for testing, but essential for production). Why? This allows users to access your app via a memorable URL instead of an IP address.

  • Basic terminal knowledge. Why? We'll use command-line tools for efficiency and precision.

First, update your system packages:

sudo apt update && sudo apt upgrade -y

Why? This ensures your server has the latest security patches and software versions, reducing vulnerabilities and compatibility issues.

Step 1: Installing the LEMP Stack (Linux, NGINX, MySQL, PHP)

Laravel runs on PHP and needs a web server and database. We use the LEMP stack (NGINX instead of Apache for better performance under load).

1.1 Install NGINX

sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx

Why? NGINX acts as the web server, serving your app's files. Enabling and starting it ensures it runs automatically on boot and is active immediately. NGINX is chosen over Apache because it's lightweight and handles concurrent connections better, which is great for Laravel's API-heavy apps.

1.2 Install PHP and Extensions

sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install php8.3 php8.3-fpm php8.3-mysql php8.3-curl php8.3-mbstring php8.3-xml php8.3-zip php8.3-bcmath php8.3-gd php8.3-intl -y

Why? Laravel requires PHP 8.1+ (we're using 8.3 for the latest features and security). PHP-FPM processes PHP code efficiently with NGINX. The extensions (like mysql for database connections, curl for HTTP requests) are Laravel dependencies—without them, features like authentication or file handling would break.

1.3 Install MySQL (Database) - Optional

sudo apt update
sudo apt install mysql-server -y
sudo systemctl enable mysql
sudo systemctl start mysql
sudo mysql_secure_installation

Why? Laravel needs a database like MySQL for storing data (e.g., users, posts). The secure installation removes default vulnerabilities, like anonymous users, to protect against attacks.

💡
For production environments, using a managed database service from providers like DigitalOcean can be more professional and reliable. Managed databases handle backups, updates, monitoring, and security automatically, allowing your application server to focus solely on running the app.
Running a database directly on the same server as your application consumes disk space, RAM, and CPU resources, which can impact performance as traffic grows. Separating the database from the application server improves scalability, stability, and fault isolation.

1.4 Setting Up the Database for Laravel

For managed database simply connect to the database using tools like MySQL Workbench and proceed to the next step. Skip this step if you are using a managed database.

Log into MySQL:

sudo mysql -u root -p

Then run:

CREATE DATABASE laravel_db;
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Why? Creating a dedicated database and database user follows the principle of least privilege—your app only accesses what it needs, enhancing security. Using a strong password prevents unauthorized access.

1.5 Install Composer

sudo apt install curl unzip -y
curl -sS https://getcomposer.org/installer -o composer-setup.php
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
rm composer-setup.php

Why? Composer manages PHP dependencies. Laravel is installed via Composer, so this tool pulls in all required packages automatically, saving you from manual downloads.

Step 2: Installing and Configuring Laravel

2.1 Create the Project

Navigate to /var/www/:

cd /var/www/
composer create-project laravel/laravel mylaravelapp

Why? This installs a fresh Laravel instance with all core files. /var/www/ is the standard web root on Ubuntu, making it easy for NGINX to serve files.

Or clone the from an existing github project:

cd /var/www/
git clone https://github.com/username/github-repo.git

Then go to your app's directory and install your project's dependencies:

cd gitHub-repo
composer install
💡
Note: If you do not run composer install you will not be able to run artisan commands and other PHP dependencies (packages) your project needs will not work.

2.2 Set Permissions

cd mylaravelapp
sudo chown -R www-data storage
sudo chown -R www-data bootstrap/cache
sudo chmod -R 775 storage
sudo chmod -R 775 bootstrap/cache

Why? Laravel writes logs and cache to these directories. The www-data user (NGINX/PHP's default) needs ownership and write permissions; otherwise, your app could crash with "permission denied" errors.

2.3 Configure the .env File

cp .env.example .env
nano .env

Update keys like APP_NAME, APP_ENV=production, APP_DEBUG=false, database details, and generate the app key:

php artisan key:generate

Why? The .env file holds environment-specific settings. Setting production mode disables debug output for security. The app key encrypts sessions and data—without it, features like authentication fail.

2.4 Run Migrations and Optimize

php artisan migrate
php artisan optimize:clear
php artisan config:cache
php artisan route:cache

Why? Migrations create database tables based on your app's schema. Caching configs and routes speeds up performance by reducing file reads on every request.

Step 3: Handling Frontend Assets with Node.js and npm

Laravel often uses JavaScript for frontend (e.g., via Vite). If you run npm install and get an error, install Node.js:

3.1 Add NodeSource Repository

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -

3.2 Install Node.js and npm

sudo apt update
sudo apt install nodejs -y

Why? npm (Node Package Manager) installs JavaScript dependencies. We use a recent version (20.x) for compatibility with Laravel's Vite (which replaced Mix). Older versions from apt could cause build errors.

3.3 Build Assets

From your project directory:

npm install
npm run dev  # For development
# Or npm run build for production

Why? This compiles CSS/JS files. Laravel's frontend scaffolding relies on this—skipping it means your styles and scripts won't load properly.

Step 4: Configuring NGINX for Laravel

Create a config file, by using this command in your root directory:

sudo nano /etc/nginx/sites-available/mylaravelapp

Open the config file and add this block (customize server_name and root to your specific needs):

server {
    listen 80;
    listen [::]:80;
    server_name example.com; #Use your domain name(s) here
    root /var/www/mylaravelapp/public; #Use the relative path to your app

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files \(uri \)uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME \(realpath_root\)fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Note that the PHP version php8.3 in this directive fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; should match the PHP version installed on your server, otherwise your server will crash.

Save and close the config file, then enable the config and reload nginx:

sudo ln -s /etc/nginx/sites-available/mylaravelapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Why? This routes all requests through Laravel's index.php for proper handling (e.g., pretty URLs). Headers add security against clickjacking. Denying hidden files prevents exposure of sensitive data.

To configure your server to use HTTPS (recommended for production) run this command:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com

Why? SSL encrypts traffic, protecting user data and boosting SEO.

Step 5: Testing and Troubleshooting

  • Visit your domain/IP; you should see Laravel's welcome page (or your app's home page that you built).

  • Check logs: sudo tail -f /var/log/nginx/error.log

  • Ensure services: sudo systemctl status php8.3-fpm nginx mysql

Why test? Catches issues early, like misconfigurations.

Conclusion: Your Laravel App is Live!

Congratulations! You've deployed a secure, performant Laravel app on Ubuntu with NGINX. This setup scales well and follows best practices. For production, add monitoring and backups. If you run into issues, Laravel's docs or communities like Stack Overflow are goldmines.

Happy coding! If you have questions, drop a comment below. 🚀