Introduction
Laravel is a popular open-source framework that makes it easy for developers to build web applications. It offers out-of-the-box components and features that can be included in a project to provide different functionality for a web application.
In other words, instead of building an authorization function from scratch, or having to write your own code with low-level details for interacting with a caching system, you can make use of pre-written code packages that are secure, efficient, and performant.
Laravel prioritizes the ease-of-use by offering an elegant, expressive, and simple syntax that can be quickly learnt, understood, and implemented, making it a very popular framework among developers.
However, developing and building an application is only one part of the story, or – as the saying goes – “an application running on a developer’s machine doesn’t generate revenue”. So, in order for your application to come to life it needs to be deployed on a production server somewhere. Needless to say, this server and other related infrastructure components should provide the required performance, reliability, and scalability for the application. This leaves us with a simple answer to these requirements, which is the “Cloud”.
Combining the features of Laravel with the capabilities of a Cloud infrastructure, we can have a complete solution for building, deploying, and scaling our applications starting from the development phase, and up to the live production environment. All while providing high performance and extreme scalability.
In this guide, we’re going to cover the step-by-step process for building a Laravel app and deploying it to a Cloud server on UpCloud. Whether you’re a complete beginner or have prior experience with Cloud deployments, you’ll be able to understand the following:
- How to setup Laravel and the key components of a Laravel project
- How to create, build, and locally test a Laravel project
- How to create a Cloud server with the required configuration to deploy your application
- How to scale and optimize your server for best performance
By the end of this guide, you’ll have a running Laravel application that is deployed on a Cloud environment and making use of its underlying infrastructure scalability and performance features.
Prerequisites
Before diving into our scenario, make sure you go through the following checklist to be able to follow along with this guide:
- Create an UpCloud account: This gives you access to different UpCloud services using the GUI control panel, command-line interface, or the API.
- Deploy a Cloud server on UpCloud: This is going to be our target server where we’ll deploy our application.
- Install PHP and composer: Laravel uses PHP as its core, so you’ll need to have PHP and composer installed in your environment before running Laravel. For this guide, we’ll be running on Ubuntu so you can use the apt package manager to install PHP. For composer, you can download and use its installer from the command line.
- Familiarity with using the CLI: We’ll be using some basic commands throughout this guide to install our tools, navigate project directories, and work with SSH.
Step 1: Setting Up Laravel
The first step in our scenario is to prepare our local environment by installing the Laravel framework. There are two common ways to install Laravel:
- Directly using composer: This will use composer to create your Laravel project and download all required Laravel files with the following command:
composer create-project --prefer-dist laravel/laravel <Project-name> |
- Using Laravel installer: The Laravel installer is a package that makes it easy to create and setup a Laravel project. You can download this package with the following command:
composer global require laravel/installer |
Then you’ll be able to create your Laravel project using the following command:
laravel new <Project-name> |
Install Laravel on the Cloud Server
Now after preparing the local environment, we’ll also need to install Laravel on our Cloud server with the following steps:
- Deploy the server on UpCloud if you haven’t already done so. For this guide, I’ve created the Cloud server with the Ubuntu operating system, so I’ll be installing Laravel on Ubuntu.
- Connect to the server using SSH. You’ll first need to generate an SSH key and then connect to the server using the server’s IP address and the generated SSH key. You can find the instructions for different operating systems in the How to connect section under the server information in the UpCloud control panel:

- Since I’m connecting from a local Linux environment, I’ll use the following command:
ssh -i SSH-key root@IP-address |
Make sure you replace SSH-key with your SSH key file, and IP-address with your server IP.

- Now that I’m connected to my Cloud server, I’ll use the composer method to install Laravel with the command
composer create-project --prefer-dist laravel/laravel <Project-name>
. You’ll need to already have PHP and composer installed:

- Finally, we can verify that everything is installed correctly on our Cloud server by checking and navigating to our project folder using the following commands:
cd myProject
ls

Create and Test a Laravel App Locally
Now that we have prepared our local and Cloud server environments, the next step is to create a simple Laravel application. We’ll start by creating the application locally, I’ll again use the composer method:
composer create-project --prefer-dist laravel/laravel myProject |
Next let’s navigate to our project directory and start our local development server:
cd myProject
php artisan serve
The php artisan serve
command starts the built-in web server of PHP. This is useful for quickly testing your application on the local development environment without the need to install a dedicated web server like Apache or Nginx.

As we can see in the above image, our local development server is started and listening for requests on port 8000. Now let’s test accessing our application from the same local environment with the following command:
curl localhost:8000 |

As we can see, we’re able to get the response from our server.
Step 2: Building Your Laravel App
In the previous section, we tested the sample Laravel code provided for us by default when we created our project. Now let’s understand the different components that make up our application so that we can add some functionality to it using these components.
Laravel follows the MVC design pattern principles, which makes the project code maintainable, scalable, and well-structured. The main components of a Laravel project are as follows:
- Routes: A route provides a way to map a specific URL path to a specific action to be executed. For example, we might want to display a welcome message when a user sends a GET request to our application on the
/welcome
URL. In that case, we define a route with the/welcome
endpoint that triggers a function which displays the welcome message. - Model: A model handles different operations related to the data in our application. It is responsible for storing, retrieving, and manipulating different data structures used in our application. A model usually interacts with external data stores like an SQL database or an in-memory cache.
- View: This is simply the part of our application that provides the user interface that a client interacts with. It is responsible for presenting the state of the data in our application or receiving user input to manipulate this data.
- Controller: A controller is responsible for the business logic and is usually implemented as a Class with a set of methods each handling a specific functionality. A controller also sits in between the view and the model to manage the data exchange between them.
In the default Laravel project directory structure, each of the above components can be found in a specific location. For example, the routes are defined under the /routes
directory in the project’s root as follows:

In the above image, we navigated to the /routes
directory under the project’s root, then inside the /routes
directory we viewed the contents of the web.php
file. This is where our routes are going to be defined. Currently, there’s a single route for the root (“/”)
URL which returns a view called welcome
.
Now let’s check this welcome
view. Views in Laravel’s directory structure are located under resources/views
as follows:

As we can see, under the resources/views
there’s a single file called welcome.blade.php
. The first part of the file name is the view name, which is welcome
. The .blade.php
extension specifies that the file is using the blade templating language.
Inside the file, we can see some HTML content which is the same as what we’ve seen when we sent a request to our application in the previous section using the curl
command on port 8000.
So, how did this flow work?
When we typed “curl localhost:8000”
, we were sending an HTTP GET request to our application, since we didn’t specify any path URL in our request, it was sent to the root (“/”
) or home page.
This request matched the configured route that we’ve seen under the /routes
directory, which registers a route for the root (“/”) path. So, the function inside this route was triggered and it called the welcome
view.
Finally, our welcome
view returned the HTML contents that it contains in the response, after applying the required templating using the blade language.

Now let’s make some small changes to our Laravel project. First, we’ll replace the contents of the welcome
view with the following code:
<html>
<body>
<h1>Hello world from Laravel</h1>
</body>
</html>

Next we’ll create another view called greeting
with the following content:
<html>
<body>
<h1>How are you, {{ $name }}</h1>
</body>
</html>

Now let’s create another route that calls this greeting view by adding the following code to our web.php file under the /routes directory:
Route::get('/{name}', function ($name) {
return view('greeting', ['name' => $name]);
});

So what we did here is that we registered a new route with the URL /{name},
meaning that a dynamic value can be passed in the request path after the (“/”)
and it will replace the name
variable. Next we call the greeting
view, and we’re telling it to replace the {{ $name }}
placeholder in the blade template with the value of the $name
variable, which was originally received in the request.
Now let’s start our local development server using the php artisan serve
command (make sure you issue the command from the project’s root directory):

Next let’s test our routes by sending requests to each path URL:

As we can see, we’re able to get the response from the view corresponding to each route.
We can also see our requests showing in the output of our server logs:

Now that we’ve built our Laravel app, the next step is to deploy it to our Cloud server.
Step 3: Deploying Laravel to the Cloud Server
There are multiple ways to deploy our Laravel project from the local environment to the Cloud server. For this guide, we’re going to use Git following this procedure:
- Create a Github repository under your Github account. This will be the remote repository where we’ll push and share our local Laravel project.
- Initialize the Laravel project’s directory as a local Git repository with the following command:
git init -b main
This will set the default branch name as main
.

- Add all the project files in the working directory to the staging area and create a new commit with the following commands:
git add .
git commit -m <Your commit message>

Something that’s worth mentioning here is the vendor/
directory. This is the location where PHP composer downloads the required dependencies. It can be ignored when pushing the Laravel project to the Github repository, and then we can download the dependencies again using composer on the target server where we deploy our application.
- Set the new Github repository as a remote for this local repository with the following command:
git remote add origin <Github repository URL>

- Push your local repository to the remote Github repository with the following command:
git push -u origin main

- Connect to your Cloud server using SSH:

- Clone the Github repository on the Cloud server with the following command:
git clone <Repository URL>

Now we can see that our project’s content is deployed to the Cloud server with the changes we made in the routes and views.
Set up Apache Web Server to Serve the App
In our local environment, the PHP built-in web server was enough to test our changes quickly and easily. However, when we deploy our Laravel app to a production server, we need a more powerful web server to handle user requests. For this guide, we’ll be using Apache as our web server.
We can install Apache on our Ubuntu Cloud server with the following steps:
- Update the package index files using the command
sudo apt update
- Install the Apache package using the command
sudo apt install apache2 -y
- Verify the status of the service using the command
sudo systemctl status apache2
- If everything is working fine, you should see the service status as active

- Test the Apache web server by opening a web browser to the server IP address:

Now that we have our Apache web server running, we need to configure it to work with our Laravel application.
We can apply this configuration in multiple ways, for example, we can modify the main apache2.conf
file directly, or we can create a separate virtual host configuration.
For this guide, we’ll be using a virtual host configuration to host our Laravel app following this procedure:
- Move the Laravel project’s directory under the Apache web root directory:
sudo mv <Your Laravel project directory> /var/www/html
- Navigate to the apache sites-available configuration directory:
cd /etc/apache2/sites-available/
- A default template configuration for virtual host is provided under a file called
000-default.conf
, make a copy of this file to create a virtual host for our Laravel app:
sudo cp 000-default.conf laravel-app.conf
- Replace the contents of the new file with the following:
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName <Your server IP address/hostname>
DocumentRoot /var/www/html/<Your Laravel project directory>/public/
<Directory /var/www/html/<Your Laravel project directory>>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
There are a couple of important things to note in the above configuration. The ServerName
here will be used by Apache when checking the Host
in the requests sent to the server. If you don’t have a DNS server where your host name is mapped to the server IP, you should use the server IP address directly in this ServerName
configuration.
Replace <Your Laravel project directory>
with the directory name that includes your Laravel project files (the one we moved previously). This will allow Apache to locate the index.php
file which is the entry point for requests sent to the Laravel application.

- Enable the Apache rewrite module, enable the Laravel virtual host, and then restart the Apache service with the following commands:
sudo a2enmod rewrite
sudo a2ensite laravel-appsudo systemctl restart apache2
Prepare Environment Configuration and Database
Decoupling the configuration from application code is a common pattern that allows the application to be more maintainable and portable across different environments. Laravel uses a simple .env
file to provide different environment configurations to an application.
This .env
file is created for you by default in the project’s root directory, and it can be modified according to your needs and environment specifics.
For the purpose of this guide, we’ll only be going through the database configuration inside the .env
file, but most of the other configurations should be pretty descriptive and easy to understand.
Now let’s view our .env
file and check the database configuration:

As we can see, we’ve a typical database connection configuration that currently has some default values. Now we need to create a database instance and populate these configurations with our instance details.
A simple, yet powerful option is to use a Cloud managed database instance. Managed databases take the heavy lifting of provisioning and setting up the database server, and reduces the maintenance and operational overhead.
You can use UpCloud managed databases which offer a variety of the most popular database engines like PostgreSQL and MySQL. For this guide, we’ll be using the UpCloud PostgreSQL managed database.
After you create your UpCloud managed database, you can get all the database connection details from the UpCloud control panel under your database instance:

Next we can add the database details to our .env
file:

After the configuration is added to the .env
file, we need to set up the database schema by running the following command:
php artisan migrate
After the migration is complete, let’s try to access our application routes from a browser:


As we can see, our previously configured routes are providing the correct response.
Step 4: Scaling the Laravel Application
Availability and performance are of the top priorities for almost any application. Users definitely won’t like to access an application and find its services to be down, or slowly processing their requests. So, there’s always a tight relation between these two requirements and customer satisfaction.
The ability to scale your application on-demand to satisfy the changing availability and performance requirements is a crucial part of any deployment, and that’s where Cloud services really shine the most.
Instead of having to manually provision additional infrastructure on your own, and calculate a lot of costs up-front according to estimations, Cloud services facilitate the scaling process by offering capacity resources that can be provisioned and released on-demand, and – most importantly – you only pay for what you use, no upfront estimations or CAPEX investments required.
Now applying this to our scenario, just having a functional application running on the Cloud server is not the end of the story. We’ve to understand how we can scale this application when there’s a demand.
UpCloud offers different ways to scale our Cloud servers, let’s explore how to implement each of them.
Vertical Scaling using Hot Resize
Vertical scaling – also called scaling up – refers to the process of scaling our servers by adding more compute resources. For example, if we upgrade a server instance from 4GBs of RAM to 8GBs of RAM, this is a scale up process.
Since vertical scaling involves modifying the hardware configuration of the server, it usually requires taking the server down for some time to apply these changes, which causes some down time for the applications running inside this server.
UpCloud provides a seamless scale-up feature called Hot resize
that allows adding more resources to a Cloud server without the need to shutdown the server. Let’s apply this to our server:
- From the UpCloud control panel, select the server you want to scale up

- Go to the plan tab and check the current and available plans.

- Select the target plan you want to scale up to.

- Click on Save changes at the bottom of the page

- And we have our additional resources added to the server without application downtime.

Horizontal Scaling using a Load Balancer
Horizontal scaling – also called scaling out – is the process of scaling our application by adding more server instances. Usually, all the server instances are replicas of each other and contain the same application code.
Scaling out can sometimes provide some advantages compared to scaling up. For example, in a scaling up scenario you might be limited by a maximum amount of resources a single instance can include, while scaling out can add as many instances as you need. Another significant advantage for the scaling out is that it increases the availability and not only the performance, as you’ll have multiple instances serving your application traffic, a failure in one instance will not take your application down completely.
However, scaling out configurations are usually more complex than those of scaling up. Scaling out typically involves creating multiple replicas from the server, and properly configuring a load balancer to distribute the traffic across the server instances.
Now let’s walk through the steps for scaling out our application on UpCloud:
- Creating additional instances from our server: The first step is that we need to create additional Cloud servers that are replicas from our current server and contain the same application. Instead of creating these servers from scratch, UpCloud provides a simple option by cloning our current server

- The cloning feature requires that we shutdown our server first:

- As we can see, the Clone option became available after the server was stopped.
- Provide the configuration you want for the new server and click on Clone at the bottom of the page:

- Once the clone operation is finished we’ll be able to see both servers in our server list.

- Modify required Apache/Laravel configuration: Some configuration inside the server might need to be changed. For example, I’m going to change the virtual host configuration to provide the new server IP address.

- I’m also going to modify the
welcome
view in the Laravel project to indicate that it’s coming from the other server.

- We can verify it’s working fine by connecting to the new server IP from a browser.

- Create a private network: Private networks allow servers and resources to communicate with each other using private IPs on an isolated network as if they were connected to a network switch.
- Attach the servers to the private network: Under the network tab of your server, select attach SDN private network and choose the network you created earlier.

- Now the next step is to create a Load Balancer to distribute the traffic across the 2 servers. Make sure you create the Load Balancer in the same location as your servers and attach it to the same private network.


- After adding the necessary backend and frontend configuration we should be able to reach our application through the Load Balancer.


- We can also see that the request is served from the 2 different servers.
Best Practices for Laravel Deployment
Just getting a functional Laravel application might not be sufficient for a production environment. We need to improve our deployment further by implementing additional configurations that satisfy more application requirements. These requirements can roughly be divided into the following pillars:
- Security: Secure your app by using encrypted HTTPS connections to the web server instead of plain HTTP, incorporate Laravel’s authentication and authorization features into your app, and implement fine-grained access control and firewall configuration on your Cloud servers.
- Performance: Make use of UpCloud scalability features to dynamically adjust your server infrastructure resources for responding to the change in application demand. Leverage the global presence of UpCloud services to deploy your app in multiple locations that are closer to your clients, and implement caching and CDN techniques to improve your app response time and latency.
- Availability/Disaster Recovery: Boost your application’s uptime by implementing techniques such as clustering, load balancing, and replication. Leverage UpCloud server backup features and tailor it for your specific needs.
- Observability and Monitoring: Supercharge your deployment by implementing appropriate metrics, logging, and tracing solutions that give you insights about your application behavior. Analyzing the data from these solutions can dramatically support your application design and operational decisions. You can use the built-in statistics and monitoring data provided by UpCloud for their different services or use additional tools like Prometheus, Elasticsearch, and Grafana.
Conclusion
Laravel is a popular web application framework that provides an elegant and simple syntax for developers. It offers out-of-the-box security, performance, and scalability features. We can boost the performance of our Laravel application even more by deploying it to a Cloud environment and making use of the massive scalability of the Cloud.
In this guide, we covered how to build, deploy, and scale a Laravel application. We used UpCloud high performance servers to install and set up Laravel. Then we explored the different components of a Laravel project and added some functionality to our application. After that we deployed our Laravel application to the Cloud server and installed Apache to serve web requests. Finally, we checked the different methods that UpCloud offers for scaling our server.
Want to take the first steps for running your Laravel app in the Cloud? Try UpCloud now and explore a set of Cloud services optimized for your Laravel deployment.
FAQs
- How do I install Laravel on an Ubuntu server?
You can use Composer or the Laravel installer package to install Laravel on Ubuntu. Ensure all dependencies like PHP are installed. You can follow the steps outlined in the guide.
- What is the best way to deploy a Laravel app?
Using a cloud server like UpCloud’s fast cloud servers that are optimized for running Laravel applications. Upload your files, configure a web server, and set up the database using Laravel Artisan.
- How can I scale a Laravel app on UpCloud?
Implement load balancing and vertical scaling on UpCloud. Optimize app performance by caching and using queues.
- What tools can I use for Laravel deployment?
Tools like SSH, Git, and deployment managers like Envoyer can simplify deployment.