How to Deploy a Laravel App on a VPS Without Docker
Many teams do not need Docker just to ship a Laravel app.
What they need is a repeatable path for:
- creating the site
- pulling code from Git
- configuring PHP and the database
- pointing DNS
- issuing SSL
- checking that queues, storage, and cache behave correctly
LarVPS is built for exactly that kind of workflow.
This guide shows how to deploy a Laravel application on a VPS without Docker, using a site-first flow that keeps the app understandable for small teams, solo founders, and agencies.
When a non-Docker Laravel deployment is the right call
Docker is useful, but it is not the default answer for every app.
A direct VPS deployment is often the better choice when:
- you want lower operational overhead
- your app is a standard Laravel stack
- you are deploying one app or a small number of apps per server
- you want simpler troubleshooting with native Nginx, PHP-FPM, and MariaDB/PostgreSQL
- your team wants the dashboard to explain the next step instead of maintaining custom container scripts
For a lot of production Laravel work, that is enough.
What you need before creating the site
Before you touch the app itself, make sure the server is already connected and healthy in cloud.larvps.com.
You should also have:
- a connected Ubuntu 22.04 or 24.04 server
- a domain or subdomain you plan to use
- your Laravel code in a Git repository
- a clear choice for database engine:
- MariaDB
- PostgreSQL
- SQLite for small/simple use cases
If the server is not connected yet, start here first:
How to Connect an Ubuntu 22.04 or 24.04 VPS to LarVPS
Step 1: Create the site in LarVPS
Go to the Sites page and choose Add Site.
For a normal Laravel deployment, your Simple Setup should usually stay small:
- Server
- Domain
- Runtime
- DNS mode
Choose:
- Runtime:
Laravel
That choice matters because LarVPS uses runtime-aware defaults instead of forcing every app through the same generic PHP flow.
Step 2: Decide how DNS will be handled
LarVPS supports two common paths:
Auto via CloudflareManual DNS
If your team has already connected Cloudflare at the team level, Auto via Cloudflare is usually the cleanest option.
If not, Manual DNS is still fine. The important thing is that the domain needs to point to the VPS before SSL can be issued successfully.
If you are unsure which path to choose, read this next:
Cloudflare DNS Setup for VPS Sites: Auto vs Manual
Step 3: Add your Git source
For a Laravel app, Git is usually the best source of truth.
LarVPS supports:
- public repositories
- private repositories
- Git credentials for private access
- monorepo subdirectory deployment
That means you can deploy cases like:
- Laravel app at repository root
- Laravel backend inside
apps/api - mixed monorepo where frontend and backend live separately
If your Laravel app is not at the repository root, set the Git App Directory correctly. That prevents the agent from building the wrong folder and makes deploy logs much easier to read.
Step 4: Set the right PHP options
For a standard Laravel app, the default runtime is usually enough to get moving, but you still want to review:
- PHP Version
- Database choice
- Runtime preset
The goal is not to expose fifty knobs on day one. The goal is to keep the app on a safe, understandable baseline and only tune when traffic or behavior justifies it.
If your app is a normal Laravel codebase, avoid over-customizing before the first successful deploy.
Step 5: Choose the database engine on purpose
Laravel gives you flexibility here, but your operational experience will differ depending on the engine.
MariaDB
Best for:
- most small-to-medium Laravel apps
- broad ecosystem compatibility
- teams that want familiar tooling
PostgreSQL
Best for:
- apps that already rely on PostgreSQL features
- teams with existing Postgres habits
- projects that value strictness and advanced query features
SQLite
Best for:
- prototypes
- internal tools
- low-complexity apps with modest write volume
The important part is to choose intentionally instead of leaving the database story vague. LarVPS now stores the real DB type for the site so the UI and follow-up actions can stay accurate.
Step 6: Create the site and watch the right status
After you submit the site, LarVPS queues the provisioning flow through the normal path:
- frontend
- cloud task
- daemon
- agent
That is the correct architecture. It means the dashboard can explain what is happening instead of hiding a pile of one-off shell logic.
During provisioning, focus on the real deployment signals:
- code pulled successfully
- runtime prepared
- database configured
- site inventory visible
- DNS/SSL state explained clearly
Do not panic if SSL is not live immediately. The correct interpretation is often:
“The site is ready. SSL is waiting for DNS.”
That is a DNS timing problem, not a failed Laravel deployment.
Step 7: Verify the Laravel basics after first deploy
After the site is up, check the Laravel-specific essentials.
Storage
Make sure your app can write to the expected storage paths.
Laravel sites often look “mostly fine” while still failing on:
- uploads
- cached files
- generated assets
- logs
LarVPS includes file ownership and safe permission actions in Site Settings because this is one of the most common real-world issues after initial deploy.
Queue
If your app uses jobs, make sure queue behavior matches the app’s needs.
Typical Laravel production problems are not the homepage failing. They are:
- mail jobs not processing
- notifications stuck
- background work timing out
Cache
Confirm whether your app expects:
- file cache
- Redis-backed cache
- config caching
- route caching
Do not aggressively cache until the first successful baseline is stable and understood.
Step 8: Point DNS and issue SSL
Once the site is reachable over HTTP and the domain is pointed correctly, issue SSL.
The right order is:
- site created
- DNS points to the correct IP
- SSL is issued
Trying to reverse that order is the classic cause of “SSL failed” confusion in VPS products.
LarVPS now tries to make this visible in the UI so the operator understands whether the blocker is:
- site provisioning
- DNS propagation
- or a real SSL error
Step 9: Set backups before launch
Do not treat backups as a “later” task.
For a Laravel site, your minimum launch posture should cover:
- source snapshot or Git recovery plan
- database backup
- off-server storage destination
Local-only backups are better than nothing, but cloud-backed backups are safer for real production use.
A few Laravel deployment mistakes to avoid
1. Treating every PHP app as the same thing
Laravel, WordPress, and generic PHP apps overlap, but they are not interchangeable.
Using the Laravel runtime is better than trying to bend the app into a generic PHP App flow unless the codebase is actually non-standard.
2. Overcomplicating the first deploy
Do not start with:
- exotic queue topology
- custom permission hacks
- aggressive tuning
- premature worker sprawl
Get one clean deploy first.
3. Confusing site readiness with SSL readiness
A site can be provisioned correctly while SSL still waits for DNS.
Those are separate stages.
4. Forgetting monorepo path selection
If the app lives in a subdirectory and the Git App Directory is wrong, the rest of the deploy can look strangely broken even though the server itself is fine.
Why this flow scales better for small teams
The real win is not just “Laravel deployed.”
The win is that the next operator can understand:
- which server owns the app
- how the domain is connected
- what database engine it uses
- where backups go
- what the latest task did
That is exactly why a site-first dashboard beats a pile of improvised SSH steps once the project becomes real.
Final checklist
Before you call the deployment done, confirm:
- server heartbeat is healthy
- Laravel site runtime is correct
- Git source is pointed to the right directory
- database engine is intentional
- DNS points to the server
- SSL is live or clearly waiting for DNS
- backup path is configured
If all seven are true, you have a much better production baseline than most “just get it on the server” Laravel setups.