Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
World desk9 min

Laravel Folder Structure and Permissions for Deployment on a VPS

A secure Laravel VPS deployment keeps the project root private, points Nginx at public/, and limits PHP-FPM write access to storage/ and bootstrap/cache/. This guide covers ownership, groups, ACLs, Nginx, storage links, release strategies, and troubleshooting without chmod 777.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a secure Laravel deployment on a VPS, point Nginx at the application’s public/ directory—not the project root—and allow the PHP-FPM account to write only to storage/ and bootstrap/cache/. Keep .env, application code, Composer dependencies, and framework directories outside the web root. This arrangement prevents source disclosure while giving Laravel the access it needs for logs, sessions, caches, compiled views, uploads, and generated framework files.

The production layout Laravel expects

A Laravel project contains far more than files intended for direct browser access. The public/ directory is the web boundary; requests enter through its front controller, index.php. Nginx should never serve the directory that contains .env, source code, route definitions, or Composer metadata.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Laravel’s current 13.x deployment guidance states: “Laravel will need to write to the bootstrap/cache and storage directories, so you should ensure the web server process owner has permission to write to these directories.” That is the essential permission rule. The account name and exact mode bits depend on your Linux distribution and PHP-FPM pool.

What each top-level directory does

Directory Purpose Web-server treatment
app/ Application code and most classes. Readable by the runtime, never the document root.
bootstrap/ Framework bootstrap code and generated files. Keep outside the web root; only bootstrap/cache/ needs runtime write access.
bootstrap/cache/ Generated route, service, event, and configuration cache files. Writable by the PHP-FPM account.
config/ Configuration files loaded by the application. Readable, not publicly served. After configuration caching, env() calls outside configuration files return null.
database/ Migrations, factories, and seeders. Readable for deployment commands, not exposed through Nginx.
public/ Front controller and browser-facing assets. The only directory Nginx should expose.
resources/ Blade views and raw, uncompiled assets. Keep outside the document root.
routes/ Web, API, console, and other route definitions. Readable by PHP, never directly downloadable.
storage/ Logs, compiled Blade templates, file sessions, file caches, and generated files. It is divided into app, framework, and logs. Writable by PHP-FPM; do not publish the directory itself.
storage/app/public/ User-generated files that are meant to be public. Reachable through the controlled public/storage link, not by exposing storage/.
vendor/ Composer-installed dependencies. Readable by PHP, outside the web root.

Point Nginx at public/, not the project root

Assume the release is stored at /var/www/example/current. The Nginx root must end in /public. A typical server block is:

#1 Best Overall
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
  • [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
  • [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
  • [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
  • [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.
server {
    listen 80;
    server_name example.com;

    root /var/www/example/current/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /.(?!well-known).* {
        deny all;
    }
}

Use the PHP version and socket that are actually installed on the VPS; php8.3-fpm.sock is an example, not a universal value. On some distributions the include file already sets SCRIPT_FILENAME, so retain only one correct definition. Test the configuration with your service manager’s Nginx test command before reloading it.

Serving /var/www/example/current as the root is dangerous. A misconfiguration, static-file rule, or backup file could expose .env, source code, database credentials, or Composer metadata. A dotfile deny rule is useful defense in depth, but it does not make serving the project root safe.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Find the account that must write files

Do not assume the account is always www-data. Debian and Ubuntu commonly use that name; other distributions use nginx, and a PHP-FPM pool may run under a dedicated user. Inspect the active Nginx and PHP-FPM service and pool configuration, then verify the identity with a process listing or the pool’s user and group settings.

Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
  • 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
  • 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
  • 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
  • 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.

The account that executes PHP must be able to traverse every parent directory and write the two Laravel paths. Read permission on the rest of the release is normally sufficient. The deployment user still needs enough access to install releases and run Artisan commands, but that does not require making the entire tree writable by the web process.

A controlled POSIX-group setup

One workable pattern is a deployment user named deploy and a runtime group named www-data. Replace those names with the identities on your VPS:

sudo chown -R deploy:www-data /var/www/example/current
sudo find /var/www/example/current -type d -exec chmod 750 {} ;
sudo find /var/www/example/current -type f -exec chmod 640 {} ;
sudo chgrp -R www-data /var/www/example/current/storage /var/www/example/current/bootstrap/cache
sudo chmod -R ug+rwX /var/www/example/current/storage /var/www/example/current/bootstrap/cache

The first two commands establish conservative ownership and read/execute access. The last two give the runtime group write access only where Laravel documents that it is required. Check that the deployment user can still update a release and that PHP-FPM can create a test file in both writable directories. If your deployment process replaces directories, apply the ownership and mode policy to every new release rather than relying on an old inode’s permissions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord
  • [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
  • [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
  • [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
  • [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
  • [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by

Do not use chmod -R 777 as a blanket fix. It grants write access to every local user and process, hides the underlying ownership problem, and is broader than Laravel’s requirement. If a command needs elevated privileges during deployment, fix the ownership or group membership instead of permanently opening the tree.

When ACLs are a better fit

POSIX groups are portable and simple when one deployment group and one runtime group are enough. On a server with several deployment tools or multiple PHP pools, filesystem ACLs can grant a specific account access without changing the primary group:

sudo setfacl -R -m u:www-data:rwx /var/www/example/current/storage /var/www/example/current/bootstrap/cache
sudo setfacl -R -d -m u:www-data:rwx /var/www/example/current/storage /var/www/example/current/bootstrap/cache

Use the real PHP-FPM user, and verify that setfacl is installed and supported by the filesystem. Default ACLs matter for files and directories created later; without them, a newly generated cache or log file may revert to unusable permissions.

Rank #4
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
  • Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
  • All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
  • Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
  • Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.

Deploy in an order that avoids permission and cache errors

  1. Prepare the release. Upload the application to a release directory outside the document root. Install production dependencies with composer install --no-dev --optimize-autoloader as the deployment user.
  2. Install the environment file. Place the production .env where Laravel expects it, restrict its ownership and mode, and verify database, cache, queue, mail, filesystem, and application-key settings before caching configuration.
  3. Check writable paths. Ensure the PHP-FPM identity can traverse the path and write to storage/ and bootstrap/cache/. A failed log write can mask the original application error.
  4. Run database changes deliberately. Execute migrations with the deployment account and the intended production flags, for example php artisan migrate --force when unattended execution is appropriate.
  5. Build framework caches. Run php artisan optimize, or run the individual config:cache, event:cache, route:cache, and view:cache commands. Do this only after .env and configuration are correct. Once configuration is cached, changing an environment variable requires rebuilding that cache.
  6. Create the public upload link when needed. Run php artisan storage:link. This creates public/storage pointing to storage/app/public.
  7. Switch the web root. Point Nginx at the new release’s public/ directory, or update a current symlink used by the server block.
  8. Validate and reload services. Test Nginx syntax, check the PHP-FPM socket path, reload Nginx and PHP-FPM through the host’s service manager, then request both a static asset and a dynamic Laravel route.

In a release-based deployment, keep shared writable directories outside individual immutable releases and link them into each release. That prevents logs, sessions, uploads, and caches from disappearing during a rollback. Ensure the symlink targets have the same runtime ownership policy.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Make uploaded files public without exposing all of storage

Laravel’s public disk is designed for files stored under storage/app/public that should be downloadable by URL. The command php artisan storage:link creates public/storage as a link to that directory. Nginx then serves only the linked public area, while private files and logs remain under storage/.

If the command fails, check that the deployment user can create links inside public/, that the target directory exists, and that the web server is reading the same release whose link you created. On a multi-server deployment, local disk is not automatically shared; use durable object storage when every server must read the same uploads.

Choose a deployment model deliberately

Decision Advantages Costs and cautions
Self-managed VPS Full control over Nginx, PHP-FPM pools, filesystem layout, services, and security policy. You maintain updates, users, firewall rules, backups, monitoring, and rollback procedures.
Laravel Forge A managed VPS control layer that can install and manage Nginx, MySQL, Redis, Memcached, Beanstalk, and related services. You still need to understand document-root and writable-directory rules, and you trade some low-level control for managed setup.
Single release directory Simple paths and fewer moving parts. Deploying in place can leave mixed-version files and makes rollback less predictable.
Release-based directories Atomic symlink switches and safer rollback. Requires shared storage for uploads, logs, and other mutable data, plus consistent permissions on every release.
POSIX groups Portable, easy to audit, and adequate for one deployment user and one runtime group. Less precise when several pools or service accounts need different access.
ACLs Fine-grained permissions for multiple accounts without changing primary group ownership. Less familiar, filesystem-dependent, and easy to overlook when setting defaults for newly created files.
Local disk uploads Simple Laravel configuration and low latency on one server. Not durable by itself and difficult to share across multiple application servers.
Object storage Better durability and multi-server access for user files. Adds credentials, network dependency, billing, and a different operational failure mode.

Troubleshoot “permission denied” without opening the whole server

Laravel cannot write a log

Confirm the PHP-FPM user, then inspect every parent directory from the filesystem root to storage/logs. The runtime needs execute permission on directories to traverse them, not merely write permission on the final directory. Check ownership, group membership, ACLs, disk space, and whether a read-only mount is involved.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Compiled views or cache files fail

Check both storage/framework and bootstrap/cache. Clear stale files as the deployment user, restore the intended group and mode, and rerun the relevant Artisan cache command. Avoid running Artisan as root during routine deployment; doing so commonly leaves root-owned files that PHP-FPM cannot replace.

The site returns a 404 or downloads PHP

Verify that Nginx’s root ends in /public, that the try_files rule sends unmatched requests to index.php, and that the PHP-FPM socket matches the installed PHP version. Confirm that public/index.php exists in the active release and reload Nginx after correcting the configuration.

Uploads return 404 after deployment

Check whether public/storage exists and points to the active release’s storage/app/public. Recreate the link with php artisan storage:link if it was omitted. For release-based deployments, make the link target a shared upload directory or use object storage; otherwise a release switch can make existing URLs disappear.

Environment changes appear ignored

If configuration was cached, Laravel will not read changed environment values dynamically from ordinary application code. Update .env, rebuild the configuration cache, and reload PHP-FPM if the process manager is retaining old workers or environment state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Final VPS deployment checklist

  • Nginx root is the application’s public/ directory.
  • Requests are routed through public/index.php with try_files.
  • The PHP-FPM socket and SCRIPT_FILENAME refer to the installed PHP version and active release.
  • .env, app/, config/, routes/, storage/, and vendor/ are outside the document root.
  • The PHP-FPM account can write to storage/ and bootstrap/cache/, but the whole project is not world-writable.
  • Dotfiles are denied at the web server, and backups are stored outside public/.
  • storage:link has been run when public uploads are part of the application.
  • Production dependencies and Laravel caches were built with the correct environment settings.
  • Logs, sessions, caches, and uploads have a persistence plan if releases are replaced or more than one server is used.
  • Nginx and PHP-FPM were syntax-checked, reloaded, and tested through both static and dynamic requests.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.