This guide builds a production LAMP server for a Laravel application on your own VPS running AlmaLinux 9: Apache, MariaDB, PHP-FPM from the Remi repository, Composer, a virtual host, SELinux-correct permissions and free HTTPS. It applies to a VPS you manage yourself, not to shared hosting, where the server is already set up and you can't install system packages.
On AlmaLinux 9: update the system, create a sudo user with SSH key login, open HTTP and HTTPS in firewalld, install Apache and MariaDB, install a current PHP from Remi with PHP-FPM, install Composer, create the Laravel project in /var/www, point an Apache virtual host at its public folder, give the storage and bootstrap/cache folders the right group and SELinux label, then add Let's Encrypt with Certbot. Use a Laravel release that still receives security fixes; Laravel 10 no longer does.
Laravel 10 stopped receiving security fixes in February 2025. Start new projects on the current Laravel release and check its minimum PHP version on the official Laravel documentation before you choose a PHP version. The steps below work for current releases; commands that differ are noted.
1. Prepare the VPS
Log in as root with the details from your VPS welcome email, then update and create a normal user for daily work:
dnf -y update
adduser deploy
passwd deploy
usermod -aG wheel deployCopy your public key to the new user from your own computer (ssh-copy-id deploy@your-server-ip), confirm you can log in with it, and only then disable root and password logins in /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication noFiles in /etc/ssh/sshd_config.d/ are read first and win, so check them for a PasswordAuthentication yes line. Run sudo sshd -t to test the configuration, then sudo systemctl reload sshd. Keep your current session open until a new login works. More hardening is in our SSH security hardening checklist.
Moving SSH off port 22 is optional. On AlmaLinux you must also allow the new port in SELinux (semanage port -a -t ssh_port_t -p tcp 2222) and in firewalld before restarting SSH, or you will lock yourself out.
2. Firewall
firewalld is the standard firewall on AlmaLinux. Make sure it runs and allow web traffic:
sudo dnf -y install firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reloadSSH is allowed by default. Do not open port 3306: Laravel talks to MariaDB on the same server.
3. Apache
sudo dnf -y install httpd mod_ssl
sudo systemctl enable --now httpdBrowse to http://your-server-ip and you should see the AlmaLinux test page. mod_rewrite, which Laravel's .htaccess needs, is loaded by default.
4. MariaDB
sudo dnf -y install mariadb-server
sudo systemctl enable --now mariadb
sudo mariadb-secure-installationAnswer yes to removing anonymous users, the test database and remote root login. Then create a database and a user for Laravel:
CREATE DATABASE laravel_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'laravel_user'@'127.0.0.1' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'127.0.0.1';Run these in sudo mariadb. No FLUSH PRIVILEGES is needed after CREATE USER and GRANT.
5. PHP from the Remi repository
AlmaLinux's own PHP streams lag behind; Remi provides current, maintained builds. Enable EPEL and Remi, then pick a PHP stream that your Laravel version supports:
sudo dnf -y install epel-release
sudo dnf -y install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf module list php
sudo dnf -y module reset php
sudo dnf -y module enable php:remi-8.4
sudo dnf -y install php php-cli php-fpm php-mysqlnd php-mbstring php-xml \
php-bcmath php-intl php-zip php-gd php-opcache php-process git unzip
sudo systemctl enable --now php-fpm
sudo systemctl restart httpdReplace remi-8.4 with the stream you chose from dnf module list php. On AlmaLinux, installing php-fpm also installs an Apache config that sends .php files to PHP-FPM, so you don't add a handler by hand. Check with php -v.
Adjust /etc/php.ini for your app, for example memory_limit, upload_max_filesize, post_max_size and date.timezone = Asia/Kolkata, then sudo systemctl restart php-fpm.
Older guides test PHP with a public phpinfo.php. It shows your paths, modules and environment to anyone. Use php -v and php -m on the command line instead, or delete the test file immediately.
6. Composer
Install Composer as a normal user with the verified installer commands from the official download page (getcomposer.org/download), which check the installer's hash before running it. Then move it into your path:
sudo mv composer.phar /usr/local/bin/composer
composer --version7. Create the Laravel project
Work as the deploy user in /var/www, where SELinux already expects web content:
sudo mkdir /var/www/myapp
sudo chown deploy:deploy /var/www/myapp
cd /var/www
composer create-project laravel/laravel myappFor an existing app, git clone it into /var/www/myapp and run composer install --no-dev --optimize-autoloader, then cp .env.example .env and php artisan key:generate.
Edit /var/www/myapp/.env. Recent Laravel versions default to SQLite, so set MariaDB explicitly:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://example.com
DB_CONNECTION=mariadb
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=a-long-random-passwordOn older Laravel versions without the mariadb driver, use DB_CONNECTION=mysql. Then run php artisan migrate --force.
8. Permissions and SELinux
Apache runs as the apache user on AlmaLinux (not www-data, which is Debian and Ubuntu). Only two folders need to be writable by the web server:
cd /var/www/myapp
sudo chgrp -R apache storage bootstrap/cache
sudo chmod -R ug+rwX storage bootstrap/cache
sudo find storage bootstrap/cache -type d -exec chmod g+s {} +
sudo dnf -y install policycoreutils-python-utils
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
sudo setsebool -P httpd_can_network_connect_db 1The last line lets Apache and PHP-FPM connect to the database over TCP. If your app calls outside APIs (payment gateways, mail services), also run sudo setsebool -P httpd_can_network_connect 1. Keep SELinux enforcing; switching it off with setenforce 0 hides problems rather than fixing them.
9. The Apache virtual host
Create /etc/httpd/conf.d/myapp.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/myapp/public
<Directory /var/www/myapp/public>
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/myapp-error.log
CustomLog /var/log/httpd/myapp-access.log combined
</VirtualHost>The document root is the public folder only, so .env and your code are never served. Check and reload:
sudo apachectl configtest
sudo systemctl reload httpdPoint your domain's A record at the VPS IP address (see how to change your domain's DNS settings) and open the site; you should see the Laravel welcome page.
10. HTTPS with Let's Encrypt
sudo dnf -y install certbot python3-certbot-apache
sudo certbot --apache -d example.com -d www.example.com
sudo systemctl list-timers | grep certbotCertbot creates the HTTPS virtual host and a renewal timer. Test renewal with sudo certbot renew --dry-run.
11. Production finishing touches
- Cache configuration and routes:
php artisan optimizeafter every deploy. - Scheduler: add
* * * * * cd /var/www/myapp && php artisan schedule:run >> /dev/null 2>&1to thedeployuser's crontab. - Queue workers: run
php artisan queue:workunder a systemd service withRestart=always, and restart it after each deploy. - Updates: apply
sudo dnf updateregularly, and keep Laravel and Composer packages patched. - Backups: dump the database (
mariadb-dump) and copy it off the server on a schedule. - A web application firewall such as ModSecurity is optional; it needs tuning for your app, or it blocks legitimate requests.
12. Running this on Domain India
Domain India VPS plans are KVM servers with full root access and a choice of Linux operating system, including AlmaLinux. They are self-managed by default, so the steps above, updates and security are yours to run. cPanel is not offered on our VPS plans.
- 1 vCPU
- 2 GB DDR4 RAM
- 64 GB NVMe SSD Storage
- 2 TB Monthly Bandwidth
- 2 vCPU
- 4 GB DDR4 RAM
- 128 GB NVMe SSD Storage
- 3 TB Monthly Bandwidth
The cards show live list prices, excluding 18% GST. If you would rather not run a server, a standard Laravel app with a cron-driven scheduler can run on shared hosting, built locally and uploaded or with Composer over jailed SSH; queue workers, Redis and Octane need a VPS. See Laravel on cPanel and DirectAdmin.
Which Laravel version should I install?
Install the current Laravel release, which receives bug and security fixes. Laravel 10 stopped receiving security fixes in February 2025. Check the minimum PHP version for your chosen release in the official Laravel documentation.
Why do I get a 500 error or "permission denied" on storage?
On AlmaLinux both file permissions and SELinux must allow writing. Give the apache group write access to storage and bootstrap/cache, and label both folders httpd_sys_rw_content_t with semanage and restorecon.
Why can't Laravel connect to MariaDB even though the password is right?
On AlmaLinux, SELinux blocks the web server from making database connections over TCP until you run setsebool -P httpd_can_network_connect_db 1. Also check that the database user's host matches DB_HOST.
Should I use www-data as the owner on AlmaLinux?
No. www-data is the web server user on Debian and Ubuntu. On AlmaLinux and Rocky Linux, Apache and PHP-FPM run as apache.
Is a Domain India VPS managed?
It is self-managed by default. You get full root access and you look after the operating system, security updates and software yourself.
Can I run Laravel on shared hosting instead?
A standard Laravel app runs on Domain India shared hosting if you build it on your own computer and upload it with the vendor folder, and use a cron-driven scheduler. Queue workers, Redis, Octane and websockets need a VPS.
Ready to build? Compare VPS plans, read Laravel on cPanel and DirectAdmin if shared hosting may be enough, or ask us through a support ticket.
Full root access on a self-managed KVM VPS, ready for Apache, MariaDB, PHP and Laravel.
See VPS plans