Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix 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
VGSources
Blog

How to Configure Laravel with Apache on an Ubuntu Linux VPS

A production-focused guide to deploying Laravel with Apache on an Ubuntu VPS, including PHP requirements, virtual hosts, permissions, caching, HTTPS, and route troubleshooting.
Length12 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Point Apache at Laravel’s public/ directory, enable URL rewriting, grant the PHP process write access to storage/ and bootstrap/cache/, then verify DNS and HTTPS in that order. Never use the Laravel project root as Apache’s document root: it contains .env, Composer files, and application code that should not be downloadable.

The procedure below targets a self-managed Ubuntu VPS running Apache. Laravel 13 requires PHP 8.3 or newer and the extensions listed in the compatibility table; an existing application’s composer.json and composer.lock remain the final authority if it uses an older Laravel major.

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.

What the finished setup should look like

A browser request should pass through these layers:

  1. DNS resolves the requested hostname to the VPS.
  2. Apache selects the virtual host whose ServerName or ServerAlias matches that hostname.
  3. The virtual host maps the site to /var/www/example.com/public, not /var/www/example.com.
  4. Apache serves existing assets such as CSS, JavaScript, and images directly.
  5. Laravel’s shipped public/.htaccess sends other paths to public/index.php.
  6. PHP loads the framework, reads the environment and configuration, and returns the response.

The project root remains outside the web-exposed directory. Files such as .env, composer.json, composer.lock, source code, and cached secrets are therefore not addressable as public URLs.

Check PHP, extensions, and server prerequisites

Laravel 13’s current deployment documentation lists PHP 8.3 or newer and these extensions:

Requirement Why it matters
PHP >= 8.3 Laravel 13’s supported PHP baseline.
Ctype Character-type checks used by framework and application code.
cURL Outbound HTTP and API requests.
DOM XML and HTML document handling.
Fileinfo MIME-type detection for uploaded and generated files.
Filter Input filtering functions.
Hash Password and data hashing.
Mbstring Multibyte string operations.
OpenSSL Encryption and secure transport support.
PCRE Regular-expression processing.
PDO Database abstraction and drivers.
Session PHP session support where the application uses it.
Tokenizer PHP source-token processing.
XML XML parsing and related framework features.

Install the PHP version and database driver required by the project rather than blindly installing a newer runtime. A Laravel application on an older major can have a lower PHP baseline. Check the lock file and package constraints before changing production PHP.

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

Verify the runtime before deployment

php -v
php -m
composer --version
apache2ctl -v

Compare the output of php -m with the project’s requirements. A command-line PHP binary and Apache’s PHP handler can load different configuration files, so also create a temporary, protected diagnostic endpoint or inspect the active handler configuration when a module appears present in the shell but missing from web requests. Remove any diagnostic endpoint immediately after testing.

Prepare the application directory and release user

Use a path such as /var/www/example.com for the complete release. Deploy through a non-root administrative account and reserve root for package installation, service management, and protected configuration changes.

Install the release

Place the repository checkout or release archive in the application directory. Keep .env server-side and do not commit it. If you deploy from a repository, make the release user the owner of the checkout and use a repeatable release process rather than editing files in production.

sudo mkdir -p /var/www/example.com
sudo chown -R deploy:deploy /var/www/example.com
cd /var/www/example.com
composer install --no-dev --prefer-dist --optimize-autoloader

The Composer command installs the versions recorded in composer.lock, omits development packages, and builds an optimized autoloader. Run the project’s documented frontend production build as part of the release if it has JavaScript or CSS assets. Do not assume a Node.js version; read the project’s package files and build documentation.

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

Keep releases separate when you need rollbacks

For a larger application, keep immutable release directories and point a stable path, such as current, at the active release. Ensure the Apache virtual host ultimately resolves to that release’s public/ directory. Shared .env, user uploads, and cache directories must be managed deliberately when switching releases; a symlink alone does not solve ownership or persistence.

Create a safe production environment

Laravel expects .env at the application root. Create it from the project’s example file or from a secret-management process, then set values for the production environment, canonical URL, application key, database, cache, session and queue drivers, mail transport, and application-specific credentials.

cd /var/www/example.com
cp .env.example .env
chmod 640 .env

Set APP_DEBUG=false in production. Debug output can disclose stack traces, paths, SQL details, and configuration data. Generate an application key only for a new installation:

php artisan key:generate

Do not rotate an existing key casually. Previously encrypted values, cookies, and other ciphertext may become unreadable after a key change. Plan a key rotation as a migration with backups and application-specific re-encryption steps.

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

Keep secrets out of the Apache virtual-host file whenever possible. Apache configuration is read by administrators and may be copied into diagnostics or backups. Environment variables supplied by the process manager or a protected deployment mechanism can override values, but document which source is authoritative.

Configure Apache to expose only Laravel’s public directory

Apache’s DocumentRoot is the directory used to map URL paths to files. For Laravel, it must end in /public.

Create the HTTP virtual host

Save the following as /etc/apache2/sites-available/example.com.conf, replacing the hostname and path with your values:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public

    <Directory /var/www/example.com/public>
        AllowOverride All
        Require all granted
        Options FollowSymLinks
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>

ServerName should be the canonical hostname. Include ServerAlias only for names that should serve the same application, such as www. DNS records for every listed name must point to this VPS; an alias in Apache does not create DNS.

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

Enable the site and rewrite support

sudo a2enmod rewrite
sudo a2ensite example.com.conf
sudo a2dissite 000-default.conf
sudo apachectl configtest
sudo systemctl reload apache2

Only disable the default site if it would otherwise answer requests intended for your application. apachectl configtest must report a successful syntax check before you reload. On a new server, inspect the parsed virtual hosts with:

sudo apachectl -S

The public/.htaccess file supplied by Laravel contains the front-controller rewrite rules. AllowOverride All permits those directives. A hardened configuration can replace it with a narrower AllowOverride policy after you have identified the exact override classes needed by the shipped rules, but disabling overrides entirely will commonly produce 404 responses for routes that are not physical files.

Check parent-directory traversal

Apache needs execute permission on every parent directory in the path, not just on public/. A restrictive home-directory mode or a parent owned by another account can cause a 403 even when the virtual host looks correct. Check each component from /var through the release directory and grant only the traversal access required by the web process.

Set ownership and write permissions safely

Laravel must be able to write to storage/ and bootstrap/cache/. The web process account is commonly www-data on Ubuntu, but confirm the account used by the installed Apache/PHP handler before changing ownership.

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

A group-based permission pattern

Keep deployment ownership with the release user, share a group with the web process, and grant group write access only to Laravel’s required directories:

sudo usermod -aG www-data deploy
sudo chgrp -R www-data /var/www/example.com/storage /var/www/example.com/bootstrap/cache
sudo chmod -R ug+rwX,o-rwx /var/www/example.com/storage /var/www/example.com/bootstrap/cache

The deploying user may need to start a new login session before the supplementary group is active. If your release process replaces directories, reapply group ownership and modes as part of deployment or use a filesystem default ACL designed by your administrator.

Do not run chmod -R 777. It makes every local account able to modify application data and often masks the real owner, group, or handler mismatch. Keep source files, Composer metadata, and .env more restrictive than runtime directories.

Publish user-uploaded files

If the application uses Laravel’s public filesystem disk, create the documented link from public/storage to the storage location:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
cd /var/www/example.com
php artisan storage:link

The link exposes only files intended for the public disk. Private uploads should remain outside the public path and be delivered through an authorization-controlled application response or a separate private-storage mechanism.

Run deployment commands in the right order

Once the environment, dependencies, Apache mapping, and permissions are correct, execute the release tasks required by the application.

  1. Run database migrations only when the project’s release policy permits them. Take a backup and understand whether migrations are backward-compatible with the currently running code.
  2. Build frontend assets using the project’s documented production command.
  3. Cache Laravel configuration and framework metadata where appropriate.
  4. Restart long-running workers and reload other processes that retain old code or configuration.
php artisan config:cache
php artisan event:cache
php artisan route:cache
php artisan view:cache

These commands create production caches. Validate that the application boots successfully before enabling them on a new deployment.

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

Understand the env() limitation

After php artisan config:cache, Laravel does not load the .env file directly during ordinary runtime calls. Use env() inside configuration files, then read the resulting configuration with config() from application code. If code calls env() directly in controllers, jobs, or services, it can appear to ignore a changed value after configuration is cached.

When an environment value looks stale, clear and rebuild the cache through the deployment process rather than deleting arbitrary files while requests are running. Coordinate this with queue workers, schedulers, WebSocket processes, or other services that may have loaded the old configuration into memory.

Add HTTPS only after HTTP and DNS work

TLS troubleshooting is meaningful only after the hostname resolves publicly and the HTTP virtual host serves the intended application. Confirm http://example.com first, then obtain a certificate with an ACME client such as Certbot.

Use a dedicated port-80 redirect host

After certificate issuance, a simple redirect virtual host can be used for the canonical name:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

ACME HTTP-01 validation still needs access to /.well-known/acme-challenge/. Configure the chosen ACME client and its validation method so the challenge is reachable; do not add an unconditional rule that blocks it.

Let the certificate tool manage certificate paths

Use the certificate paths and renewal hooks generated for this server. Do not copy hard-coded paths from another machine, because file locations, permissions, and renewal integration vary. After the tool updates Apache:

sudo apachectl configtest
sudo systemctl reload apache2

Test both the bare domain and any www alias, confirm that the certificate names match the requested host, and verify that application-generated links use the intended HTTPS canonical URL.

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

Verify the deployment before calling it finished

  • DNS A and, where applicable, AAAA records point to the VPS.
  • apachectl -S shows the expected enabled virtual host and hostname.
  • The virtual host’s DocumentRoot ends in /public.
  • mod_rewrite is enabled and public/.htaccess is present.
  • The home page returns the application, not Ubuntu’s default page.
  • A non-root Laravel route works after a direct refresh, not only after navigating from the home page.
  • Static assets return the expected content type and status.
  • Apache’s error and access logs show the request reaching the intended vhost.
  • The PHP handler reports the required version and extensions.
  • storage/ and bootstrap/cache/ are writable by the active PHP process.
  • APP_DEBUG=false is active and sensitive files cannot be downloaded.
  • HTTPS presents a valid certificate, redirects HTTP as intended, and leaves the ACME challenge reachable during renewal.

Troubleshoot common failures by symptom

Symptom Likely cause Checks and fix
Apache shows its default page DNS, hostname matching, or site enablement is wrong. Check DNS, ServerName, enabled sites, and sudo apachectl -S. Disable the default site only when it is taking precedence.
Only / works; other Laravel routes return 404 Apache is not using Laravel’s front controller. Confirm DocumentRoot ends in /public, enable rewrite, ensure public/.htaccess exists, and permit overrides in the matching <Directory> block.
403 Forbidden Apache cannot traverse a parent directory or authorization rules deny access. Inspect execute permission on every parent, Require all granted, and the Apache error log. Avoid making the whole tree world-writable.
500 error or “failed to open stream” PHP startup failure, missing extension, or unwritable runtime directory. Read the Apache error log, compare web PHP modules with the project requirements, and test write access to storage and bootstrap/cache.
Environment changes do not appear Configuration cache or a long-running worker still contains old values. Rebuild Laravel’s configuration cache through deployment and restart workers or other persistent processes. Keep runtime env() calls out of application code.
Uploaded images or files return 404 The public storage link is missing or points to an incorrect release. Run php artisan storage:link, inspect the link target, and verify that the public disk and directory permissions are correct.
Certificate issuance fails DNS, port 80, vhost selection, or challenge access is incorrect. Resolve the hostname publicly, confirm port 80 reaches this VPS and the intended vhost, and allow /.well-known/acme-challenge/ through any redirect or access rule.

Production security and operational details

Protect files by architecture, not by hope

Using public/ as the document root is the primary boundary. Do not rely on Apache rules to hide a project root that is already exposed. Keep backups, deployment archives, database dumps, private uploads, and secret files outside the public directory.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

Separate deployment and runtime responsibilities

The deploy user should own releases and run Composer and Artisan commands. The PHP process should have write access only where Laravel needs runtime writes. This separation makes an accidental request-time file modification less damaging and makes permission errors easier to diagnose.

Plan worker restarts

Queue workers, schedulers, WebSocket servers, and application servers can retain old classes or configuration after a release. Use the project’s supervisor and restart procedure after deploying code or changing cached configuration. A successful Apache reload alone does not refresh those processes.

Use logs as the first diagnostic source

Keep separate access and error logs for the virtual host. A 404 in Laravel’s response is different from an Apache 404, and the logs reveal which layer generated it. Avoid placing credentials or full request bodies into verbose production logging.

Choose an operating model deliberately

A self-managed Apache VPS is not the only way to run Laravel. The practical distinction is how much infrastructure work remains yours.

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.
Concern Self-managed Apache VPS Managed Laravel infrastructure
OS and Apache configuration You control packages, virtual hosts, PHP handlers, firewall, and upgrades. The provider supplies supported defaults and limits low-level control.
Scaling You design vertical or horizontal scaling and configure load balancing. Managed services may automate capacity changes, subject to their supported architecture.
Queues and processes You install and supervise workers, schedulers, and reloads. Process management may be integrated, but supported worker types and limits vary.
Backups You choose schedules, retention, off-site copies, and restore tests. Backups may be offered as a service; confirm retention, scope, and restore responsibility.
Observability You configure logs, metrics, alerts, and retention. Dashboards and alerts may be included, with provider-specific visibility.
Cost model You pay for the VPS and operate it directly. You pay for managed convenience and any usage-based infrastructure.

Choose the VPS path when you need OS-level control and can own patching, monitoring, backups, certificate renewal, and incident response. A managed option can reduce routine server work, but it does not remove the need to understand application configuration, migrations, queues, secrets, or recovery.

A repeatable deployment checklist

  1. Confirm the project’s Laravel and PHP constraints from composer.json and composer.lock.
  2. Provision Apache, the correct PHP handler and extensions, Composer, and the required database connectivity.
  3. Deploy the release under a non-root account at a path such as /var/www/example.com.
  4. Create a protected .env; set production values and disable debug output.
  5. Install locked dependencies with composer install --no-dev --prefer-dist --optimize-autoloader.
  6. Build frontend assets using the application’s documented production toolchain.
  7. Set Apache’s DocumentRoot to /var/www/example.com/public.
  8. Enable mod_rewrite, permit the shipped rewrite rules, and reload only after apachectl configtest succeeds.
  9. Grant the PHP process write access to storage/ and bootstrap/cache/, not the entire tree.
  10. Run required migrations, create the storage link when needed, and build Laravel caches deliberately.
  11. Test DNS, the selected vhost, clean route refreshes, assets, logs, and sensitive-file protection.
  12. Issue the certificate, configure HTTPS and renewal, then test the redirect and ACME challenge path.
  13. Restart persistent workers and record the release, migration, cache, and rollback steps.

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 *

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.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver 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.