Table of Contents
#Local development environment
#Running Laravel without the database
#Running Laravel with the database
#Preparing for production
#Deploying to the cloud
#Conclusion
#UPDATE: September 8, 2024
Home Backend Development PHP Tutorial Prepare your Laravel app for the cloud

Prepare your Laravel app for the cloud

Mar 07, 2025 am 01:02 AM

The recent announcements at LaraconUS have sparked a renewed interest in cloud-based deployments within the Laravel community. As the debate continues on how to deploy your apps, one thing is clear: the cloud is becoming a more viable option for Laravel users.

In this article, we'll explore how to prepare your Laravel app for deployment in a cloud environment using FrankenPHP, Caddy, Dockerfiles, and finally deploying it to Sevalla.

So where do we start? In the local environment of course! ?

#Local development environment

For the sake of simplicity, we'll assume you have a fresh Laravel app installed on your local machine, which connects to a PostgreSQL database to read/write some data.

Before we move on, make sure you have a .env file in your project root with the following content:

.env:

<!-- Syntax highlighted by torchlight.dev -->...
DB_CONNECTION=pgsql
...
Copy after login
Copy after login
Copy after login

Once that's verified, we can start building. ? ☕️

It's always a good idea to have a local development environment that closely resembles your production environment. This way, you can catch any issues early on and avoid surprises when you deploy your app in production.

To mimic the production setup we're going to use Docker and Docker Compose. If you don't have Docker installed on your machine, you can download it from the official website.

#Running Laravel without the database

First off, create a new file called compose.yml in the root of your Laravel project and add the following content:

compose.yml:

<!-- Syntax highlighted by torchlight.dev -->services:
  php:
    image: dunglas/frankenphp:php8.3-bookworm
    environment:
      SERVER_NAME: ":8080"
    ports:
      - 8080:8080
    volumes:
      - .:/app
Copy after login
Copy after login
Copy after login

This configuration file defines a service called php that uses the dunglas/frankenphp:php8.3-bookworm image, which is a FrankenPHP image that includes necessary extensions to run a Laravel app. The SERVER_NAME environment variable configures Caddy to listen on port 8080. We also expose port 8080 to access the app from the host machine.

To test your configuration, try running the following command in your terminal:

<!-- Syntax highlighted by torchlight.dev -->docker compose up [-d]
Copy after login
Copy after login
Copy after login

You should see a Laravel error page explaining the connection was not established to the database because of a missing driver when you navigate to http://localhost:8080 in your browser. This is expected as we haven't connected our Laravel app to a database yet.

Awesome, so far we've configured our Laravel app to be served by a FrankenPHP server.

Next, let's connect our local app with a PostgreSQL database!

#Running Laravel with the database

To connect your Laravel app to a PostgreSQL database, we'll need to do a couple of things.

First, we need to set the following environment variables in your .env file:

.env:

<!-- Syntax highlighted by torchlight.dev -->...
DB_CONNECTION=pgsql
...
Copy after login
Copy after login
Copy after login

Following that, you'll need to add new services to your compose.yml file, and create a custom Dockerfile for your dev environment. Create and update the files with the following content:

Dockerfile.dev:

<!-- Syntax highlighted by torchlight.dev -->services:
  php:
    image: dunglas/frankenphp:php8.3-bookworm
    environment:
      SERVER_NAME: ":8080"
    ports:
      - 8080:8080
    volumes:
      - .:/app
Copy after login
Copy after login
Copy after login

Dockerfile.dev is only meant to be used by your local/development environment, and it extends the dunglas/frankenphp:php8.3-bookworm image to include the pdo_pgsql extension, which is required to connect to a PostgreSQL database.

compose.yml:

<!-- Syntax highlighted by torchlight.dev -->docker compose up [-d]
Copy after login
Copy after login
Copy after login

There is a lot going on here, let's take a look at what has changed and why:

  1. We've updated the php service to use a custom Dockerfile called Dockerfile.dev to build a new image that includes the necessary extensions to connect to a PostgreSQL database.
  2. We've added a new service called db that uses the postgres:16.4-alpine image to run a PostgreSQL database. We've also defined some environment variables to set up the database user, password, and database name.
  3. We've created a new volume called db_data to persist the data in the database on your machine, and Docker could reuse it when you restart the services.
  4. A new service called init was also added that reuses Dockerfile.dev. This image is used to run the php artisan migrate command to run your database migrations. The depends_on key ensures that the db service is up and running before the migrations are run.
  5. The php service now depends on the init service to ensure that the database migrations are run before the Laravel app starts.
  6. We've added a health check to the db service to ensure that the PostgreSQL database is up and running before the init service runs the migrations.

To test your configuration, run the following command in your terminal:

<!-- Syntax highlighted by torchlight.dev -->...
DB_CONNECTION=pgsql
DB_HOST=db
DB_PORT=5432 # default PostgreSQL port
DB_DATABASE=main
DB_USERNAME=admin
DB_PASSWORD=password
Copy after login

Your application should now be connecting to your PostgreSQL database, and your database migrations are always run. ?

Your local envnironment is now ready to mimic your production environment. You can now develop your app locally and test a really similar setup you'll use in production.

#Preparing for production

It's time to make the necessary changes for your production environment.

The first step is to tell Docker which directories it can safely ignore when building the production image. Create a new file called .dockerignore in the root of your Laravel project and add the following content:

.dockerignore:

<!-- Syntax highlighted by torchlight.dev -->FROM dunglas/frankenphp:php8.3-bookworm

RUN install-php-extensions pdo_pgsql
Copy after login

This file tells Docker to ignore the vendor, bootstrap/cache, and tests directories.

Then, create a Dockerfile that will be used to build your production image:

Dockerfile:

<!-- Syntax highlighted by torchlight.dev -->...
DB_CONNECTION=pgsql
...
Copy after login
Copy after login
Copy after login

This Dockerfile is similar to the Dockerfile.dev we created earlier, but it includes a few additional steps:

  1. As the FrankenPHP image uses Caddy as the default web server, we've set the SERVER_NAME environment variable to :8080 to instruct Caddy to listen on port 8080.
  2. We install the @composer PHP extension to install Composer in the image.
  3. composer install command is run to install the dependencies of your Laravel app.
  4. We've set the working directory to /app and copied the contents of your Laravel app to the image.

To test your changes in your local environment, you'll need to produce a production build of your app. Run the following command in your terminal:

<!-- Syntax highlighted by torchlight.dev -->services:
  php:
    image: dunglas/frankenphp:php8.3-bookworm
    environment:
      SERVER_NAME: ":8080"
    ports:
      - 8080:8080
    volumes:
      - .:/app
Copy after login
Copy after login
Copy after login

This command builds a new Docker image called my-laravel-app based on the Dockerfile in the current directory.

To test your newly built production image, use the following command:

<!-- Syntax highlighted by torchlight.dev -->docker compose up [-d]
Copy after login
Copy after login
Copy after login

Replace <your-app-key> with the value of the APP_KEY environment variable in your .env file or grab a key from here.

Visit localhost:8080 in your browser, and your app should start in production mode. It may error due to the lack of a database connection, but that's expected.

#Deploying to the cloud

Now that you have a production-ready Docker image, you can deploy it to a cloud provider. ?

In this tutorial, we'll use Sevalla, a new cloud provider that offers a simple way to deploy Dockerfile-based deployments.

As your app depends on a PostgreSQL database, you're better off provisioning a new PostgreSQL database on Sevalla first. Once you're logged in the Sevalla dashboard,

  1. Navigate to the Create database modal
  2. Select PostgreSQL database
  3. Confirm the settings and create the database

Once your database is ready, you can create your Laravel app on Sevalla.

  1. Navigate to the Create app modal
  2. Select your app's repository from your preferred Git provider
  3. Make sure to select the same data-center your database is in
  4. Set the APP_KEY environment variable required by Laravel
  5. Select Dockerfile as build type
  6. Confirm the rest of the settings and hit "Deploy later" button

If your app is ready, you can now connect it with your PostgreSQL database.

  1. Navigate to the app's page
  2. Go to the "Network" tab
  3. Click on the "Add connection" button and select your PostgreSQL database
  4. Confirm the settings and hit "Connect"

Then, set the following environment variables in the "Environment variables" tab with your database's connection details:

  • DB_CONNECTION
  • DB_HOST
  • DB_PORT
  • DB_DATABASE
  • DB_USERNAME
  • DB_PASSWORD

We recommned using the internal network address of your database as the DB_HOST value. This way, your app can connect to the database over a private network.

The last step is to set up a Job process for your application to run the database mirgations before starting the app.

  1. Navigate to the "Processes" tab
  2. Click on the "Create process" button and select "Job"
  3. Set the command to php artisan migrate --force
  4. Set the start policy to "Before deployment"
  5. Confirm the settings and hit "Create"

If this is also done, you can now initiate a manual deployment of your app in the Deployments tab. ?

If all went well, congrats! You've successfully prepared your Laravel app for the cloud. ?

#Conclusion

In this article, we've explored:

  • How to setup your local environment to mimic your production environment using Docker and docker compose.
  • How to prepare your Laravel app for deployment in a cloud environment using Docker, FrankenPHP, and Caddy.
  • We've also covered how to deploy your app to a cloud provider like Sevalla.

By following these steps, you can take your Laravel app to new heights and enjoy the benefits of cloud-based deployments. ?

#UPDATE: September 8, 2024

We received valuable feedback from the community through a discussion on X.

The first point highlighted that including the php artisan serve command in the compose.yml file was unnecessary, as it bypassed the FrankenPHP server. We've corrected this by updating the relevant sections of the compose.yml file.

The second point, shared by Kévin Dunglas (creator of FrankenPHP), recommended using a Debian-based image (bookworm) instead of Alpine (alpine), as Debian offers better compatibility with PHP and better performance with FrankenPHP. As a result, we updated both the Dockerfile.dev and Dockerfile files.

We're grateful for the community's support and feedback. ? ❤️

The above is the detailed content of Prepare your Laravel app for the cloud. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

How does session hijacking work and how can you mitigate it in PHP? How does session hijacking work and how can you mitigate it in PHP? Apr 06, 2025 am 12:02 AM

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

Describe the SOLID principles and how they apply to PHP development. Describe the SOLID principles and how they apply to PHP development. Apr 03, 2025 am 12:04 AM

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to debug CLI mode in PHPStorm? How to debug CLI mode in PHPStorm? Apr 01, 2025 pm 02:57 PM

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

Framework Security Features: Protecting against vulnerabilities. Framework Security Features: Protecting against vulnerabilities. Mar 28, 2025 pm 05:11 PM

Article discusses essential security features in frameworks to protect against vulnerabilities, including input validation, authentication, and regular updates.

How to automatically set permissions of unixsocket after system restart? How to automatically set permissions of unixsocket after system restart? Mar 31, 2025 pm 11:54 PM

How to automatically set the permissions of unixsocket after the system restarts. Every time the system restarts, we need to execute the following command to modify the permissions of unixsocket: sudo...

What are Enumerations (Enums) in PHP 8.1? What are Enumerations (Enums) in PHP 8.1? Apr 03, 2025 am 12:05 AM

The enumeration function in PHP8.1 enhances the clarity and type safety of the code by defining named constants. 1) Enumerations can be integers, strings or objects, improving code readability and type safety. 2) Enumeration is based on class and supports object-oriented features such as traversal and reflection. 3) Enumeration can be used for comparison and assignment to ensure type safety. 4) Enumeration supports adding methods to implement complex logic. 5) Strict type checking and error handling can avoid common errors. 6) Enumeration reduces magic value and improves maintainability, but pay attention to performance optimization.

See all articles