Modified to bring instructions up to date for latest version of the Rasbian OS - released June 2018
A few years ago I setup a Raspberry Pi 2 Model B as a development web server. I took note of the steps involved and over the ensuing months, I've provided those notes to individuals on our Gitter chat looking to do the same thing. I recently purchased the latest Raspberry Pi 3 Model B which has the same form-factor, but has a faster 1.2Ghz quad core processor, built-in WIFI, and Bluetooth 4.1. I thought I would take this opportunity to update my notes, and turn them into a full blown tutorial as this seems to be a popular subject.
In this tutorial, we cover the basics to get Raspbian OS running on your Raspberry Pi computer. We will install the high-performance nginx 1.9 webserver, along with PHP 7.0 for optimal performance. We'll also cover installing the latest Netatalk 3 with spotlight support for easy file sharing with your Mac. So read on dear listener if you would like to discover the joy of building your own full linux-powered server on a $35 computer!
Initial Raspbian Installation
Raspbian is the best option for operating systems on the Raspberry Pi because it's the most supported and is based on Debian, a very popular Linux distribution. Those of you that have used Debian or Ubuntu will be very much at home with Raspbian. The current version called Rasbian Buster is equivalent to the latest Debian 9 release.
Rather than rehashing all the information available, I suggest you follow the installation procedures outlined on the Raspberry Pi site and install NOOBS onto an SD card. After you have created your bootable NOOBS installer, you can insert it in your Raspberry Pi and power it on. It will boot very quickly and then you can simply pick Raspbian from the installer and let it do it's thing.
When the installation is complete, you should be greeted by a clean desktop environment. Time to get some things setup and configured!
Raspbian Updates
Throughout this tutorial, I'm going to assume you are using a terminal so if you have not already done so, start up a terminal by clicking the terminal icon from the top menu bar of the desktop and it will launch a terminal instance for you.
Even though you just installed Raspbian, there are often updates to packages available so the first thing to do is make sure you are running the latest versions. Follow these steps:
$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get upgrade
You probably won't have any extra updates to perform after the dist-upgrade
step, but better safe than sorry!
Raspbian Configuration
We can use the RASPI Config command to setup some important configuration options for our new Pi.
$ sudo raspi-config
Read the official docs for full details, but I like to set the following:
- Change Password - pick a new unique password (default is
raspberry
) - Boot Option - I like to select
console
as I don't use the desktop at all - Interfacding Options - Enable SSH to allow remote access
- Internationalisation Options - Change Locale to suite (I use
en_US.UTF-8
), Change Timezone toUTC
(why?)
Choose your Editor
By default Raspbian comes with the GNU Nano Editor. It's a very capable editor and is great for newbies because it has on-screen help for commands. However, I've been a Vi kind of guy for many years, and just feel more comfortable using that. Vi has been around for years, and Vim is a new and improved version that is easily installable on Raspbian:
$ sudo apt-get install vim
Throughtout this guide I commonly will have vi
commands for editing files. You can simply replace this with nano
if you wish to use the default editor.
Changing the default Hostname
By default, Raspbian installs with the hostname raspberry
. If you wish to change this to something more memorable, you just need to edit this value and then restart the hostname service:
$ sudo vi /etc/hosts
$ sudo vi /etc/hostname
$ sudo /etc/init.d/hostname.sh
Accessing Remotely
It's all well and good to use your new Raspberry Pi machine via the keyboard and monitor you have plugged into it, but it's much easier to simply access it remotely from your regular desktop. To do this your best friend is SSH (Secure Shell). In order to reach your Raspberry Pi, you will need to know the IP address. To do so simply type:
$ hostname -I
This will report the current IP address of the machine.
On your regular computer, you can simply create a /etc/hosts
entry with this IP and a suitable name. Usually this should match the hostname you just set. Then you can access your Pi remotely via:
$ ssh pi@raspberry
Enter the password you set in the configuration step, or if you have not set the password yet, it will be raspberry
. More details can be found in the docs.
It is strongly advised to use SSH Keys rather than passwords. There is a great tutorial on how to set up Passwordless SSH Access in the offical docs.
Updating Firmware (Optional)
Your Raspbian installation also included a pretty recent copy of the Raspberry Pi firmware. However, sometimes there are important updates, so it really doesn't hurt to update this to the latest version:
$ sudo rpi-update
$ sudo reboot
Change the Shell (Optional)
By default, Raspbian ships with the very capable bash shell. However, I personally prefer zsh which has many useful features. On top of this I like to use Oh My ZSH! which is a handy ZSH configuration tool that comes packed with custom plugins, themes, etc.
To install this just follow these steps:
$ sudo apt-get install zsh git
$ wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh
$ chsh -s `which zsh`
Then simply log out and back in to see your new shell in all it's glory! I like to change the theme to nice clean multi-line version. To do so simply edit the ~/.zshrc
file and change the theme to one of the many supported themes (My personal favroite is the dst
theme).
Install PHP 7.2
Raspbian being based on Debian Stretch ships with PHP 7.0 by default. This works fine, but there is a new and better supported PHP 7.2 release available. Released in November of 2017, PHP 7.2 is the current latest released version of PHP, and will be supported until November 2019 with security updates until November 2020.
As with most PHP-centric projects, Grav commonly sees 2X performance increases when running under PHP 7.2 (compared to PHP 5.6) and that combined with the reduction in memory, makes it an ideal candidate for the Raspberry Pi.
To install this newer PHP version however, we must tap into the testing branch of Raspbian, commonly known by the codename buster. We must credit a new buster.list
file used by Aptitude (apt-get
):
$ sudo vi /etc/apt/sources.list.d/10-buster.list
Add this line:
deb http://mirrordirector.raspbian.org/raspbian/ buster main contrib non-free rpi
Now, by adding this and referencing -t buster
in our apt-get
commands, it wil use the newer versions of files available in the buster release which is not considered 100% stable. To facilitate this we need to create a buster preferences file:
$ sudo vi /etc/apt/preferences.d/10-buster
And paste in the follwing:
Package: *
Pin: release n=stretch
Pin-Priority: 900
Package: *
Pin: release n=buster
Pin-Priority: 750
Save this file and update:
$ sudo apt-get update
You can see which release versions are available with which priority by using sudo apt-cache policy
. You can also see specific versions of packages with sudo apt-cache policy <package_name>
Now you are ready to install PHP 7.2 from the buster release including all the common PHP packages:
$ sudo apt-get install -t buster php7.2 php7.2-curl php7.2-gd php7.2-fpm php7.2-cli php7.2-opcache php7.2-mbstring php7.2-xml php7.2-zip
After this has been completed, you can quickly test to make sure things have been installed by simply typing:
$ php -v
PHP 7.2.9-1 (cli) (built: Aug 19 2018 06:56:13) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.9-1, Copyright (c) 1999-2018, by Zend Technologies
Installation of nginx 1.13
While it's trivial to install nginx 1.10 with Raspbian, we want to use a faster, more up to date, and secure version of nginx here, and luckily there's a nginx 1.13 version available in the buster release.
$ sudo apt-get install -t buster nginx
You can easily see what version would install by simulating an install: sudo apt-get install -t buster -s <packagename>
Once fully installed (accept any defaults when prompted), we should now tweak our PHP 7.2 FPM pool to be better optimized:
$ sudo vi /etc/php/7.2/fpm/conf.d/90-pi-custom.ini
And add:
cgi.fix_pathinfo=0
upload_max_filesize=64m
post_max_size=64m
max_execution_time=600
Now, we want to modify our PHP 7.2 FPM pool to use our pi
user and group, so edit the config file:
$ sudo vi /etc/php/7.2/fpm/pool.d/www.conf
And and change the user and group references:
user = pi
group = pi
Next we want to create a new nginx configuration for our grav
test site:
$ sudo vi /etc/nginx/sites-available/grav
In this file paste:
server {
#listen 80;
index index.html index.php;
## Begin - Server Info
root /home/pi/www/grav;
server_name localhost;
## End - Server Info
## Begin - Index
# for subfolders, simply adjust:
# `location /subfolder {`
# and the rewrite to use `/subfolder/index.php`
location / {
try_files $uri $uri/ /index.php?$query_string;
}
## End - Index
## Begin - PHP
location ~ \.php$ {
# Choose either a socket or TCP/IP address
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
# fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
## End - PHP
## Begin - Security
# deny all direct access for these folders
location ~* /(.git|cache|bin|logs|backups|tests)/.*$ { return 403; }
# deny running scripts inside core system folders
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny running scripts inside user folder
location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny access to specific files in the root folder
location ~ /(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) { return 403; }
## End - Security
}
Now we need to ensure the default
site is not loaded and we load this new grav
site instead:
$ cd /etc/nginx/sites-enabled/
$ sudo rm default
$ sudo ln -s ../sites-available/grav
Then simply restart nginx and php-fpm to ensure the new changes are picked up:
$ sudo service nginx restart
$ sudo service php7.2-fpm restart
Installing Grav
The nginx configuration is expecting our Grav site to be located in /home/pi/www/grav
, so now we need to create that folder structure:
$ cd ~;mkdir www;cd www
Then download Grav release package you wish to install. We are going to use the Blog Skeleton in our example, but you can use any release package or skeleton:
$ wget https://getgrav.org/download/skeletons/blog-site/latest -O grav-blog.zip
$ unzip grav-blog.zip
$ mv grav-skeleton-blog-site grav
Adjust the naming of the these files to reflect the Grav release package or skeleton you are using
At this point, and if you followed all the steps properly, you should be able to point your browser at your Raspberry Pi with either the IP or the hostname you setup in your /etc/hosts
file. For example: http://raspberry
.
Problems?
If you have a problem reaching the webserver, there are a few things to check:
- You have a symbolic link called
grav
in your/etc/nginx/sites-enabled
folder - The
grav
file looks correct and matches the example pasted above - If you receive a 'Bad Gateway' error, then check to ensure the
/var/run/php/php7.2-fpm.sock
file exists and is referenced correctly in the/etc/nginx/sites-available/grav
file.
Advanced - Install PHP 7.2 APCu + Yaml
A couple of useful PHP packages that can inmprove performance are not available in the regular repositories, but they can be installed using PECL.
To accomplish this we first need to install PECL, then update the PECL repo data:
$ sudo apt-get install php7.2-dev
$ sudo pecl channel-update pecl.php.net
APCu
To install APCu, simply run this command:
$ sudo pecl install apcu
If you get an error during this process regarding Archive\Tar.php
you can fix this by editing the file and editing the line provided in the error that looks like this:
$v_att_list = & func_get_args();
with this:
$v_att_list = func_get_args();
Then run the PECL command again.
To add APCu to the PHP configuration you need to edit the php.ini
file:
sudo vi /etc/php/7.2/fpm/php.ini
And add an entry under the [PHP]
block at the top of the file:
extension=apcu.so
Then restart php-fpm
with:
$ sudo service php7.2-fpm restart
YAML
This one is also pretty easy simple to install:
$ sudo apt-get install libyaml-dev
$ sudo pecl install yaml
To add Yaml to the PHP configuration you need to edit the php.ini
file:
sudo vi /etc/php/7.2/fpm/php.ini
And add an entry under the [PHP]
block at the top of the file:
extension=yaml.so
Then restart php-fpm
with:
$ sudo service php7.2-fpm restart
Advanced - Install Netatalk 3 (Optional)
Now you have a 100% functional Linux server that is perfect for web development. However, it's more convenient to be able to access your new server with a shared network folder from your main development machine. If you are using a Mac like I am, then you are going to want to install Netatalk 3 which is a Linux implementation of the Apple AFP network protocol. The problem however, is that by default Raspbian (even the buster release) only provides a very old version that doesn't work well with modern versions of OS X.
If you are using a Windows machine, you will need to install Samba rather than Netatalk, but this is a pretty straightforward process that has been documented elsewhere.
The solution is to download the source of the latest Netatalk 3 server software, and build it for your Raspbery Pi. Perform the following steps:
$ sudo apt-get install -t buster build-essential libevent-dev libssl-dev libgcrypt-dev libkrb5-dev libpam0g-dev libwrap0-dev libdb-dev libtdb-dev libmariadbclient-dev avahi-daemon libavahi-client-dev libacl1-dev libldap2-dev libcrack2-dev systemtap-sdt-dev libdbus-1-dev libdbus-glib-1-dev libglib2.0-dev libio-socket-inet6-perl tracker libtracker-sparql-1.0-dev libtracker-miner-1.0-dev
$ cd ~;mkdir src;cd src
$ wget https://downloads.sourceforge.net/project/netatalk/netatalk/3.1.11/netatalk-3.1.11.tar.bz2
$ tar -xvf netatalk-3.1.11.tar.bz2; cd netatalk-3.1.11
$ ./configure \
--with-init-style=debian-systemd \
--without-libevent \
--without-tdb \
--with-cracklib \
--enable-krbV-uam \
--with-pam-confdir=/etc/pam.d \
--with-dbus-daemon=/usr/bin/dbus-daemon \
--with-dbus-sysconf-dir=/etc/dbus-1/system.d \
--with-tracker-pkgconfig-version=1.0
$ make
$ sudo make install
Assuming everying built correctly you need to edit the configuration file:
$ sudo vi /usr/local/etc/afp.conf
Modify the existing file with the following content:
;
; Netatalk 3.x configuration file
;
[Global]
; Global server settings
[Homes]
basedir regex = /home
; [My AFP Volume]
; path = /path/to/volume
After this point you should be good to go to restart the service:
$ sudo service netatalk restart
Now you should see your server show up in the sidebar of Finder. Simply connect with your pi
user and password.
FYI, you can validate that things are setup correctly by typing:
$ sudo /usr/local/sbin/afpd -V
You should see output similar to the following:
afpd 3.1.11 - Apple Filing Protocol (AFP) daemon of Netatalk
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version. Please see the file COPYING for further information and details.
afpd has been compiled with support for these features:
AFP versions: 2.2 3.0 3.1 3.2 3.3 3.4
CNID backends: dbd last tdb mysql
Zeroconf support: Avahi
TCP wrappers support: Yes
Quota support: Yes
Admin group support: Yes
Valid shell checks: Yes
cracklib support: Yes
EA support: ad | sys
ACL support: Yes
LDAP support: Yes
D-Bus support: Yes
Spotlight support: Yes
DTrace probes: Yes
afp.conf: /usr/local/etc/afp.conf
extmap.conf: /usr/local/etc/extmap.conf
state directory: /usr/local/var/netatalk/
afp_signature.conf: /usr/local/var/netatalk/afp_signature.conf
afp_voluuid.conf: /usr/local/var/netatalk/afp_voluuid.conf
UAM search path: /usr/local/lib/netatalk//
Server messages path: /usr/local/var/netatalk/msg/