How to Host PHP Laravel Website on DigitalOcean Droplet Using GitHub – Step-by-Step Guide
Deploying a PHP or Laravel application can be a daunting task, especially for those new to cloud hosting. In this guide, we’ll walk you through the process of deploying your Laravel app on DigitalOcean Droplet using GitHub for version control. By leveraging the simplicity of GitHub’s repository management and the scalability of DigitalOcean’s cloud infrastructure, you can easily streamline your deployment process. Whether you're building a small project or scaling a startup, this step-by-step tutorial will help you ensure a smooth and efficient deployment.
Create Droplet:
- Click on create button in top nav.
- Choose droplet.
- Choose region: New York.
- Choose image:
- Click on marketplace and search for "LEMP".
- Select LEMP (Get NGINX, MYSQL, and PHP-FPM...) on Ubuntu.
- Choose Size: Shared CPU/Dedicated CPU.
- Choose desired plan according to your needs.
- Choose Authentication mode (SSH/Password).
- SSH is recommended.
- Choose Hostname (Optional).
- Click on create droplet.
Access to SSH as Root User:
- Select the droplet
- Choose "Access Console" from the menu.
- Write "root" inside login as field
- Click on Launch Droplet Console
Create New SSH User:
adduser <your_desired_username>- You will be asked for a password, choose a strong password, and press enter.
- You can leave the next options empty (default). Just press enter for all:
- Full Name, Room Number, Work Phone, Home Phone, Other.
- Type
Yand press enter on the confirmation message.
Allow Permissions to New User:
usermod -aG sudo <your_desired_username>Switch from Root to New User:
su - <your_desired_username>
Generate Local SSH Keys:
cd ~/.ssh(if directory doesn't exist create one usingmkdir ~/.sshand thencd ~/.ssh)ssh-keygen -t rsa -b 4096 -C "<your_email@example.com>"- Press enter to accept default name i.e.
<id_rsa>(or write your desired name) - Enter desired password and confirm it.
Print above created ssh keys
cat ~/.ssh/id_rsa.pub
Above command will print the public key in your terminal. copy this value and now go back to your DigitalOcean console window.
Make SSH directory and Change Permissions on Server:
- Make SSH directory and change access permission:
cd ~mkdir .sshchmod 700 .ssh
nano .ssh/authorized_keys- Paste the value of your local public SSH key that we generated in the previous step at the end.
- Press Ctrl+x, then press "y", and then press enter to save this file.
Connect to Your Droplet from Local Computer Terminal:
Use the following command:
ssh <your_desired_username>@<your_droplet_ip_address>Use your local ssh key password/passphrase to login.
Configure Server Firewall:
sudo ufw allow 'Nginx HTTP'Configure MySQL:
(If you are going to use a separate server for MySQL, you can skip this step)
sudo mysql_secure_installationpress enter key to set default value for VALIDATE PASSWORD COMPONENT i.e. No
press y to remove anonymous user from DB or press n to keep it as default
press y to disable root login remotely or press n to keep it
press y to remove test database or press n to keep it
press y to reload privileges table
sudo mysql -u root -pcreate user '<your_desired_mysql_username>'@'localhost' identified by '<your_password>';alter user '<your_desired_mysql_username>'@'localhost' identified with mysql_native_password by '<your_password>';create database <database_name>;grant all on <database_name>.* to '<your_desired_mysql_username>'@'localhost';flush privileges;exit;Install Desired PHP Version and Extensions:
Check already installed PHP version using php -v.
If you want to add a new PHP version on nginx, follow these steps:
sudo apt updatesudo apt install --no-install-recommends php8.1 - (Replace 8.1 with your desired PHP version)
Check php version: `php -v` (It should be 8.1 or whatever you have choosen)
sudo apt-get install -y php8.1-cli php8.1-common php8.1-mysql php8.1-zip php8.1-gd php8.1-mbstring php8.1-curl php8.1-xml php8.1-bcmath php8.1-fpm- (Replace 8.1 with your desired PHP version)
Install Composer on Nginx:
sudo apt install unzipcurl -sS https://getcomposer.org/installer |phpsudo mv composer.phar /usr/local/bin/composerClone Private GitHub Repository:
Create SSH key on your server to allow GitHub access:
cd ~/.sshssh-keygen -t rsa -b 4096 -C "<your_email@example.com>"Press enter to accept default name ie. <id_rsa> (or write your desired name)
I recommend using a strong password. But later if you want to use the same key with GitHub Action for CI/CD and get an error: `ssh.ParsePrivateKey: ssh: this private key is passphrase protected`, create another key without a password.
eval "$(ssh-agent -s)"ssh-add ~/.ssh/id_rsacat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keysAdd Your SSH Key to GitHub Account:
- Open repository settings
- Go to Deploy Keys page and click on "Add Deploy Key" button.
- Enter any name to remember where this key belongs to.
- Enter the public SSH key in the value field. (You can use
cat ~/.ssh/id_rsa.pubcommand on the server.)
For Using the Same Key for GitHub Action CI/CD Process:
(Not necessary for just one-time deployment):
- Open Security > Secrets and variables > Actions
- Add 4 new secrets by clicking on "New repository secret" button:
- Name: "HOST", Value: "<your_server_ip_address>"
- Name: "USERNAME", Value: "<your_ssh_username>"
- Name: "PORT", Value: "<your_ssh_password>" (default is 22)
- Name: "SSH_KEY", Value: "<your_ssh_private_key>" (To get private key, use
cat ~/.ssh/id_rsacommand on the server.)
Allow GitHub Host to Allow Connection with Your Server:
nano ~/.ssh/configPaste the following content:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yesMake sure to replace id_rsa with your SSH key name.
Press Ctrl+x, then press y, and then press enter to save this file.
Clone Repository on Server (Deploy Laravel App):
cd /var/wwwsudo chown <your_ssh_username> ./git clone <your_private_github_repository_SSH_url> <directory_name_to_be_cloned_in>Change Web Directory Ownership:
sudo chown -R www-data:www-data /var/www/<app_directory_name>sudo chmod -R 755 /var/www/<app_directory_name>Setup Laravel Script:
cd <directory_name_to_be_cloned_in>composer installcp .env.example .envphp artisan key:generateUpdate
.envfile with the database name, username, password and other necessary environment variables.sudo nano .envTo save changes, press
Ctrl+x, then pressyand then press enter key to save this file.
php artisan migrate --seedsudo chown -R www-data.www-data storagesudo chown -R www-data.www-data bootstrap/cacheConfigure NGINX:
sudo nano /etc/nginx/sites-available/<your_desired_file_name>.confPaste the following configuration:
server {
listen 80;
server_name <domain_name_or_server_ip>;
root /var/www/<project_directory_name>/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.(?!well-known).* {
deny all;
}
}- (Make sure to replace values of `server_name`, `root`, and php version in above content.)
Save and close the file with Ctrl+x and press y to save changes.
Enable newly created nginx configs:
sudo ln -s /etc/nginx/sites-available/<your_desired_file_name>.conf /etc/nginx/sites-enabled/Test nginx working properly after making changes in configs:
sudo nginx -tRestart nginx server:
sudo service nginx restartConfigure SSL Using Let's Encrypt:
Run
sudo ufw statusand check if status is active and output contains below two enteries:Status: active To Action From -- ------ ---- Nginx Full ALLOW Anywhere Nginx Full (v6) ALLOW Anywhere (v6)sudo ufw allow ‘Nginx Full’- (if Nginx Full is not allowed in above command output)
sudo ufw delete allow ‘Nginx HTTP’- (delete Nginx HTTP from above command output)
sudo certbot --nginx -d example.com -d www.example.com- (make sure A records for both domains exists in your DNS settings.)
- provide your email in prompts and agree other terms.
By following this guide, you’ve successfully deployed your Laravel application to DigitalOcean using GitHub, unlocking the power of seamless version control and cloud hosting. This setup not only ensures a streamlined deployment process but also allows for easy scaling as your application grows. Whether you’re managing updates or collaborating with a team, this workflow keeps everything organized and efficient. Now, you can focus on what matters most—building and enhancing your application while enjoying the reliability of DigitalOcean’s cloud services.
Extra Helpful Commands and Links:
- Restart nginx:
sudo systemctl restart nginx - Restart php-fpm:
sudo systemctl restart php8.1-fpm(make sure to replace php version with your desired php version) - View Nginx logs:
sudo tail -f /var/log/nginx/error.log - Change php.ini file:
sudo nano /etc/php/8.1/fpm/php.ini(make sure to replace php version with your desired php version) - Move file from local to remote server:
scp /path/of/file.sql ssh_username@your_server_ip:/path/to/destination - Import MySQL dump file:
mysql -u remote_user -p remote_database < /path/of/file.sql - Helpful Links:
