Deploy Laravel Applications on Linux Cloud Servers

2024-10-01

Deploying a Laravel application on a Linux cloud server involves multiple components working together: Apache web server for serving HTTP requests, PHP for running Laravel code, MySQL for database management, and proper configuration of file permissions and virtual hosts. This comprehensive guide walks you through every step of the deployment process, from initial server setup to troubleshooting common issues.

Whether you're deploying your first Laravel application or setting up a production environment, this guide provides detailed instructions for configuring your server infrastructure, managing databases, handling Git authentication, and ensuring your application runs smoothly in a cloud environment.

Prerequisites

Before starting the deployment process, ensure you have:

  1. A Linux cloud server (Ubuntu/Debian recommended)
  2. Root or sudo access to the server
  3. Basic knowledge of command line operations
  4. A Laravel application ready for deployment
  5. Database dump file (if migrating existing data)

Installing Server Components

The foundation of any Laravel deployment requires a properly configured LAMP (Linux, Apache, MySQL, PHP) stack. Each component plays a crucial role in serving your application.

Step 1: Update the Package List

Start by updating your system's package manager to ensure you have access to the latest software versions:

sudo apt update

This command refreshes the local package index with the latest changes made in the repositories, ensuring you install the most recent versions of software packages.

Step 2: Install Apache Web Server

Apache HTTP Server is a robust, commercial-grade web server that will handle incoming HTTP requests to your Laravel application:

sudo apt install apache2

Apache serves as the entry point for web traffic, processing requests and directing them to your PHP application. It also handles static assets like CSS, JavaScript, and images efficiently.

Step 3: Install PHP and Required Extensions

Laravel requires PHP 7.3 or higher along with several PHP extensions. Install PHP with all necessary extensions for Laravel:

sudo apt install php php-cli php-fpm php-mbstring php-xml php-zip php-bcmath php-mysql libapache2-mod-php

These extensions provide essential functionality:

  • php-mbstring: Multibyte string handling for international characters
  • php-xml: XML processing capabilities
  • php-zip: Archive file handling
  • php-bcmath: Arbitrary precision mathematics
  • php-mysql: MySQL database connectivity
  • libapache2-mod-php: Apache module for PHP processing

Step 4: Install MySQL Database Server

MySQL will store your application's data and handle database operations:

sudo apt install mysql-server

MySQL provides reliable, scalable data storage with support for complex queries, transactions, and relationships that Laravel applications typically require.

Step 5: Start and Enable Services

Start both Apache and MySQL services and configure them to start automatically on system boot:

sudo systemctl start apache2
sudo systemctl start mysql

Enable automatic startup:

sudo systemctl enable apache2
sudo systemctl enable mysql

These commands ensure your web server and database server are running and will automatically restart if the system reboots.

Configuring MySQL Database

Proper database configuration is crucial for Laravel applications. MySQL needs to be secured and configured with appropriate user accounts and databases.

Step 1: Secure MySQL Installation

Run the MySQL security script to remove default accounts and set security policies:

sudo mysql_secure_installation

This interactive script will prompt you to:

  • Set a root password
  • Remove anonymous users
  • Disallow root login remotely
  • Remove test database
  • Reload privilege tables

Follow the prompts and choose secure options for your production environment.

Step 2: Create Database and User

Log into MySQL as the root user:

sudo mysql -u root -p

Create a dedicated database and user for your Laravel application:

CREATE DATABASE your_database_name;
CREATE USER 'your_username'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON your_database_name.* TO 'your_username'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Replace your_database_name, your_username, and your_password with your actual values. This creates an isolated database environment for your application with dedicated credentials.

Setting Up Git Authentication

If you're deploying from a Git repository, you'll need to configure SSH authentication to securely access your code repository.

Step 1: Check for Existing SSH Keys

First, check if SSH keys already exist on your server:

ls -la ~/.ssh

If you see id_rsa and id_rsa.pub files, you already have an SSH key pair. If the directory is empty or doesn't exist, proceed to generate new keys.

Step 2: Generate SSH Key Pair

Create a new SSH key pair if one doesn't exist:

ssh-keygen -t rsa -b 4096

When prompted:

  • Press Enter to save the key in the default location (~/.ssh/id_rsa)
  • Optionally add a passphrase for additional security, or leave empty
  • The public key will be saved as ~/.ssh/id_rsa.pub

Step 3: Display and Copy Public Key

Display your public key to copy it to your Git provider:

cat ~/.ssh/id_rsa.pub

Copy the entire output, including the ssh-rsa prefix and email suffix.

Step 4: Add Key to GitHub

  1. Go to GitHub Settings → SSH and GPG keys
  2. Click "New SSH key"
  3. Give it a descriptive title (e.g., "Production Server")
  4. Paste your public key
  5. Click "Add SSH key"

Step 5: Test SSH Connection

Verify the SSH connection to GitHub:

ssh -T git@github.com

If successful, you'll see a message like:

Hi username! You've successfully authenticated, but GitHub does not provide shell access.

Troubleshooting SSH Issues

If you encounter permission denied errors:

Check SSH Agent

Verify your SSH key is loaded:

ssh-add -l

If you see "The agent has no identities," add your key:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

Deploying Your Application

With the server environment configured, you can now deploy your Laravel application.

Step 1: Set Directory Permissions

Change ownership of the web directory to allow your user to write files:

sudo chown -R $USER:$USER /var/www/html

This grants necessary permissions to clone and manage your application files.

Step 2: Clone Your Repository

Navigate to the web directory and clone your Laravel application:

cd /var/www/html
git clone git@github.com:your-username/your-repository.git

Replace the URL with your actual repository URL.

Step 3: Set Application Permissions

Configure proper permissions for Laravel:

sudo chown -R www-data:www-data /var/www/your-laravel-app
sudo chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache

These permissions ensure:

  • Apache can serve your application files
  • Laravel can write to storage and cache directories
  • Proper security is maintained

Database Import and Management

If you're migrating an existing application, you'll need to import your database.

Step 1: Prepare Database Dump

Ensure your database dump file (.sql) is accessible on the server. If you have a compressed file, extract it first.

Step 2: Import Database

Import your SQL dump into the MySQL database:

mysql -u root -p your_database_name < /path/to/your_dump_file.sql

For example:

mysql -u root -p db_name < /var/www/html/project/sql-db/database_file.sql

Step 3: Verify Import

Check that tables were imported successfully:

mysql -u root -p

Inside MySQL:

USE your_database_name;
SHOW TABLES;

This will list all tables in your database.

Configuring Apache Virtual Host

Apache needs to be configured to serve your Laravel application properly, directing traffic to the public directory and enabling URL rewriting.

Step 1: Create Virtual Host Configuration

Create a new Apache virtual host configuration file:

sudo nano /etc/apache2/sites-available/laravel-app.conf

Add the following configuration:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName your-domain.com
    DocumentRoot /var/www/your-laravel-app/public

    <Directory /var/www/your-laravel-app/public>
        AllowOverride All
        Require all granted
    </Directory>

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

Replace your-domain.com and /var/www/your-laravel-app with your actual domain and application path.

Step 2: Enable Site and Modules

Enable your new site configuration and the rewrite module:

sudo a2ensite laravel-app.conf
sudo a2enmod rewrite

The rewrite module is essential for Laravel's routing system to work properly.

Step 3: Restart Services

Apply the changes by restarting Apache and MySQL:

sudo systemctl restart apache2
sudo systemctl restart mysql

File Management Operations

During deployment and maintenance, you'll need to perform various file operations.

Moving Files

To move all files from a project directory to /var/www/html:

mv Project_name/* Project_name/.* .

This command moves:

  • Project_name/*: All visible files and directories
  • Project_name/.*: All hidden files (like .env, .git)
  • .: Destination is the current directory

You may see warnings about . and .. directories - these are normal and can be ignored.

Removing Files

Remove a single file:

sudo rm index.html

Remove all files and folders in a directory:

sudo rm -rf /var/www/html/*
sudo rm -rf /var/www/html/.[!.]*

Warning: This is irreversible. Always double-check the path before executing.

Removing Empty Directories

After moving files, remove empty directories:

rmdir Project_name

Troubleshooting Common Issues

Laravel deployments can encounter various issues. Here are solutions to common problems.

MySQL Authentication Error

If you encounter "Access denied for user 'root'@'localhost'" error:

Problem

MySQL is using auth_socket plugin for root user authentication, requiring sudo instead of password authentication.

Solution

  1. Login with sudo:

    sudo mysql
    
  2. Change authentication method:

    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password';
    
  3. Exit and test:

    EXIT;
    
    mysql -u root -p
    

Disabling MySQL ONLY_FULL_GROUP_BY

Laravel applications might encounter SQL mode compatibility issues.

Quick Fix (Single Command)

sudo sed -i '/^\[mysqld\]$/a sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' /etc/mysql/mysql.conf.d/mysqld.cnf && sudo systemctl restart mysql

Manual Method

  1. Edit MySQL configuration:

    sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
    
  2. Add under [mysqld] section:

    sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
    
  3. Save and restart:

    sudo systemctl restart mysql
    

Monitoring and Logging

Proper monitoring helps identify and resolve issues quickly.

Accessing Apache Logs

Apache logs provide valuable information about requests and errors.

View Logs

sudo tail -f /var/log/apache2/access.log
sudo tail -f /var/log/apache2/error.log

List Log Files

sudo ls -la /var/log/apache2

PHP Configuration for File Uploads

For applications handling file uploads, configure PHP limits:

Edit PHP configuration:

sudo nano /etc/php/8.1/apache2/php.ini

Add or modify these values:

upload_max_filesize = 100M
post_max_size = 120M
max_execution_time = 300
memory_limit = 256M

Restart Apache to apply changes:

sudo systemctl restart apache2

Security Best Practices

File Permissions

Ensure proper file permissions for security:

# Application files
sudo chown -R www-data:www-data /var/www/your-laravel-app
sudo chmod -R 644 /var/www/your-laravel-app
sudo chmod -R 755 /var/www/your-laravel-app/storage
sudo chmod -R 755 /var/www/your-laravel-app/bootstrap/cache

Environment Configuration

Protect your .env file:

sudo chmod 600 /var/www/your-laravel-app/.env
sudo chown www-data:www-data /var/www/your-laravel-app/.env

Database Security

  • Use strong passwords for database users
  • Grant only necessary privileges
  • Regularly update MySQL
  • Consider using SSL for database connections

Performance Optimization

Enable Apache Modules

Enable useful Apache modules for better performance:

sudo a2enmod deflate
sudo a2enmod expires
sudo a2enmod headers
sudo systemctl restart apache2

Laravel Optimization

Run Laravel optimization commands:

cd /var/www/your-laravel-app
php artisan config:cache
php artisan route:cache
php artisan view:cache

Maintenance Commands

Service Management

Restart services when needed:

# Restart Apache
sudo systemctl restart apache2

# Restart MySQL
sudo systemctl restart mysql

# Check service status
sudo systemctl status apache2
sudo systemctl status mysql

Updates and Maintenance

Keep your system updated:

sudo apt update
sudo apt upgrade -y

Application Updates

Update your Laravel application:

cd /var/www/your-laravel-app
git pull origin main
composer install --no-dev
php artisan migrate
php artisan config:cache

Conclusion

Deploying Laravel applications on Linux cloud servers requires careful attention to server configuration, security, and maintenance procedures. This guide covers the essential steps from initial server setup through troubleshooting common deployment issues.

Key takeaways for successful Laravel deployment:

  • Properly configure the LAMP stack with appropriate PHP extensions
  • Secure your MySQL installation and use dedicated database users
  • Set up SSH authentication for secure Git access
  • Configure Apache virtual hosts correctly for Laravel routing
  • Implement proper file permissions for security and functionality
  • Monitor logs and handle common issues proactively
  • Maintain regular updates and backups

By following these procedures and best practices, you'll have a robust, secure Laravel application running on your cloud server. Regular monitoring, updates, and maintenance will ensure your application continues to perform optimally in production.

Remember to always test changes in a staging environment before applying them to production, maintain regular backups of both your code and database, and monitor your application's performance and security continuously.