Laravel is the most popular PHP framework in the world, offering an elegant syntax, a powerful ORM (Eloquent), built-in authentication scaffolding, and a rich ecosystem of first-party packages. Installing Laravel on RHEL 8 involves a few more steps than on a generic Linux distribution because of SELinux and the systemd-managed PHP-FPM service. This tutorial guides you through creating a new Laravel project with Composer, configuring Nginx as the front-end web server, setting the required environment variables, and applying the correct SELinux file contexts so that Laravel can write to its cache and storage directories.

Prerequisites

  • PHP 8.0 or 8.1 installed via AppStream with php-fpm, php-cli, php-mbstring, php-xml, php-pdo, php-mysqlnd, php-bcmath, and php-tokenizer
  • Composer installed and available as /usr/local/bin/composer
  • Nginx installed (sudo dnf install nginx)
  • A database server (MariaDB, MySQL, or PostgreSQL) installed and running
  • A user account with sudo privileges

Step 1 — Create a New Laravel Project

Use Composer’s create-project command to scaffold a fresh Laravel application. The installer pulls the latest stable release from Packagist and places it in the myapp directory.

cd /var/www
sudo composer create-project laravel/laravel myapp
sudo chown -R nginx:nginx /var/www/myapp

Replace myapp with your preferred project directory name. The chown command transfers ownership to the nginx user so the web server process can read application files.

Step 2 — Configure the .env File and Generate the Application Key

Laravel uses a .env file for environment-specific configuration such as database credentials and the application key. A fresh create-project install includes a pre-populated .env, but you must set the correct values for your environment and generate a unique encryption key.

cd /var/www/myapp
cp .env.example .env

# Edit the file with your database credentials
sudo vi .env

Key variables to set in .env:

  • APP_NAME — your application’s human-readable name
  • APP_ENV=production and APP_DEBUG=false for live servers
  • DB_CONNECTION=mysql, DB_HOST=127.0.0.1, DB_DATABASE, DB_USERNAME, DB_PASSWORD

After saving the file, generate the application key:

php artisan key:generate

Step 3 — Set Storage and Cache Directory Permissions

Laravel writes compiled views, session files, and cache data under storage/ and bootstrap/cache/. These directories must be writable by the web server user.

sudo chown -R nginx:nginx storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache

On RHEL 8 with SELinux in enforcing mode, file permissions alone are not sufficient. Apply the correct SELinux file context to allow the Nginx/PHP-FPM process to write to those directories:

sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/myapp/storage(/.*)?"
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/myapp/bootstrap/cache(/.*)?"
sudo restorecon -Rv /var/www/myapp/storage /var/www/myapp/bootstrap/cache

Step 4 — Configure Nginx for Laravel

Create an Nginx server block that routes all requests through Laravel’s index.php front controller and passes PHP files to PHP-FPM.

sudo vi /etc/nginx/conf.d/myapp.conf

Paste the following configuration, adjusting server_name and the root path to match your setup:

server {
    listen 80;
    server_name myapp.example.com;
    root /var/www/myapp/public;
    index index.php index.html;

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

    location ~ .php$ {
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /.(?!well-known).* {
        deny all;
    }
}
sudo nginx -t && sudo systemctl reload nginx

Step 5 — Run Database Migrations

Laravel’s Artisan CLI can create all the default application tables in your database using the bundled migrations.

cd /var/www/myapp
php artisan migrate

If the database connection fails, double-check the credentials in .env and ensure the database server is running and the user has been granted the necessary privileges.

Step 6 — Optimise for Production

Laravel provides several Artisan commands that compile routes, configuration, and views into cached files, significantly reducing request latency in production.

php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan optimize

Re-run these commands any time you deploy new code. Use php artisan optimize:clear to remove all caches during development or before re-caching after a change.

Conclusion

You have deployed a fresh Laravel application on RHEL 8, configured Nginx to serve it through PHP-FPM, applied the necessary SELinux file contexts, and optimised the application for production. Your Laravel site is now live and ready for feature development. The SELinux and permissions steps are the most common pitfall on RHEL-based systems, so keep those commands handy for future deployments.

Next steps: How to Install Symfony on RHEL 8, How to Configure PHP-FPM with Nginx on RHEL 8, and How to Install PHP on RHEL 8.