Deploying your Laravel application with Docker on a VPS might seem daunting at first – especially when you’re juggling server configurations, dependency management, and ensuring your app runs seamlessly in production. Even after building a well-optimized web application, replicating your local environment on a server can be a whole new challenge.

In this comprehensive guide, we’ll show you how to deploy Laravel with Docker on a VPS using Laravel Sail.

Sail simplifies the process by handling the Docker setup for you, making it a great option whether you’re new to Docker or looking for a streamlined approach.

You’ll learn how to download Laravel, spin up essential services such as the web server, PHP, and database, and run the necessary setup commands to get your application live.

Let’s dive in!

Why Use Docker for Laravel Deployment?

Deploying a Laravel application from your local development setup to a live production server is not easy. If you have deployed applications in the past, you’ll probably agree that the deployment process introduces numerous complexities, and it’s challenging to manage environment consistency.

Traditionally, server setup involved manually installing and configuring PHP, web servers such as Nginx or Apache, databases, caching services such as Redis or Memcached, and countless system libraries – all directly onto the server’s operating system.

This process is not only time-consuming but also prone to errors and inconsistencies. Subtle differences between development, staging, and production environments cause unexpected bugs and failures during application deployment.

Docker fundamentally solves this by enabling you to package your entire application into standardized, isolated units called Docker containers, including its specific dependencies and configurations.

Advantages of Dockerizing Laravel Applications

The primary advantage of containerizing your Laravel applications with Docker is that it allows you to have a consistent development and deployment experience for all developers. By packaging your application code along with the exact versions of PHP, extensions, web server (Nginx/Apache), system libraries, and other dependencies within a Docker image, you eliminate variations between developer machines, testing environments, and production servers.

This portability means a container built on one machine will run identically on any other machine with Docker installed, drastically reducing bugs related to environment differences.

In addition, Dockerization brings significant benefits in terms of isolation, scalability, and resource efficiency for Laravel projects. Each Docker container runs in its own isolated userspace, preventing conflicts between different applications or microservices running on the same host. It also enhances security by limiting the potential blast radius of vulnerabilities.

This isolation makes it easier to scale specific components of your application (e.g., PHP-FPM workers, queue workers) independently based on demand, often orchestrated via Docker Compose or more advanced container management tools such as Kubernetes.

Compared to traditional virtual machines, containers have significantly lower overhead as they share the host OS kernel. This leads to faster startup times, better resource utilization, and the ability to run more application instances on the same hardware, ultimately improving overall reliability and cost-effectiveness.

📖 Suggested read: What is Docker And How Does it Work

Step-by-Step Instructions For Deploying Your First Laravel App with Docker (Sail)

This section explains how to deploy your Laravel application on a generic cloud VPS using Docker.

If you are using RunCloud to manage your servers, then you can refer to our Laravel documentation to learn how to do this effectively.

Prerequisites

Before we begin installing Laravel, ensure your server environment is correctly prepared.

  1. Server Access: You’ll need access to a Linux server (such as a VPS from providers such as DigitalOcean, Linode, Vultr, etc.) via SSH.
  1. Sudo Privileges: You must be logged in as a user with sudo privileges or as the root user directly (though using a sudo user is generally recommended for security). Remember, commands run with sudo have elevated permissions, so execute them carefully.
  2. Docker Installation and Service: Docker must be installed and running on your server. You can check if it is installed by running docker –version. If it’s not found, you’ll need to install it following the official Docker documentation for your Linux distribution.

Note: Many cloud providers offer server images with Docker pre-installed. Using one of these can save you the installation step.

📖 Suggested read: What Are Docker Images And How To Use Them

Step 1: Download Your Laravel Application

We will use the official Laravel.build service to download a starter Laravel project configured for Sail. The command below downloads a script and executes it using bash.

Run this command, making sure you replace runcloud-laravel-app with the desired name for your application’s directory. This name will be used for the project folder.

curl -s https://laravel.build/runcloud-tutorial | sudo bash

Important Security Precaution: Piping (|) commands directly from curl to sudo bash executes the downloaded script with root privileges. While laravel.build is an official and trusted source, be cautious when running scripts from the internet this way. Read our blog post on Pipes vs Xargs to learn more on this topic.

📖 Suggested read: How To Create a Docker Image For Your Application

In the above command:

  • curl -s: Downloads the script silently (no progress meter).
  • https://laravel.build/runcloud-tutorial: This tells the service to generate a setup script for an app named runcloud-tutorial.
  • | sudo bash: Pipes the downloaded script directly to the bash interpreter, executed with sudo (root) privileges. This creates the project directory and sets initial permissions.

Step 2: Navigate into Your Application Directory

Once the previous command completes, navigate into the newly created project directory. Remember to use the actual application name you chose:

cd runcloud-tutorial

You should now be inside your Laravel project’s root directory.

📖 Suggested read: Understanding Docker Services | RunCloud Docs

Step 3: Start the Docker Containers with Laravel Sail

Laravel Sail is an interface for managing your application’s Docker containers. We’ll use it to build and start the necessary services (web server, PHP, database, etc.).

Execute the following command to start Sail in “detached” mode (-d), meaning the containers will run in the background:

sudo ./vendor/bin/sail up -d

In the above command:

  • sudo: We use sudo here because Sail needs root permissions to manage Docker networking and volumes.
  • ./vendor/bin/sail: Executes the Sail script located in your project’s vendor directory.
  • up: This command tells Docker (via Sail and Docker Compose) to create and start the containers defined in the docker-compose.yml file. The first time you run this, it will download the necessary Docker images (such as PHP, Nginx, MySQL), which can take several minutes (sometimes ten or more), depending on your internet connection.
  • -d: Runs the containers in the background so your terminal prompt remains available.

📖 Suggested read: Docker Security: Best Practices to Secure a Docker Container

Step 5: Run Database Migrations

Once the containers (including the database container) are running, you’ll need to set up your application’s database schema. Laravel uses “migrations” for this.

Run the following command to execute the default Laravel migrations:

sudo ./vendor/bin/sail artisan migrate

In the above command:

  • sudo ./vendor/bin/sail: Again, we use Sail to execute a command.
  • artisan migrate: This tells Sail to run the PHP artisan migrate command inside the main application container (the one running PHP). This command creates the necessary tables in the database (like the users table, etc.).

You should see an output indicating that the migrations ran successfully.

Step 6: Access Your Application

Your Laravel application should now be running and accessible!

  • On a Server: Open your web browser and navigate to your server’s public IP address: http://your_server_ip. Sail, by default, configures the web server container to listen on port 80.
  • On Your Local Machine (if developing locally): If you performed these steps on your local computer instead of a server, you can usually access it via http://localhost.

If you cannot access the site via the server’s IP address, your server’s firewall might be blocking incoming connections on port 80 (HTTP). You will need to configure your firewall (e.g., ufw, firewalld, or your cloud provider’s firewall settings) to allow traffic on TCP port 80.

📖 Suggested read: How to Use Cloudflare Firewall Rules to Protect Your Web Application 

Step 7: Troubleshooting Potential Permission Errors (If Needed)

Sometimes you might encounter file permission errors within your Laravel application, due to how Docker handles file volumes and user mapping between the host server and the container. This often happens because the web server process inside the container (running as the sail user) doesn’t have write permission to files owned by the root user on the host (created during the initial curl | sudo bash step).

If you suspect permission issues, you can fix them by changing the ownership of the project files inside the container to the sail user.

Enter the main application container as root:

sudo ./vendor/bin/sail root-shell

This gives you a root command prompt inside your Laravel application’s container.

Change ownership recursively: This command changes the owner and group of the html directory (as well as everything inside it) to sail:

chown -R sail:sail /var/www/html

Let’s understand each part of the above command.

  • chown: Change owner command.
  • -R: Recursive (apply to the directory and all files/directories within it).
  • sail:sail: Set the user to sail and the group to sail.
  • html: The target directory (which corresponds to your project root, mounted at /var/www/html).

Close the container shell:

exit

After running these commands, try accessing your application again, and refresh the web page.

Wrapping Up: Deploying Laravel with Docker on a VPS

While Sail simplifies the Docker aspect for a single Laravel project, managing the underlying server, handling security configurations, setting up monitoring, deploying multiple applications, and keeping everything updated still requires significant effort and Linux expertise. This is where platforms specifically designed for server management truly shine.

RunCloud makes it incredibly easy to develop, deploy, and maintain your web applications across one or many servers, all from a single, intuitive central dashboard.

It abstracts away the complexities of server administration, letting you focus on building great applications.

RunCloud works with standard Laravel applications, high-performance setups such as Laravel Octane, and popular CMS platforms such as WordPress. You can start using RunCloud and choose from various optimized server stacks directly through the RunCloud interface.

Ready to experience truly effortless server management and application deployment?

Sign up for RunCloud today and see the difference for yourself!

FAQs on Deploying Laravel with Docker on a VPS

What are the benefits of using Docker for Laravel deployment?

Docker packages your Laravel app and its dependencies into containers, ensuring consistent environments from development to production. This isolation prevents conflicts between application dependencies and simplifies portability across different servers or cloud providers.

How do I secure my Dockerized Laravel application?

You can secure your Dockerized Laravel app by following standard web security practices within your code, using minimal, trusted base images, and running containers as non-root users. RunCloud provides several security features out of the box and simplifies configuration management.

Can I use Docker Compose with Laravel?

Absolutely, Docker Compose is highly recommended, especially for local development and simpler multi-container production setups with Laravel. It allows you to define and manage all the related services your application needs (such as the web server, PHP-FPM, database, and cache) in a single YAML file. This makes it easy to spin up, connect, and manage the entire application stack with simple commands.

What is the best way to manage environment variables in Docker?

For security reasons, avoid hardcoding environment variables or committing .env files directly into your Docker image. Instead, pass environment variables into the container at runtime using Docker’s -e flag, Docker Compose environment, or env_file directives.

Is Docker necessary for deploying Laravel?

No, Docker isn’t strictly necessary; you can successfully deploy Laravel using a traditional approach by setting up a LAMP or LEMP stack directly on your VPS. However, Docker provides significant advantages in environment consistency, dependency management, and deployment predictability. Tools such as RunCloud make both traditional and Docker-based deployments significantly easier to manage.

What are the alternatives to Docker for deploying Laravel?

You can deploy your web applications using the traditional deployment directly onto a configured VPS. RunCloud makes this process extremely easy by providing a centralized dashboard for VPS management.

Can I use Kubernetes to manage Laravel deployments?

Yes, Kubernetes (K8s) is a powerful container orchestration system suitable for managing complex, large-scale Laravel applications requiring high availability, auto-scaling, and rolling updates. However, it introduces significant operational complexity compared to simpler Docker or Docker Compose setups. Managing deployments via a tool such as RunCloud provides sufficient capability for many projects without the K8s learning curve.

What is the difference between Docker and traditional VPS deployment?

Traditional VPS deployment required you to install and manage all software (OS, web server, PHP, database, dependencies) directly on the virtual server, sharing the host OS kernel and resources in a less isolated way. Docker uses containerization to package the application and its dependencies into isolated user-space environments that run consistently anywhere, sharing the host OS kernel but keeping libraries and binaries separate.