Complete VPS Setup Guide for Laravel, PHP, Apache & MySQL on Ubuntu

This guide provides a complete production-ready VPS setup for Laravel applications running on Ubuntu with Apache, MySQL and PHP. It is designed for developers and DevOps engineers who want a stable, secure and scalable deployment environment.


1. Initial Ubuntu Server Preparation

Connect to your VPS via SSH and update system packages:

sudo apt update && sudo apt -y upgrade

Create a secure non-root sudo user:

sudo adduser prashant
sudo usermod -aG sudo prashant

2. Install Apache Web Server

sudo apt install -y apache2
sudo a2enmod rewrite headers ssl
sudo systemctl enable apache2
sudo systemctl start apache2

3. Install and Secure MySQL

sudo apt install -y mysql-server
sudo mysql_secure_installation

Create database and user for Laravel:

CREATE DATABASE laravel_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'StrongPassword';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;

4. Install PHP (mod_php Setup)

sudo apt install php php-mysql php-xml php-mbstring php-curl php-zip php-gd php-bcmath php-intl

Edit php.ini (usually located at /etc/php/8.x/apache2/php.ini) and update:

memory_limit = 512M
max_execution_time = 300
upload_max_filesize = 64M
post_max_size = 64M

Restart Apache:

sudo systemctl restart apache2

5. Deploy Laravel Application

sudo mkdir -p /var/www/html/project
sudo chown prashant:www-data /var/www/html/project
cd /var/www/html/project
git clone your_repo .
composer install --no-dev --optimize-autoloader
cp .env.example .env
php artisan key:generate
php artisan migrate --seed

Fix storage permission issues:

sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
php artisan optimize:clear

6. SSL Configuration with Let’s Encrypt

sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d example.com -d www.example.com

If using Cloudflare, set SSL mode to Full (Strict) and avoid duplicate HTTPS redirects in Apache.


7. Configure Supervisor for Laravel Queues

sudo apt install supervisor
[program:laravel-worker]
command=/usr/bin/php /var/www/html/project/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
user=www-data

Reload Supervisor:

sudo supervisorctl reread
sudo supervisorctl update


8. Firewall and Security Hardening

sudo apt install ufw
sudo ufw allow OpenSSH
sudo ufw allow 'Apache Full'
sudo ufw enable
sudo apt install fail2ban

Frequently Asked Questions

What causes “Too Many Redirects” in Laravel VPS setup?

Duplicate HTTPS redirect rules between Apache and Cloudflare usually cause redirect loops. Use Full (Strict) SSL mode and avoid redundant redirects.

Why can’t Laravel write to storage/framework/views?

Incorrect ownership. Ensure storage and bootstrap/cache are owned by www-data and have 775 permissions.

How do I reload updated php.ini?

If using mod_php, restart Apache using: sudo systemctl restart apache2

Should I use mod_php or PHP-FPM?

For high-traffic applications, PHP-FPM is recommended. For smaller projects, mod_php works fine.

Fix Elasticsearch Red Status: 3 Proven Steps

What an Elasticsearch Red Status Really Means

The Elasticsearch red status is a clear signal that your cluster is in a critical state. But what does it actually mean? In the world of Elasticsearch, cluster health is color-coded for simplicity: green, yellow, and red. While green means everything is perfect and yellow indicates a non-critical issue (like unassigned replicas), red is a call to immediate action. It signifies that at least one primary shard is unassigned. Since primary shards hold your actual data, a red status means some of your data is offline and unavailable for searching or indexing. For developers running a local instance, the first encounter with this error can be frustrating. You can diagnose this by running the cluster health API:

curl -XGET 'http://localhost:9200/_cluster/health?pretty'

When you see "status": "red" along with a non-zero value for "unassigned_primary_shards" in the response, you have confirmed the root cause. This guide will walk you through the common reasons for this status on a local machine and provide the exact commands to fix it, turning that alarming red light back to a healthy yellow or green.

Fix #1: The Common Replica Trap in a Single-Node Cluster

The most frequent reason for seeing an Elasticsearch red status right after a fresh local installation is the default replica setting. Elasticsearch is designed for resilience and high availability, so by default, it creates one replica for every primary shard. In a production cluster with multiple nodes, this is fantastic; if one node fails, the replica on another node takes over. However, in a single-node local setup, there is no “other node” to place the replica on. Elasticsearch tries to assign the replica, fails, and keeps retrying. Because the primary shards are linked to their replicas, this configuration conflict can sometimes prevent the primaries from being allocated, resulting in unassigned primary shards and a red status. The solution is straightforward: tell Elasticsearch that for this single-node cluster, you don’t need any replicas. You can do this by updating the settings for all indices with a simple API call:

curl -XPUT "http://localhost:9200/_all/_settings" -H 'Content-Type: application/json' -d'{
"index.number_of_replicas": 0
}'

Executing this command instructs Elasticsearch to set the replica count to zero for every index. This resolves the allocation conflict, allows the primary shards to become active, and typically shifts the cluster status from red to yellow (yellow is expected for a single-node cluster, as it signifies all primaries are active but replicas are not, which is true).

Fix #2: Defeating the Red Status Caused by Low Disk Space

So, you’ve set your replicas to zero, but you’re still facing a stubborn Elasticsearch red status. The next critical resource to check is your disk space. Elasticsearch is highly protective of its data and will not operate under low-disk conditions, which could lead to data corruption. It uses a system called “disk watermarks” to monitor storage. By default, when disk usage hits the “high” watermark (often 90%), Elasticsearch stops allocating shards to that node. If a shard was unassigned and needs to be allocated, it will remain unassigned, leading to a red cluster. You can check your node’s disk usage from Elasticsearch’s perspective with this command:

curl -XGET 'http://localhost:9200/_cat/allocation?v'

If you see a high disk usage percentage (e.g., 93%), you’ve found your culprit. The first and most crucial step is to free up disk space on your machine. After you have cleared sufficient space, you can encourage Elasticsearch to re-evaluate its decision and allocate the waiting shards by temporarily disabling the disk threshold, triggering a reroute, and then re-enabling the protection:

  1. Disable Thresholds: curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'{"transient":{"cluster.routing.allocation.disk.threshold_enabled":false}}'
  2. Retry Allocation: curl -X POST "localhost:9200/_cluster/reroute?retry_failed"
  3. Re-enable Thresholds: curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'{"transient":{"cluster.routing.allocation.disk.threshold_enabled":true}}'

Remember, skipping the step of freeing up disk space can lead to data integrity issues. This sequence simply forces a re-check after you’ve already fixed the underlying storage problem.

Fix #3: Solving the Fatal Startup Error “node settings must not contain any index level settings”

Perhaps the most perplexing issue is when Elasticsearch refuses to start at all, showing an exit code 1. When you check the logs, you find a fatal error: java.lang.IllegalArgumentException: node settings must not contain any index level settings. This error is a common pitfall for developers trying to make the “no replicas” setting permanent. After learning that setting replicas to zero fixes the Elasticsearch red status, a common impulse is to add index.number_of_replicas: 0 directly to the elasticsearch.yml configuration file. However, this is incorrect and will prevent Elasticsearch from booting.

The configuration file, elasticsearch.yml, is strictly for node-level settings—things that define the node itself, like its name, network settings, and memory. In contrast, settings that begin with index. are index-level settings, which define the properties of a specific data index. Since version 5.x, Elasticsearch strictly enforces this separation. You cannot place index settings in the node configuration. To fix this, you must open your elasticsearch.yml file and remove any lines that start with index.. Once you have removed these invalid entries and saved the file, Elasticsearch will start correctly. The proper way to apply index settings globally is through index templates, or by applying them directly via the API after the cluster is running, as shown in the previous steps.

FAQs

Frequently Asked Questions (FAQs)

1. What does an Elasticsearch red status mean?
An Elasticsearch red status indicates a critical issue where at least one primary shard (and consequently its replicas) is unassigned to any node. This means some of your data is unavailable, and search and indexing operations for that data will fail. While alarming, in a local setup, this is often due to configuration rather than data loss.
2. Why is my single-node Elasticsearch cluster yellow and not green?
A yellow status means all primary shards are active, but one or more replica shards are unassigned. This is the expected and perfectly healthy state for a single-node cluster. Since a replica must be on a different node than its primary, a single-node setup can never assign replicas, resulting in a permanent yellow status. The cluster is fully functional and all data is available.
3. How do I fix an Elasticsearch red status caused by unassigned shards?
For a single-node cluster, the fix is to tell Elasticsearch not to create any replicas. You can do this by running an API command to set the number of replicas to zero for your indices: curl -XPUT "http://localhost:9200/_all/_settings" -H 'Content-Type: application/json' -d'{"index.number_of_replicas": 0}'. This resolves the primary cause of the red status in a development environment.
4. Can low disk space cause an Elasticsearch red status?
Yes, absolutely. Elasticsearch has built-in disk watermarks to protect nodes from running out of disk space. If usage exceeds the high watermark (typically 90%), Elasticsearch will stop allocating new shards to that node. If a primary shard becomes unassigned for any reason and cannot be re-allocated due to this disk pressure, the cluster status will turn red. Freeing up disk space is the only solution in this scenario.
5. What is the “node settings must not contain any index level settings” error?
This fatal startup error occurs when you place a setting that belongs to an index (like index.number_of_replicas) into the main node configuration file (elasticsearch.yml). Since Elasticsearch version 5, index-level configurations must be managed via index templates or the index settings API, not in the node’s static configuration. To fix it, you must remove any lines starting with index.* from your elasticsearch.yml file.

Conclusion/Recomendation

Conclusion: Achieving a Healthy Elasticsearch Cluster

Encountering an Elasticsearch red status can be alarming, but as we’ve demonstrated, it’s often a solvable issue, especially in a local development environment. The key is a systematic approach to troubleshooting. By understanding the root causes, you can quickly diagnose and resolve the problem. Always start by checking for unassigned replicas, as this is the most frequent culprit in a single-node setup. If the issue persists, your next step should be to investigate disk space, as Elasticsearch’s protective watermarks can halt shard allocation. Finally, if you face startup failures, a misconfigured elasticsearch.yml is almost always the cause.

By following the steps outlined in this guide—setting replicas to zero via the API, managing disk space, and keeping your configuration files clean—you can reliably turn that red status to yellow or green. Adopting these practices will not only fix your immediate problem but also empower you with the knowledge to maintain a stable and efficient local Elasticsearch environment for all your development needs.

Proven Fixes for Apache Virtual Hosts Not Redirecting Subdomains

Introduction

When setting up Apache Virtual Hosts, it’s common to face issues where subdomains don’t redirect to their intended directories. This problem can disrupt site functionality and cause user confusion. Let’s explore the solutions.

What Causes Apache Virtual Hosts Issues?

Apache Virtual Hosts issues often arise from:

  1. Incorrect ServerName or ServerAlias directives.
  2. Missing or improperly enabled configuration files.
  3. Conflicting configurations.
  4. DNS settings pointing incorrectly.

Fixes for Apache Virtual Hosts Not Redirecting Subdomains

1. Verify Virtual Host Configuration

Ensure each subdomain points to the correct DocumentRoot.

<VirtualHost *:80>
    ServerName dev.domain.com
    DocumentRoot /var/www/html/dev
</VirtualHost>

2. Enable Configuration Files

Activate your configuration using:

sudo a2ensite dev.domain.com.conf
sudo systemctl reload apache2

3. Check DNS Settings

Ensure your DNS provider has an A record for each subdomain pointing to your server’s IP.

4. Set a Global ServerName

Eliminate warnings by defining a global ServerName:

ServerName domain.com

5. Restart Apache

After making changes, restart Apache to apply them:

sudo systemctl restart apache2


Other Fixes: Check permissions, disable conflicting modules, and review error logs for additional clues.

Why Proper Subdomain Redirection Matters

Misconfigured subdomains can lead to:

  • Poor user experience.
  • SEO ranking issues.
  • Security vulnerabilities.

Conclusion

By following these fixes, you can resolve Apache Virtual Hosts not redirecting subdomains efficiently.