Deploying a Laravel Application to a VPS: A Beginner's Guide Using Ubuntu and Nginx
Deploying a Laravel application on a Virtual Private Server (VPS) can be a rewarding experience for developers. This step-by-step guide will walk you through deploying your Laravel project on a VPS, specifically using DigitalOcean, Ubuntu, and Nginx. Additionally, we'll cover setting up a secure environment using Let's Encrypt and Certbot, and as a bonus, how to deploy using Docker.
Setting Up Your Server
1. Creating a Non-Root User
First, ensure your server is secure by creating a non-root user:
# Log in as root
ssh root@your_server_ip
# Create a new user
adduser your_username
# Grant administrative privileges
usermod -aG sudo your_username
2. Setting Up the Firewall
To secure your server, configure the firewall to allow only necessary traffic:
# Allow OpenSSH
ufw allow OpenSSH
# Enable the firewall
ufw enable
# Check the status
ufw status
Installing Required Software
3. Installing Nginx, MySQL, and PHP
Update your package index and install Nginx, MySQL, and PHP:
# Update package index
sudo apt update
# Install Nginx
sudo apt install nginx
# Install MySQL
sudo apt install mysql-server
# Secure MySQL installation
sudo mysql_secure_installation
# Install PHP and additional extensions
sudo apt install php-fpm php-mysql
4. Installing Composer
Composer is required to manage Laravel dependencies:
# Download and install Composer
curl -sS https://getcomposer.org/installer | php
# Move Composer to a globally accessible location
sudo mv composer.phar /usr/local/bin/composer
Deploying Laravel
5. Cloning Your Laravel Project
Clone your Laravel project from Git:
# Navigate to the web root
cd /var/www/
# Clone the repository
sudo git clone https://github.com/your-username/your-laravel-project.git
# Move into the project directory
cd your-laravel-project
6. Configuring the .env File
Copy the example environment file and configure it:
# Copy the example .env file
cp .env.example .env
# Generate an application key
php artisan key:generate
7. Setting Permissions
Ensure Laravel can read and write necessary files:
# Set the owner to www-data
sudo chown -R www-data:www-data /var/www/your-laravel-project
# Set permissions
sudo chmod -R 775 /var/www/your-laravel-project/storage
sudo chmod -R 775 /var/www/your-laravel-project/bootstrap/cache
8. Setting Up the Database
Create a database and user for your Laravel application:
# Log in to MySQL
sudo mysql -u root -p
# Create a new database
CREATE DATABASE laravel_db;
# Create a new user and grant privileges
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
9. Configuring Nginx
Set up Nginx to serve your Laravel application:
# Create a new Nginx server block
sudo nano /etc/nginx/sites-available/laravel
Add the following content:
server {
listen 80;
server_name your_domain www.your_domain;
root /var/www/your-laravel-project/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Enable the configuration and restart Nginx:
# Enable the configuration
sudo ln -s /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/
# Test the configuration
sudo nginx -t
# Restart Nginx
sudo systemctl restart nginx
Enabling HTTPS with Let's Encrypt
10. Installing Certbot and Obtaining a Certificate
Secure your application with SSL using Let's Encrypt:
# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Obtain a certificate
sudo certbot --nginx -d your_domain -d www.your_domain
# Verify renewal
sudo certbot renew --dry-run
Bonus: Deploying with Docker
11. Docker Setup
Create Dockerfiles and configuration for PHP, MySQL, and Nginx:
Dockerfile
FROM php:7.4-fpm
WORKDIR /var/www
COPY . .
RUN docker-php-ext-install pdo pdo_mysql
docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
volumes:
- .:/var/www
networks:
- app-network
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: laravel_db
MYSQL_USER: laravel_user
MYSQL_PASSWORD: password
networks:
- app-network
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- app-network
networks:
app-network:
driver: bridge
default.conf
server {
listen 80;
index index.php index.html;
server_name your_domain www.your_domain;
root /var/www/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
12. Running Docker Containers
Start your application with Docker:
# Build and start the containers
sudo docker-compose up -d
Conclusion
Congratulations! You've successfully deployed your Laravel application on a VPS using Nginx and secured it with HTTPS. As a bonus, you've also learned how to deploy using Docker. This setup will serve as a robust foundation for deploying your future Laravel projects.