Setup Dev Environment For Laravel On Ubuntu 20.04 (LEMP + Redis, MailHog, Minio, Ngrok)

Feb 14, 2022

Note: This setup is only for development on local machine, it is not ready for production! To setup server with LEMP stack ready for production please inform yourself more about performances and security issues.

Prerequisites

You should already have installed Ubuntu 20.04 server or desktop.

Installing PHP

First we will install PHP and after that we will install all extensions that are required to run Laravel.

Note: We will install PHP version 8.1, which is latest version in time when this article is written. If you want to install some other version replace 'php8.1' with the version you want, e.g. php7.4

First we need to add package archive for PHP:

sudo add-apt-repository ppa:ondrej/php

After that install PHP with command:

sudo apt install php8.1

If everything goes right you should now have PHP installed on your machine. To test it, run command to see current PHP version and you should see that it's version 8.1.

php -v
Output: PHP 8.1.2 (cli) (built: Jan 24 2022 10:42:33) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.2, Copyright (c) Zend Technologies

Next, we need to install PHP extensions required to run Laravel applications. At time this article is written latest Laravel version is 9 and PHP extensions required are:

  • BCMath PHP Extension
  • Ctype PHP Extension
  • DOM PHP Extension
  • Fileinfo PHP Extension
  • JSON PHP Extension
  • Mbstring PHP Extension
  • OpenSSL PHP Extension
  • PCRE PHP Extension
  • PDO PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension

Some of the extensions are already installed with PHP, but ones it's not we should install manually.

o see extensions installed run command:

php -m

You should get the list of all currently installed extension.

In the next step we will install all PHP extensions that are missing:

sudo apt install php8.1-bcmath php8.1-dom php8.1-mbstring php8.1-xml

We will also install a couple of PHP extensions that are not required for basic Laravel application, but you will probably need them for anything slightly more complicated.

sudo apt install php8.1-curl php8.1-sqlite3 php8.1-xdebug php8.1-redis php8.1-zip

At the end, we need to install extensions for Nginx and MySQL:

sudo apt install php8.1-fpm php8.1-mysql

Next, we should turn on option to display errors in php.ini configuration file. Open that file with Vim text editor and find "display_errors" and "display_startup_errors" and set their values to be "On":

sudo vim /etc/php/8.1/fpm/php.ini
php.ini: ... display_errors = On dispaly_startup_errors= On

As last step for setting up PHP, you should restart PHP service:

sudo service php8.1-fpm restart

Installing Composer

To be able to use Laravel, you need to have a composer installed.

First, go to your home directory:

cd $home

With the next couple of commands, you will download composer installer and install it on your machine.

curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php
HASH=`curl -sS https://composer.github.io/installer.sig`
php -r "if (hash_file('SHA384', '/tmp/composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer

Run command for composer version to check if the composer is successfully installed, you should get information about composer version that is installed on your machine:

composer --version
Output: Composer version 2.1.14 2021-11-30 10:51:43

Installing MySQL

As first step you should install MySQL server:

sudo apt install mysql-server

After MySQL server is successfully installed, you should start a server:

sudo service mysql start

Next, you should configure some security rules. Run command for secure installation and follow given steps:

sudo mysql_secure_installation

After that is finished, log in to MySQL server as root user:

sudo mysql -u root

In the next step, we will create a new user and give him all privileges:

CREATE USER 'your_username'@'localhost' IDENTIFIED BY 'your_password';

If you are getting error that password is not strong enough, and you are sure you want to use a weak password, run this command and after that try to create the user again:

SET GLOBAL validate_password.policy=LOW;

Next, give all permissions to this user:

GRANT ALL PRIVILEGES ON *.* TO 'your_username'@'localhost' WITH GRANT OPTION;

Log out from MySQL server with "exit" command:

exit

Then log in agin but this time with the user you just created:

sudo mysql -u your_username -p

It will ask you for a password, enter the password you choose for the user in previous steps.

When you logged in, create new database:

create database laravel_app;

MySQL server is now ready, and we created new database "laravel_app" that we can use for our Laravel application.

To use the database we just created your environment variables should be:

  • DB_CONNECTION=mysql
  • DB_HOST=127.0.0.1
  • DB_PORT=3306
  • DB_DATABASE=laravel_app
  • DB_USERNAME=your_username
  • DB_PASSWORD=your_password

Installing Nginx

To install Nginx run command:

sudo apt install nginx

That's it, Nginx is installed.

Create Laravel Application

Now when we successfully setup PHP, MySQL and Nginx we can create our Laravel application.

First, create directory at "/var/www" with the chosen name for application:

sudo mkdir /var/www/laravelapp.test

After that change permissions for that directory to have read and write privileges:

sudo chmod -R ugo+rw /var/www/laravelapp.test

Go to the directory of our application and create new Laravel application using a composer:

cd /var/www/laravelapp.test
composer create-project laravel/laravel --prefer-dist .

Next, create file for Nginx configuration at /etc/nginx/sites-available/ with same name as our project directory and write Nginx configuration:

sudo vim /etc/nginx/sites-available/laravelapp.test
/etc/nginx/sites-available/laravelapp.test server { listen 80; listen [::]:80; server_name laravelapp.test www.laravelapp.test; root /var/www/laravelapp.test/public;
add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff";
index 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_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; }
location ~ /\.(?!well-known).* { deny all; } }

Create a symbolic link of configuration file in /etc/nginx/sites-enabled/ directory:

sudo ln -s /etc/nginx/sites-available/laravelapp.test /etc/nginx/sites-enabled

Check if Nginx configuration is ok:

sudo nginx -t
Output: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

If everything is ok, reload Nginx server:

sudo systemctl reload nginx

At the end, add app domain to hosts file:

sudo vim /etc/hosts
/etc/hosts ... 127.0.0.1 laravelapp.test

That's it, if everything is done correctly you should be able to access your Laravel application at http://laravelapp.test

Note: If you get some error with storage or bootstrap directory, just give read and write permissions to that directory

sudo chmod -R ugo+rw /var/www/laravelapp.test/storage

Installing Redis

It's not necessary, but I can highly recommend installing a Redis database also, especially if you plan to use some of the advanced features of Laravel framework, like Queues.

If you don't need or want to use Redis, just skip this section.

First, install Redis server:

sudo apt install redis-server

Next, in configuration file find "supervised" and set it to be "systemd":

sudo vim /etc/redis/redis.conf
redis.conf ... supervised systemd

Restart Redis service:

sudo systemctl restart redis-server.service

Check if status is "Active":

sudo systemctl status redis-server.service

If everything is alright, log in to the Redis server:

redis-cli

To test a server, enter "ping" and you should get "PONG" as response:

ping
Output: PONG

To test if Redis is working correctly, we will set the new variable and try to get it:

set test_variable "This is test variable"
get test_variable
Output: "This is test variable"

Then test if Redis is able to persist data even after it's been stoped. Log out from Redis server, restart server, log in again and try to get test variable we just created.

exit
sudo systemctl restart redis-server
redis-cli
get test_variable
Output: "This is test variable"

Next, we should make some changes in configuration file:

sudo vim /etc/redis/redis.conf

To make sure Redis is available only to our local machine find "bind" and set it to be "127.0.0.1 ::1". It should be like that by default, but if it's not change it.

redis.conf ... bind 127.0.0.1 ::1

Setup a password for Redis database:

redis.conf ... requirepass your_password

Save and close configuration file and restart Redis.

redis.conf ... sudo systemctl restart redis-server.service

To check if a password is setup correctly log in to Redis database and try to set a new key. It should fail because authentication is required.

redis-cli
set new_key "Test new key"
Output: NOAUTH Authentication required.

Authenticate with the password we just set and try again, it should work now.

auth your_password
Output: OK
set new_key "Test new key"
Output: OK
get new_key
Output: "Test new key"

That's it, Redis server is now installed and configured.

To use Redis database your environment variables should be:

  • REDIS_HOST=127.0.0.1
  • REDIS_PASSWORD=your_password
  • REDIS_PORT=6379

Installing MailHog

To test email sending from your application, you can use fake SMTP server like MailHog.

For this package to work, you should have installed "golang" programming language. To install it run command:

sudo apt-get -y install golang-go

After that, get MailHog from official Github repository:

go get github.com/mailhog/MailHog

That's it, MailHog is installed on your machine. Everytime you want to use MailHog just run command:

~/go/bin/MailHog

And your SMTP server will be available at http://localhost:8025

To use MailHog SMTP server to test email sending in your application use this environment variables:

  • MAIL_MAILER=smtp
  • MAIL_HOST=localhost
  • MAIL_PORT=1025
  • MAIL_USERNAME=null
  • MAIL_PASSWORD=null
  • MAIL_ENCRYPTION=null
  • MAIL_FROM_ADDRESS=someaddress@example.com
  • MAIL_FROM_NAME="${APP_NAME}"

Installing Minio

Minio is high performance object storage with API compatible with Amazon S3. It's great option if you want to test a file uploading with Amazon S3 disk.

Get Minio with command:

wget https://dl.min.io/server/minio/release/linux-amd64/minio

Change permissions of the directory to have access permission:

chmod +x minio

That's it, Minio is ready. Everytime you want to use it just run command:

sudo MINIO_ROOT_USER=your_username MINIO_ROOT_PASSWORD=your_password ~/minio server /mnt/data --console-address ":9001"

After that you can use it at http://127.0.0.1:9000 with credentials you choose in previous step.

To use Minio in your application use this environment variables:

  • FILESYSTEM_DRIVER=s3

  • AWS_ACCESS_KEY_ID=your_username
  • AWS_SECRET_ACCESS_KEY=your_password
  • AWS_DEFAULT_REGION=us-east-1
  • AWS_BUCKET=your_bucket
  • AWS_ENDPOINT=http://127.0.0.1:9000
  • AWS_USE_PATH_STYLE_ENDPOINT=true

Installing Ngrok

If you want to share your application with someone, you can create public URL with Ngrok.

First download and install Ngrok:

curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list && sudo apt update && sudo apt install ngrok

In the next step you should go to https://ngrok.com/ and create account. With that account you should be able to get API key.

Authenticate Ngrok with API key you get for your account:

ngrok authtoken your_token

That's it, Ngrok is ready. To share your project, go to the project directory and run command:

ngrok http 80

Or you can expose a project by domain name:

ngrok http -host-header=laravelapp.test 80

Conclusion

You now have working local development server with installed PHP, MySQL, Nginx, MailHog, Minio and Ngrok.

For every new application you need to repeat steps described in Create Laravel Application section. Optionally, if you need to use MySQL database you need to create a new one as it is described here.

Enjoy!