This is a documentation of the steps I took in deploying my Laravel and React application to a VPS.
If you're reading along, I'm sure it'd be useful irrespective of the application stack.
1. Initial VPS Setup
Before deploying your applications, you need to prepare your server environment.
Update Your System
sudo apt update && sudo apt upgrade -y
Install Essential Dependencies
sudo apt install apache2 unzip curl git -y
2. Laravel Backend Deployment
Add ondrej/php PPA as a software repository.
sudo add-apt-repository ppa:ondrej/php # Press enter when prompted.
sudo apt update
Install PHP and Required Extensions
sudo apt install php php-cli php-mbstring php-xml php-bcmath php-tokenizer php-curl php-zip php-mysql -y
Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Set Up MySQL Database
sudo apt install mysql-server -y
sudo mysql_secure_installation
Create a database and user for your Laravel application:
sudo mysql -u root -p
Within the MySQL prompt:
CREATE DATABASE laravel_db;
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'your_strong_password';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Deploy Your Laravel Application
cd /var/www
git clone https://github.com/your-username/your-laravel-project.git laravel
cd laravel
composer install
cp .env.example .env
Edit the .env file with your database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=your_strong_password
Generate the application key and run migrations:
php artisan key:generate
php artisan migrate --seed
php artisan config:cache
Configure Apache for Laravel
Create a new Apache configuration file:
sudo nano /etc/apache2/sites-available/laravel.conf
Add the following configuration:
<VirtualHost *:80>
ServerAdmin webmaster@yourdomain.com
DocumentRoot /var/www/laravel/public
ServerName api.yourdomain.com
<Directory /var/www/laravel/public>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/laravel_error.log
CustomLog ${APACHE_LOG_DIR}/laravel_access.log combined
</VirtualHost>
Enable the site and required modules:
sudo a2ensite laravel.conf
sudo a2enmod rewrite
sudo systemctl restart apache2
Set Proper File Permissions
sudo chown -R www-data:www-data /var/www/laravel
sudo chmod -R 775 /var/www/laravel/storage /var/www/laravel/bootstrap/cache
3. React Frontend Deployment
Step 1: Build Your React Application
On your local development machine:
npm run build
Step 2: Transfer the Build to Your VPS
Using SCP:
scp -r build/ username@your-vps-ip:/var/www/react
Alternatively, you could clone your repository and build directly on the server (I'd recommend the former especially if deploying with a CICD pipeline):
cd /var/www
git clone https://github.com/your-username/your-react-project.git react
cd react
npm install
npm run build
Step 3: Configure Apache for React
Create a new Apache configuration:
sudo nano /etc/apache2/sites-available/react.conf
Add the following:
<VirtualHost *:80>
ServerAdmin webmaster@yourdomain.com
DocumentRoot /var/www/react/build
ServerName yourdomain.com
<Directory /var/www/react/build>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# This configuration ensures that React Router works correctly
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [L]
</Directory>
ErrorLog ${APACHE_LOG_DIR}/react_error.log
CustomLog ${APACHE_LOG_DIR}/react_access.log combined
</VirtualHost>
Enable the site:
sudo a2ensite react.conf
sudo systemctl restart apache2
4. Secure Your Applications with SSL
For production applications, SSL is essential. Let's Encrypt provides free SSL certificates:
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d yourdomain.com -d api.yourdomain.com
Follow the prompts to complete the SSL setup.
5. Set Up Process Management for Laravel
Configure Supervisor for Queue Workers
sudo apt install supervisor -y
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
Add the following configuration:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/laravel/artisan queue:work --tries=3 --sleep=3
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/log/laravel-worker.log
Activate the configuration:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
Set Up Laravel Scheduler
crontab -e
Add this line:
* * * * * cd /var/www/laravel && php artisan schedule:run >> /dev/null 2>&1
6. Advanced Configuration
Set Up a Load Balancer (Optional)
For high-traffic applications, consider setting up Nginx as a load balancer in front of Apache:
sudo apt install nginx -y
Create a configuration file:
sudo nano /etc/nginx/sites-available/loadbalancer
Add:
upstream backend {
server 127.0.0.1:8080;
# Add more servers if you have multiple instances
}
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Configure Redis for Caching (Optional)
sudo apt install redis-server -y
Update your Laravel .env file:
CACHE_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
7. Maintenance and Updates
Automating Laravel Updates
Create a simple script:
sudo nano /usr/local/bin/update-laravel
Add:
#!/bin/bash
cd /var/www/laravel
git pull
composer install --no-dev
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
sudo chown -R www-data:www-data /var/www/laravel
Make it executable:
sudo chmod +x /usr/local/bin/update-laravel
Monitoring Your Application
Install monitoring tools:
sudo apt install htop net-tools -y
8. Troubleshooting
Common Laravel Issues
-
500 Internal Server Error
- Check Laravel logs:
tail -f /var/www/laravel/storage/logs/laravel.log
- Check Apache logs:
tail -f /var/log/apache2/laravel_error.log
- Check Laravel logs:
-
Permission Issues
- Run:
sudo chown -R www-data:www-data /var/www/laravel
- Run:
Common React Issues
-
White Screen / Not Loading
- Check browser console for errors
- Verify .htaccess file in build directory
-
API Connection Issues
- Ensure your .env file in React has the correct API URL
Conclusion
You've now successfully deployed both your Laravel backend and React frontend on a single VPS.
Remember to regularly back up your database and application files, keep your server updated with security patches, and monitor your application's performance as your user base grows.
Up until now we have done the deployment manually, but you should definitely consider setting up a CICD pipeline for easy, automated deployment. GitHub Actions is a good recommendation.
Happy coding!👍🏻