Running Laravel on FreeBSD 10

Initial Setup

I'm gonna be using Vultr.com for the hosting, as they are cheap and of solid quality,
If you decide you want to use them and it's your first time registering, I'd appreciate it if you use my affiliate link on signup.

I'm creating a 1GB FreeBSD 10.4 x64 server for this demo, feel free to choose what suits your app.

After creating the server, when it finishes booting up, let's ssh into it using the root user

ssh root@server-ip-address

Let's create a new user to use later on when we administer the system since doing everything with the root user is not a so good idea,

# adduser

A # prompt indicates that I'm running the command as root, a $ prompt means I'm running command as a user

FreeBSD now will ask us a few questions regarding the new user, let's break them down

username: this is the name the system will use to identify this user, it's stash in my case.
full name: self explanatory
uid: leave it alone
login group: this will be the same as your username, also just press enter
invite username into other groups: type wheel, this will add the user to the root-access-having users
login class: leave it
shell: choose one if you prefer one, I'll go with tcsh
home directory: default is great
home directory permissions: also default is great
use password-based authentication: press enter to choose the default yes
Use an empty password?: no
Use a random password?: no
enter password: type something cool here
enter password again: same as above
Lock out the account after creation?: enter

it will then list the options you chose and ask you ok?

if you type yes, it'll print a success message and ask you if you want to add another user.

if you type no, FreeBSD will ignore the user and ask you if you want to add another user, you can start over if you missed up!

when done, FreeBSD will Goodbye! you ;)

Installing Packages

We want to install the following packages,
nginx to serve our sites, mariadb for the database server, php to process our requests, git to pull our codebase, and optionally node and npm, let's get going.

# pkg install nginx
# pkg install mariadb101-server
# pkg install php71 php71-mysqli php71-gd php71-curl php71-zlib php71-hash php71-tokenizer php71-mbstring php71-pdo php71-phar php71-json php71-filter php71-iconv php71-openssl php71-zlib php71-zip php71-mbstring php71-dom php71-xml php71-session php71-pdo_mysql php71-ctype php71-xmlwriter
# pkg install git
# pkg install node
# pkg install npm

Notice that every line from above is a separate command.

if you're coming from Linux, you'll be used to sudo, now, by default, FreeBSD doesn't ship with the program sudo, so we'll install it now and configure it to allow our user root privileges.

# pkg install sudo

Note that the sudoers file is to be edited from the root account and using the visudo program only.

# visudo

Go down to where you see root "ALL=(ALL) ALL", duplicate that line (pressing yy, then p), and change the username from root to the user you created earlier. stash in my case.

stash ALL=(ALL) ALL

save and quit by hitting escape key then :wq

Before logging out of root, let's add our user to the www group to avoid having to logout and login again.

# pw groupmod www -m stash

verify that our user is added by running (replace "stash" with your username)

# id stash

you should see www at the end of the groups list.

Next up is composer, log out from the root user, and log back in with the user you created,

ssh username@server-ip-address

run this command to download composer in the home directory of your user, we'll copy it after that to a global location

$ cd ~ && curl -s http://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/

then we'll add an alias to **~/.cshrc** to use composer by typing composer instead of composer.phar

$ vi ~/.cshrc

and add this line after the bunch of aliases at the start of the file

alias composer composer.phar

of course, we need to source the file for changes to take effect

$ source ~/.cshrc

lastly, confirm everything was done okkay by typing composer, you should see composer kick in.

Configuring Packages

First off, let's make our services start at server boot

$ sudo sysrc nginx_enable=yes mysql_enable=yes php_fpm_enable=yes

PHP

php installation serves with two example config files, we'll copy the production one and rename it to php.ini

$ sudo cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

open ~/usr/local/etc/php.ini using vi or your preferred editor, uncomment this line (remove the ; at the beginning of line) and change its value to be 0

cgi.fix_pathinfo=0

this will prevent php from trying to be a smart-ass and find the nearest php file to execute if the requested one doesn't exists
now we'll need to make php run as the user and group www, we'll also use the same user for nginx for security.
then add these to the beginning of the file, right after the first [PHP]

listen.owner = www
listen.group = www
listen.mode = 0660

MYSQL

We'll start by starting the mysql server and then we'll run the mysql_secure_installation program

$ sudo service mysql-server start
$ sudo mysql_secure_installation

just follow the wizard, first when asked about root password just hit enter, enter a password for the root account, confirm password, and then accept all the defaults that follow. done.

PROJECT

We need to create a folder for our project, own it to www:www, give write permissions for the group, and since we're already a part of that group we can edit files without running into permission issues.

the following commands will do those things in order * create empty folder called demo * clone an empty laravel 5.6 project into it * own the folder for user www and group www * add write permissions to group * change directory to project folder * install dependencies * copy example .env file * generate an app key for Laravel

$ cd /usr/local/www/ && sudo mkdir demo
$ sudo git clone https://[email protected]/Stash_Yazan/laravel-56-fresh.git demo
$ sudo chown -R www:www demo/
$ sudo chmod -R g+w demo/
$ cd demo/
$ composer install
$ cp .env.example .env
$ php artisan key:generate

NGINX

Okay next, let's configure nginx, we need two log files, one for access log and the other for error log, let's touch both

$ sudo touch /var/log/nginx/error.log
$ sudo touch /var/log/nginx/access.log

replace your current /usr/local/etc/nginx/nginx.conf content to be same as this

user www;
worker_processes 1;
 
error_log /var/log/nginx/error.log info;
 
events {
worker_connections 1024;
}
 
http {
include mime.types;
default_type application/octet-stream;
 
access_log /var/log/nginx/access.log;
 
sendfile on;
 
keepalive_timeout 65;
 
include /usr/local/etc/nginx/sites/*.conf;
}

there's a few things worth noting here * user www: same user as we used in php and project owner * error_log: this is the file we touched earlier to prevent permissions issues * access_log: this is the file we touched earlier to prevent permissions issues * include: we're including any file that ends with .conf in the sites folder (we'll create this now), adding more sites will be a matter of adding a .conf file in this folder

now create the folder and create a .conf file for our project

$ sudo mkdir /usr/local/etc/nginx/sites
$ sudo vi /usr/local/etc/nginx/sites/demo.conf

and this to be the demo.conf content

server {
listen 80 default_server;
server_name _;
 
root /usr/local/www/demo/public;
index index.php index.html index.htm;
 
location / {
try_files $uri /index.php?$args;
}
 
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
}

note that we're marking this server as the default project to respond if the request came to our server without specifying a host.

lastly, let's restart our stack and make a test.

$ sudo service mysql restart
$ sudo service php-fpm restart
$ sudo service nginx restart

now, if we visit our server's IP address we should see the welcome page of Laravel.

This was just the tip of the berg but it should be enough to get you going. feel free to hit me up, if you face any issues or have any questions. <[email protected]>