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!👍🏻
Top comments (1)
This doesn't work for me.
I'm using react router for routing