All Articles
Tutorialslaravelphplinuxapachemysqldevops

Deploying Laravel on a LAMP Stack

5 March 2025· 12 min read· Andrew Arscott

Introduction

When you have completed your development, you will naturally want to get your website online. Probably the quickest method to do this is via Laravel Forge. Forge is a management solution which will do all the heavy lifting for you, including provisioning a server with the necessary software, databases, caching solutions and so much more. Forge takes all of the hard work out of managing a web server and integrates with solutions like Akamai, AWS and many more. You can even bring your own server if you want to from a supplier not supported by them.

Forge isn't for everyone though. Some people still prefer to manually manage their server, and personally, I'd recommend doing it at least once so you understand what is happening under the hood when you use a solution like Forge.

The most common stack you'd encounter is LAMP: Linux, Apache, MySQL and PHP. Some setups, including Forge, will use Nginx instead of Apache, but for this tutorial we will be using Apache.

The Laravel documentation has information about deployment — we recommend reviewing it, which can be found here.

Requirements

Server

Naturally, you will need a server. In this tutorial we will be using an Ubuntu server. There are other flavours of Linux available like CentOS, but our preference is Ubuntu. You could also host on a Windows server if you desired, but the most common setup for Laravel would be a Linux server.

Web Server Software

Our web server software will be Apache. Apache has been around for a long time and is the time-trusted server of many developers.

Database

Laravel supports many different databases through its assortment of drivers. In this tutorial, we will be using MySQL.

PHP

At the time of writing, Laravel 10 is the current major version, and it has its own requirements — you can find these on their website.

They are:

  • PHP >= 8.1
  • Ctype PHP Extension
  • cURL PHP Extension
  • DOM PHP Extension
  • Fileinfo PHP Extension
  • Filter PHP Extension
  • Hash PHP Extension
  • Mbstring PHP Extension
  • OpenSSL PHP Extension
  • PCRE PHP Extension
  • PDO PHP Extension
  • Session PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension

Redis (optional)

Redis is my preferred caching tool. It can also be used to handle your job queues, and when used in conjunction with a tool like Laravel Horizon, it makes a really nice experience for managing your queues. Of course you may choose another caching solution — or have no queues running at all — so this is entirely up to you.

Composer (optional)

You may choose to install Composer so you can pull your dependencies on your server as part of your deployment process. If you do not, you will need to push the dependencies up with your website pre-installed.

Node / NPM (optional)

This step will depend on your build and deployment process. Many developers like to build their assets and store them in source control. This means that when the code is put onto the server — either via pulling directly from git, or by uploading via FTP — the assets are already built. I personally like to build assets on the server so they don't have to live in my source control, and equally because when I used to build before pushing to the server, I'd always forget to build!

Git (optional)

Like above, this step depends on your build process. Forge allows you to deploy from a git repo and then, with its deployment tools, pull automatically when you push to your production branch. This may not be required for your deployment method, especially if you are pushing via FTP instead.

Preparing Your Server

First things first, let's update our package manager. This will ensure our server has the latest package information before we start installing anything.

sudo apt update

Installing Apache

You can install Apache using the following command:

sudo apt install apache2

Follow the prompts to confirm Apache's installation. This should take a few minutes to complete.

Note: Some cloud providers have their own firewall tools running outside of the Linux box, so the firewall section below may not always be applicable.

Once the installation has completed, we need to tell the firewall to allow traffic on the relevant ports. We want port 80 (insecure HTTP) and port 443 (HTTPS). As we won't have an SSL certificate straight away, we'll enable both. You can always restrict this to HTTPS-only later.

Ubuntu's default firewall config tool is called UFW (Uncomplicated Firewall). To list the profiles currently available, run:

sudo ufw app list

In the output, you should see Apache, Apache Full, and Apache Secure. Apache is port 80 only, Apache Full is both port 80 and 443, and Apache Secure is 443 only. We want Apache Full:

sudo ufw allow in "Apache Full"

You can confirm this has been applied by running:

sudo ufw status

The output will contain entries for Apache Full.

At this point, Apache will be running and serving its default page. You can confirm this by loading your server's IP address in a browser, or a domain you have pointing to the server.

Installing MySQL

Now we need a database. Install the MySQL server using the following command:

sudo apt install mysql-server

Confirm you wish to install the packages when prompted. This process will take a few minutes.

Next, we need to configure the freshly installed MySQL server:

sudo mysql_secure_installation

This will walk you through several configuration options:

  • VALIDATE PASSWORD COMPONENT — checks that passwords meet a complexity requirement. Optional, but recommended for production.

Validate password component prompt

  • Anonymous users — the prompt recommends removing these before moving to production.

Anonymous user prompt

  • Root login — restricting root access to localhost only is a good idea as it prevents brute-force attempts from the network.

Root login restriction prompt

  • Test database — a test database is included by default. You can remove it now or keep it around for testing.

Test database prompt

  • Reload privilege tables — always say yes to this; it ensures your config changes take effect immediately.

Once complete, you can verify MySQL is working by accessing the console:

sudo mysql

This will log you in as root using sudo for credentials. To exit the console, type exit.

MySQL console

Installing PHP

We want to add a PPA first so we can pull the most recent PHP version:

sudo add-apt-repository ppa:ondrej/php

Then install PHP with the extensions Laravel requires:

sudo apt install php libapache2-mod-php php-mbstring php-cli php-bcmath php-json php-xml php-zip php-pdo php-common php-tokenizer php-mysql

Confirm the installation ran correctly:

php -v

Installing Composer

Composer is the package manager for PHP. This is optional, but useful if you want to install dependencies on the server as part of your deployment pipeline.

Download and run the installer:

curl -sS https://getcomposer.org/installer | php

At this point you may wish to verify the hash of the installer. We'll assume you know how to do this.

Move the Composer binary into your PATH:

sudo mv composer.phar /usr/local/bin/composer

Make it executable:

sudo chmod +x /usr/local/bin/composer

Verify it installed correctly:

composer --version

At the time of writing, this will give you Composer 2.

Installing Node and NPM

Node is used to build front-end assets. This is optional if you prefer to build locally and commit the compiled output.

To install Node 20:

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - &&\
sudo apt-get install -y nodejs

If you need a different version, see the nodesource distributions repo for details.

Confirm Node is installed:

node -v

Then install NPM:

sudo apt install npm

And confirm:

npm -v

Summary

By following this guide you now have a server set up and ready to host a Laravel application. There are additional services you can layer on top — Redis for caching and queues, Supervisor for running queue workers, and Let's Encrypt for SSL — which I'll cover in follow-up guides. Keep an eye out for those.

If you'd rather skip the manual setup, Laravel Forge handles all of this for you in a few clicks — well worth the subscription if your time has value.

Have thoughts on this? Get in touch.