Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Deployment Guide for Ubuntu Server from Scratch with Laravel
title keywords description date tags permalink img author authorlink
Setting Up Laravel in Ubuntu / DigitalOcean
servers, laravel, coderstape, coder's tape
Let's take a look at settting up a server from scratch for Laravel.
April 1, 2019
servers, laravel
setting-up-laravel-in-ubuntu-digitalocean
Victor Gonzalez

In this post, we are looking at the steps necessary to create an Ubuntu droplet in DigitalOcean from scratch. This is the companion guide to the video series in Laravel 5.8 from scrath. Follow along with those to get the video guide.

Part 1 https://coderstape.com/lesson/112-deployment-basic-server-setup-part-1

Part 2 https://coderstape.com/lesson/113-deployment-basic-server-setup-part-2

Part 3 https://coderstape.com/lesson/114-deployment-basic-server-setup-part-3

Getting Started

  • Create droplet with Ubuntu 18.10
  • ssh root@[DROPLET IP ADDRESS]
  • Get password from your email
  • Change password on first login
  • adduser laravel
  • Enter password and other information
  • usermod -aG sudo laravel

Locking Down to SSH Key only (Extremely Important)

  • In your local machine, ssh-keygen
  • Generate a key, if you leave passphrase blank, no need for password
  • ls ~/.ssh to show files in local machine
  • Get the public key, cat ~/.ssh/id_rsa.pub
  • Copy it
  • cd ~/.ssh and vim authorized_keys
  • Paste key
  • Repeat steps for laravel user
  • su laravel then mkdir ~/.ssh fix permissions chmod 700 ~/.ssh
  • vim ~/.ssh/authorized_keys and paste key
  • chmod 600 ~/.ssh/authorized_keys to restrict this from being modified
  • exit to return to root user

Disable Password from Server

  • sudo vim /etc/ssh/sshd_config
  • Find PasswordAuthentication and set that to no
  • Turn on PubkeyAuthentication yes
  • Turn off ChallengeResponseAuthentication no
  • Reload the SSH service sudo systemctl reload sshd
  • Test new user in a new tab to prevent getting locked out

Setting Up Firewall

  • View all available firewall settings
  • sudo ufw app list
  • Allow on OpenSSH so we don't get locked out
  • sudo ufw allow OpenSSH
  • Enable Firewall
  • sudo ufw enable
  • Check the status
  • sudo ufw status

Install Linux, Nginx, MySQL, PHP

Nginx

  • sudo apt update enter root password
  • sudo apt install nginx enter Y to install
  • sudo ufw app list For firewall
  • sudo ufw allow 'Nginx HTTP' to add NGINX
  • sudo ufw status to verify change
  • Visit server in browser

MySQL

  • sudo apt install mysql-server enter Y to install
  • sudo mysql_secure_installation to run automated securing script
  • Press N for VALIDATE PASSWORD plugin
  • Set root password
  • Remove anonymous users? Y
  • Disallow root login remotely? N
  • Remove test database and access to it? Y
  • Reload privilege tables now? Y
  • sudo mysql to enter MySQL CLI
  • SELECT user,authentication_string,plugin,host FROM mysql.user; to verify root user's auth method
  • ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'STRONG_PASSWORD_HERE'; to set a root password
  • SELECT user,authentication_string,plugin,host FROM mysql.user; to verify root user's auth method
  • FLUSH PRIVILEGES; to apply all changes
  • mysql -u root -p to access db from now on, enter password STRONG_PASSWORD_HERE

PHP & Basic Nginx

  • sudo add-apt-repository universe to add software repo
  • sudo apt install php-fpm php-mysql to install the basic PHP software
  • sudo vim /etc/nginx/sites-available/YOUR.DOMAIN.COM
server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name YOUR.DOMAIN.COM;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        }

        location ~ /\.ht {
                deny all;
        }
}
  • sudo ln -s /etc/nginx/sites-available/YOUR.DOMAIN.COM /etc/nginx/sites-enabled/ to create symlink to enabled sites
  • sudo unlink /etc/nginx/sites-enabled/default to remove default link
  • sudo nginx -t test the whole config
  • sudo systemctl reload nginx to apply all changes
  • sudo vim /var/www/html/info.php to start a new PHP file, fill it with <?php phpinfo();
  • sudo rm /var/www/html/info.php optional command to get rid of test file

Let's Dial in The Laravel Ecosystem

  • sudo apt-get install php7.2-mbstring php7.2-xml composer unzip
  • mysql -u root -p Login to create the Laravel DB
  • CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
  • GRANT ALL ON laravel.* TO 'laraveluser'@'localhost' IDENTIFIED BY 'password';
  • FLUSH PRIVILEGES;
  • exit
  • cd /var/www/html, sudo mkdir -p first-project
  • sudo chown laravel:laravel first-project
  • git clone https://github.com/coderstape/laravel-58-from-scratch.git .
  • composer install
  • cp .env.example .env, and then vim .env
APP_NAME=Laravel
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=http://YOUR.DOMAIN.COM

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=root
DB_USERNAME=laravel
DB_PASSWORD=STRONG_PASSWORD_HERE
  • php artisan migrate
  • php artisan key:generate to generate the key
  • sudo chgrp -R www-data storage bootstrap/cache fix permissions
  • sudo chmod -R ug+rwx storage bootstrap/cache fix permissions
  • sudo chmod -R 755 /var/www/html/first-project fix permissions
  • chmod -R o+w /var/www/html/first-project/storage/ fix permission

Modify Nginx

  • sudo vim /etc/nginx/sites-available/YOUR.DOMAIN.COM
server {
    listen 80;
    listen [::]:80;

    root /var/www/html/first-project/public;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name YOUR.DOMAIN.COM;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    location ~ /\.ht {
            deny all;
    }
}
  • sudo nginx -t
  • sudo systemctl reload nginx reload Nginx

Let's Encrypt

  • sudo add-apt-repository ppa:certbot/certbot to get repo
  • sudo apt install python-certbot-nginx to install
  • sudo certbot certonly --webroot --webroot-path=/var/www/html/quickstart/public -d example.com -d www.example.com
  • sudo certbot certonly --webroot --webroot-path=/var/www/html/first-project/public -d YOUR.DOMAIN.COM

Final mod for Nginx

  • sudo vim /etc/nginx/sites-available/YOUR.DOMAIN.COM
server {
    listen 80;
    listen [::]:80;

    server_name YOUR.DOMAIN.COM;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name YOUR.DOMAIN.COM;
    root /var/www/html/first-project/public;

    ssl_certificate /etc/letsencrypt/live/YOUR.DOMAIN.COM/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/YOUR.DOMAIN.COM/privkey.pem;
    
    ssl_protocols TLSv1.2;
	ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
	ssl_prefer_server_ciphers on;

	add_header X-Frame-Options "SAMEORIGIN";
	add_header X-XSS-Protection "1; mode=block";
	add_header X-Content-Type-Options "nosniff";

	index index.php index.html index.htm index.nginx-debian.html;

    charset utf-8;

    location / {
            try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    }

    location ~ /\.ht {
            deny all;
    }

    location ~ /.well-known {
            allow all;
    }
}
  • sudo nginx -t
  • sudo ufw app list For firewall
  • sudo ufw allow 'Nginx HTTPS' to add NGINX
  • sudo ufw status to verify change
  • sudo systemctl reload nginx reload Nginx

Extra Credit

Let's make the prompt pretty

  • sudo apt-get install zsh to install ZSH
  • zsh --version to confirm install
  • whereis zsh to find out where it is
  • sudo usermod -s /usr/bin/zsh $(whoami) to make Zsh default
  • sudo reboot to reapply all changes
  • 2 to populate a default file
  • sudo apt-get install powerline fonts-powerline to install powerline
  • sudo apt-get install zsh-theme-powerlevel9k to install Theme
  • echo "source /usr/share/powerlevel9k/powerlevel9k.zsh-theme" >> ~/.zshrc to enable the theme in your Zshrc
  • exit and login again to see the new theme
  • sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)" for Oh My Zsh
  • echo "source /usr/share/powerlevel9k/powerlevel9k.zsh-theme" >> ~/.zshrc to re-enable 9K
@himan72

This comment has been minimized.

Copy link

@himan72 himan72 commented Mar 24, 2019

Hey nice guide many thanks for sharing. May i suggest to add an auto-deployment from github part

@ferdikam

This comment has been minimized.

Copy link

@ferdikam ferdikam commented Mar 24, 2019

thanks for sharing.

@hamdicatal

This comment has been minimized.

Copy link

@hamdicatal hamdicatal commented Mar 24, 2019

Hey nice guide many thanks for sharing. May i suggest to add an auto-deployment from github part

I support this comment :) I appreciate all but i think this awesome tutorial deserves an auto-deploymet.

@nareshbabu557

This comment has been minimized.

Copy link

@nareshbabu557 nareshbabu557 commented Apr 3, 2019

Hey nice guide many thanks for sharing. May i suggest to add an auto-deployment from github part

+1 for this, I'm also looking for this part

@SumanRoX

This comment has been minimized.

Copy link

@SumanRoX SumanRoX commented May 31, 2019

I have very basic question on how do you setup laravel on server such that it doesn't require us to run 'php artisan serve' like we did in local environment? I watched the whole video but I am bit confused as the about,contact and all other pages don't work, gives me 404 /contact, /about , /customers not found error unless I run the artisan serve.

@SumanRoX

This comment has been minimized.

Copy link

@SumanRoX SumanRoX commented May 31, 2019

And how did you manage to bring down the project size to 5 MB while I have 60+ MB project on my local environment

@SumanRoX

This comment has been minimized.

Copy link

@SumanRoX SumanRoX commented Jun 1, 2019

Solution for "running laravel app without php artisan serve"

If you don't have AllowOverride set to All, your Laravel .htaccess file (/public/.htaccess) won't be able to enable mod_rewrite, and your routes won't work.
I solved it by adding in block

<Directory "/var/www/mylaravel/public">
    Options All
    AllowOverride All
    Allow from all
</Directory>
@Fa2it

This comment has been minimized.

Copy link

@Fa2it Fa2it commented Jul 11, 2019

Many thanks that were very helpful

@amadoutidiane

This comment has been minimized.

Copy link

@amadoutidiane amadoutidiane commented Aug 27, 2019

hello i have 405 error some one can help me i deploy angular on frontEnd that word but laravel dont access post request

@mgmgpyaesonewin

This comment has been minimized.

Copy link

@mgmgpyaesonewin mgmgpyaesonewin commented Aug 27, 2019

If Permission cmd does not work, I try with this and it is working.

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
@wbarnard81

This comment has been minimized.

Copy link

@wbarnard81 wbarnard81 commented Oct 14, 2019

I have to install php sqlite as well @let's Dial in The Laravel Ecosystem

sudo apt install php7.2-sqlite

@csiki96

This comment has been minimized.

Copy link

@csiki96 csiki96 commented Oct 20, 2019

Such a nice guide! Helped a lot, thanks!

@gabrielsmenezes

This comment has been minimized.

Copy link

@gabrielsmenezes gabrielsmenezes commented Dec 12, 2019

Great tutorial! Helped a lot.

Ajudou bastante, valeu!

@gabrielsmenezes

This comment has been minimized.

Copy link

@gabrielsmenezes gabrielsmenezes commented Dec 12, 2019

If you got error 500. Run:
chmod -R 777 storage

@eehmull

This comment has been minimized.

Copy link

@eehmull eehmull commented Dec 13, 2019

Solution for "running laravel app without php artisan serve"

If you don't have AllowOverride set to All, your Laravel .htaccess file (/public/.htaccess) won't be able to enable mod_rewrite, and your routes won't work.
I solved it by adding in block

<Directory "/var/www/mylaravel/public">
    Options All
    AllowOverride All
    Allow from all
</Directory>

@SumanRoX where did you add this code ?

@stesvis

This comment has been minimized.

Copy link

@stesvis stesvis commented Jan 3, 2020

Hello, I followed all the steps but I am getting this error:

 sudo apt-get install php7.2-mbstring php7.2-xml composer unzip
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package php7.2-mbstring
E: Couldn't find any package by glob 'php7.2-mbstring'
E: Couldn't find any package by regex 'php7.2-mbstring'
E: Unable to locate package php7.2-xml
E: Couldn't find any package by glob 'php7.2-xml'
E: Couldn't find any package by regex 'php7.2-xml'

Any idea? thanks for the tutorial!

@gabrielsmenezes

This comment has been minimized.

Copy link

@gabrielsmenezes gabrielsmenezes commented Jan 4, 2020

Hello, I followed all the steps but I am getting this error:

 sudo apt-get install php7.2-mbstring php7.2-xml composer unzip
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package php7.2-mbstring
E: Couldn't find any package by glob 'php7.2-mbstring'
E: Couldn't find any package by regex 'php7.2-mbstring'
E: Unable to locate package php7.2-xml
E: Couldn't find any package by glob 'php7.2-xml'
E: Couldn't find any package by regex 'php7.2-xml'

Any idea? thanks for the tutorial!

I think you need to install php7.2-mbstring and php7.2-xml. You can see if you have mbstring enable with:

php -i | grep mbstring

If you got:

Multibyte decoding support using mbstring => disabled

Try:

install apt-get install php7.2-mbstring

After installed run again:

php -i | grep mbstring

and you ll get something like:

/etc/php/7.2/cli/conf.d/20-mbstring.ini, Zend Multibyte Support => provided by mbstring Multibyte decoding support using mbstring => enabled mbstring mbstring extension makes use of "streamable kanji code filter and converter", which is distributed under the GNU Lesser General Public License version 2.1. mbstring.detect_order => no value => no value mbstring.encoding_translation => Off => Off mbstring.func_overload => 0 => 0 mbstring.http_input => no value => no value mbstring.http_output => no value => no value mbstring.http_output_conv_mimetypes => ^(text/|application/xhtml\+xml) => ^(text/|application/xhtml\+xml) mbstring.internal_encoding => no value => no value mbstring.language => neutral => neutral mbstring.strict_detection => Off => Off mbstring.substitute_character => no value => no value

@MuhammadFaizanShakir

This comment has been minimized.

Copy link

@MuhammadFaizanShakir MuhammadFaizanShakir commented Jan 5, 2020

Thank you

@stesvis

This comment has been minimized.

Copy link

@stesvis stesvis commented Jan 6, 2020

@gabrielsmenezes I restarted with a new instance of Ubuntu 18.0.4 instead of Ubuntu 19 and it works fine now, thanks!

@gabrielsmenezes

This comment has been minimized.

Copy link

@gabrielsmenezes gabrielsmenezes commented Jan 7, 2020

@stesvis nice :)

@akseries

This comment has been minimized.

Copy link

@akseries akseries commented Jan 21, 2020

Thank you for sharing this stuff. It is absolutely great tutorial.

@yavgel85

This comment has been minimized.

Copy link

@yavgel85 yavgel85 commented Jan 29, 2020

Great tutorial! Helped a lot.

@yavgel85

This comment has been minimized.

Copy link

@yavgel85 yavgel85 commented Jan 29, 2020

Please сan you create record a tutorial about How to Set Up a Full-Featured Mail Server on Ubuntu 18.04 (e.g. with PostFix / iRedMail)

@jaouhara-chanchaf

This comment has been minimized.

Copy link

@jaouhara-chanchaf jaouhara-chanchaf commented Mar 22, 2020

A very clear and detailed guide. Thank you for sharing !

@ahmedseaf

This comment has been minimized.

Copy link

@ahmedseaf ahmedseaf commented Mar 27, 2020

thank you very mush

@jewishmoses

This comment has been minimized.

Copy link

@jewishmoses jewishmoses commented Apr 7, 2020

chmod -R 777

I wouldn't suggest such thing.
“chmod 777” means making the file readable, writable and executable by everyone.

@csiki96

This comment has been minimized.

Copy link

@csiki96 csiki96 commented Apr 22, 2020

Encryption not working anymore therefore I dont get the ssl certificate, anybody have an idea how to fix it?

@Cod3rMax

This comment has been minimized.

Copy link

@Cod3rMax Cod3rMax commented Apr 22, 2020

How to know what is the nameserver so i can put my domain name on the droplet?

@Sahaj-15

This comment has been minimized.

Copy link

@Sahaj-15 Sahaj-15 commented May 5, 2020

Thank you so much! <3

@csiki96

This comment has been minimized.

Copy link

@csiki96 csiki96 commented May 20, 2020

Encryption not working anymore therefore I dont get the ssl certificate, anybody have an idea how to fix it?

If u have problems, just restart nginx

@dgloriaweb

This comment has been minimized.

Copy link

@dgloriaweb dgloriaweb commented Jun 16, 2020

Hi, please change this to sudo:
chmod -R o+w /var/www/html/first-project/storage/ fix permission

@youssefkhouili

This comment has been minimized.

Copy link

@youssefkhouili youssefkhouili commented Jul 3, 2020

Thank you so much

@BobbyBriQz

This comment has been minimized.

Copy link

@BobbyBriQz BobbyBriQz commented Jul 8, 2020

Thanks for this ✌🏽

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.