Laravel 7 Deployment on Centos7 OCI machine using nginx with free SSL

I recently got a chance to do a small work on a friend’s project and will summarize the secret steps to have a production deployment on Oracle Cloud of a Laravel project on Centos 7 updated 2020.

The project is split into the bellow steps:

  • Environment Provisioning
    • OCI Configuration
      • Network Setup
      • Machine creation
    • Domain acquisition
    • Packages installation
      • PHP Installation
      • Composer Installation
      • GIT
  • Database configuration
  • Project setup
    • cerbot installation
    • Laravel project creation
    • ngix installation and configuration

Environment Provisioning

OCI Configuration

This is short version of this post

Network Setup

Create a new VCN using the VCN wizard (make sure it not use DNS hostnames)

Machine creation

Create the VM and get the public ip here we will assume the ip is make sure you open the ports on the VM firewall and the the OCI console firewall, the ports we will use are 80,443,3306

Domain acquisition

The very first thing we need is to obtains a domain, you can buy it wherever you want but I personally prefer google domains, it is cheap (about 10USD annually) and they include the data protection for you domain which is very important of the email that you use for the domain registration will fill of spam in no time.

Once you have bought it you should have something like this

from which you can manage the DNS, click it and go to the bottom, there you can add DNS records to connect the VM where your site is hosted to the domain.

Here we will assume the domain is

Insert the below records

Type:  A
Name:  @
TTL:   1H
Type:  CNAME
Name:  www
TTL:   1H

hit save and the DNS should be ready, to make sure it works, from the terminal execute

 dig +trace
 dig +trace

They should return the IP that you assigned above, the change should take a up to 2 days depending on where you bought the domain and their DNS servers, in google domains it takes like 2 minutes.

Packages installation

PHP 7.4 installation

yum -y install
yum -y install
yum -y install yum-utils
yum-config-manager --enable remi-php74
yum update -y
yum install -y php php-cli
yum install -y php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mcrypt php-mbstring php-curl php-xml php-pear php-bcmath php-json php-fpm

Composer install

php -r "copy('', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

sudo mv composer.phar /usr/local/bin/composer

verify installs

php -v
composer -V

nodejs installation

curl -sL | sudo bash -
sudo yum install -y nodejs

git installation

yum remove -y git*
yum install -y
yum install -y git

Database configuration

click here

Project setup

Cerbot Installation

First as root, we need to install cerbot, which is the utility we will use later to generate the certificates for the domain.

yum install -y install python3-devel gcc augeas-libs openssl-devel libffi-devel \ redhat-rpm-config ca-certificates openssl
cd /home/$USER
git clone
cd certbot
python tools/
source venv3/bin/activate

Learn about testing cerbot executions here

Laravel project creation

cd /var/www/
composer create-project --prefer-dist "laravel/laravel=~7"
composer install
npm install
cp .env.example .env

add to the .env the database credentials

APP_KEY=$your key

run the Laravel migrations

php artisan migrate
chmod -R 777 storage
chmod -R 777 bootstrap/cache

the project was deployed home will be /var/www/ the Laravel public folder will be on /var/www/

nginx installation and configuration

yum install -y nginx

The folder configuration will be /etc/nginx now lets create some folders and files

cd /etc/nginx
mkdir sistes-available
mkdir sistes-enabled
touch sistes-available/
ln -s sistes-available/ sistes-enabled

Then modify the file /etc/nginx/nginx.conf its content should look like this (specially the include part)

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    # this is where the configs are located
    include /etc/nginx/sites-enabled/*.conf;

php fast cgi configuration

systemctl start php-fpm
systemctl enable php-fpm

Now we need to identify the socket created by the above command, to do so, open


if it is not there, you need to locate it using

locate www.conf

Inside, look for listen

listen =

This little bastard is where the nginx server will submit the php code, it could also be something like


it depends on the Linux flavor you use, now let’s edit

server {
         listen 80;
         listen [::]:80 ipv6only=on;
         # Log files for Debugging
         access_log /var/log/nginx/laravel-access.log;
         error_log /var/log/nginx/laravel-error.log;
         # Webroot Directory for Laravel project
         root /var/www/;
         index index.php index.html index.htm;
         # Your Domain Name
         location / {
                 try_files $uri $uri/ /index.php?$query_string;
         # PHP-FPM Configuration Nginx
         location ~ \.php$ {
                 try_files $uri =404;
                 fastcgi_split_path_info ^(.+\.php)(/.+)$;
                 fastcgi_index index.php;
                 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                 include fastcgi_params;

Special attention to the value of fastcgi_pass this is just a temporary configuration that will allow to access to the domain on port 80, however, on modern browser this won’t work due to security reasons, this will be used only to allow validate the domain and generate the certificates with cerbot

Now you can start nginx

systemctl restart nginx

Certificates creation

certbot certonly --webroot \
--webroot-path=/var/www/ \
 -d \

The expected output should look like

 - Congratulations! Your certificate and chain have been saved at:
   Your key file has been saved at:
   Your cert will expire on 2020-12-15. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:
   Donating to ISRG / Let's Encrypt:
   Donating to EFF:          

finally, we need to edit /etc/nginx/sites-available/ to add the TLS

server {
         listen 80;
         listen [::]:80;
         return 301 https://$server_name$request_uri;
server {
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2 default_server;
    server_name  _;
    root         /var/www/;
    index index.php index.html index.htm;
    ssl_certificate "/etc/letsencrypt/live/";
    ssl_certificate_key "/etc/letsencrypt/live/";
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
     location / {
             try_files $uri $uri/ /index.php?$query_string;
     # PHP-FPM Configuration Nginx
     location ~ \.php$ {
             try_files $uri =404;
             fastcgi_split_path_info ^(.+\.php)(/.+)$;
             fastcgi_index index.php;
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             include fastcgi_params;
     location ~ /\.ht {
                deny all;
     location ~ /.well-known {
                allow all;

Restart nginx

systemctl restart nginx

finally open the browser and enjoy