Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save BillyNate/d56745f1c282e77a8f46f4a5fb008fc8 to your computer and use it in GitHub Desktop.

Select an option

Save BillyNate/d56745f1c282e77a8f46f4a5fb008fc8 to your computer and use it in GitHub Desktop.

Portable Headless Wi-Fi Raspberry Pi LAMP Web Server

Here's documented how a portable headless webserver could be made out of a Raspberry Pi. This guide has been made in case the setup needs to be redone, for whatever reason. It is written for Raspbian Jessie Lite, but should work for any Raspbian. Other ditros might need different commands and/or different file locations.

This guide describes how to set up a Raspberry Pi as a webserver (Apache with PHP and MariaDB/MySQL) which you can attach to any network without the need of a display (ever) nor a network cable. It also contains steps to set up a Samba share (to easily access the web server files from a work station), set up X11 (to get graphical interfaces on your workstation of applications running on the Pi) and make the Pi easily discoverable on the network by its hostname, including subdomains (to host multiple websites on the Pi).

The following hardware is assumed:

  • Raspberry Pi
  • Wi-Fi (Pi3 or USB)
  • Power
  • (Micro) SD-Card
  • Windows computer capable of writing an (Micro) SD-Card

A network cable is not necessary, but could speed up the process.

Some keywords are used in this guide:

  • Pi: the Raspberry Pi that will be set up
  • workstation: a windows computer
  • device: a device, a smartphone for example, that can set up a hotspot
0. Preparing the workstation
  1. Install this software (each optional, depending on how/what will be set op)
  • Paragon ExtFS: Either install this, or attach the Pi to a network cable
  • Xming: For the X11, Xming is an X11 server for windows
  • Putty: To SSH to the Pi. Not needed ff you're not going to use X11 and got Git already installed on the workstation (contains SSH.exe).
  • USB Image tool or any other tool to write an image to the (Micro) SD-card
  1. Download a Raspbian image onto your pc (I used the latest Raspbian Lite from raspberrypi.org)

  2. Write the Raspbian image to an (Micro) SD-card

  3. Either connect your Pi to a network cable, or when ExtFS is installed:

  4. Two disks will appear, one for boot and one contains the OS files

  5. Open up etc/wpa_supplicant/wpa_supplicant.conf in a text editor (can be found on the card on the OS partition)

  6. Add the following to the bottom of the file:

     network={
       ssid="name-of-your-hotspot"
       psk="password-of-the-hotspot"
     }
    
1. Set up the Pi
  1. Move the SD-card to the Pi
  2. Boot the Pi and check if it connects (some devices show when a device connects, otherwise check the appropriate file (/data/misc/dhcp/dnsmasq.leases on Android) for devices leasing an IP
  3. Connect to the Pi (using Putty or ssh pi@ip-address). Default user/pass: pi/raspberry
  4. Run sudo iwlist wlan0 scan to see all networks found by the Pi
  5. Pick a network from the list and add it to /etc/wpa_supplicant/wpa_supplicant.conf by adding another network=... entry The order of the networks is used by the Pi. So if you've got your hotspot on frequently, you might want this on the end of the list
  6. Shutdown your hotspot and the Pi will connect to the new network entry
  7. Find the new IP of the Pi and reconnect
  8. Run sudo raspi-config and
  • Expand the filesystem
  • Check and (if needed) correct the timezone settings
  • Change the user password
  • In advanced options set a unique hostname (and remember it)
  1. Like always on a fresh Pi, run sudo apt-get update and sudo apt-get upgrade
  2. Optionally install Screen apt-get install screen. If you use a screen for running commands and a sudden connection failure appears, you can resume your session once reconnected. This can save you from some nasty experiences (like a connection failure in the middle of a apt-get upgrade).
2. Install Web server
  1. Install Apache2, PHP7.0 and MariaDB: sudo apt-get install apache2 php7.0 libapache2-mod-php7.0 mariadb-server mariadb-client php7.0-mysql optionally add one or more of php7.0-mbstring, php7.0-mcrypt, php7.0-intl, php7.0-curl, php7.0-gd, php-imagick, php7.0-json, php7.0-imap, php-memcache, php7.0-pspell, php7.0-recode, php7.0-sqlite3, php7.0-tidy, php7.0-xmlrpc, php7.0-xsl, php-gettext, php-pear

If PHP7 can't be found by apt, you'll have to go through these steps first:

  1. Add an additional source to apt-get: edit /etc/apt/sources.list by adding the following at the end of the file:

     deb http://repozytorium.mati75.eu/raspbian jessie-backports main contrib non-free
     #deb-src http://repozytorium.mati75.eu/raspbian jessie-backports main contrib non-free
    
  2. Run these commands to add the certificates:

    sudo gpg --keyserver pgpkeys.mit.edu --recv-key CCD91D6111A06851
    sudo gpg --armor --export CCD91D6111A06851 | sudo apt-key add -
    
  3. And sudo apt-get update

  4. During installation you will be asked to set a MariaDB root password

  5. Test PHP: php -v should output the version of the installed PHP

  6. Test Apache: In your browser go to the http://ip-of-pi. An Apache page should be served

  7. Edit file /var/www/html/info.php (should be empty, because it doesn't exist yet) and add <?php phpinfo();. Save & exit

  8. Test PHP in Apache: In your browser go to the http://hostname/info.php. An PHP information page should be served this time

  9. Test MariaDB mysql -u root -p

  10. Go to /var/www and run sudo chown -R www-data:www-data ./

3. Install Samba
  1. Install Samba sudo apt-get install samba. Installing samba server allows windows clients to lookup the IP address by hostname

  2. Set a password for your user in Samba: sudo smbpasswd -a <username>, we didn't change the username, so it should be pi

  3. Edit /etc/samba/smb.conf, and add the following to the end of the file:

     [www]
     path = /var/www
     valid users = pi
     read only = no
     force user = www-data
     force group = www-data
    
  4. Restart Samba: sudo service smbd restart

  5. Now open up an explorer window on your local device and go to \\HOSTNAME\www. HOSTNAME is the hostname you've set on the pi and the login credentials are the same as the pi user

  6. Open Putty, enter the hostname of the Pi, (optionally prepend pi@)

4. Install GIT
  1. Install GIT: sudo apt-get install git
  2. Make sure user pi has permissions: sudo usermod -a -G www-data pi
5. Set up X11 forwarding
  1. In Putty enable X11 forwarding in Connection -> SSH -> X11 and set the display location to localhost:0. In Session enter a name for the session, Save and connect
  2. Install GIT tools to be X11 forwarded: sudo apt-get install gitk git-gui kdiff3
  3. Set KDiff3 as diff/merge tool: git config --global merge.tool kdiff3 & git config --global diff.tool kdiff3
  4. You'll now be able to easily connect and use X11 GUI applications like gitk, git citool, git difftool and git mergetool
6. Add GIT aware prompt
  1. Add a git aware prompt for more easy use of git:
  • download the needed script:

        mkdir ~/.bash
        cd ~/.bash
        git clone git://github.com/jimeh/git-aware-prompt.git
    
  • add the following to the top of ~/.bashrc:

        export GITAWAREPROMPT=~/.bash/git-aware-prompt
        source "${GITAWAREPROMPT}/main.sh"
    
  • search for PS1= in ~/.bashrc and comment out the two lines. Below each line add these lines respectively:

        PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] \[$txtcyn\]$git_branch\[$txtred\]$git_dirty\[$txtrst\]\$ '
        PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w \[$txtcyn\]$git_branch\[$txtred\]$git_dirty\[$txtrst\]\$ '
    
7. Make subdomains accessible
  1. Install and configure DNS to catch subdomains:

  2. Install DNSMasq: sudo apt-get install dnsmasq

  3. Create an empty file /etc/dnsmasq.d/HOSTNAME (replace HOSTNAME for your hostname) and sudo chmod 766 the file

  4. Create a file /etc/network/if-up.d/dnsmasq and enter this script:

     #!/bin/sh
     
     sh /usr/local/sbin/set_ip_in_dnsmasq > /dev/null 2>&1 &
     wpa_cli -B -a /usr/local/sbin/wpa2dnsmasq
    
  5. Create another file /usr/local/sbin/set_ip_in_dnsmasq:

     #!/bin/sh
     
     IP=$(/bin/hostname -I)
     
     while [ -z $IP ]
     do
             sleep 1
             IP=$(/bin/hostname -I)
     done
     
     CN=`echo $IP | cut -d . -f 1,2`
     
     while [ "$CN" = "169.254" ]
     do
             sleep 1
             IP=$(/bin/hostname -I)
             CN=`echo $IP | cut -d . -f 1,2`
     done
     
     echo "address=/.HOSTNAME.local/${IP}" > /etc/dnsmasq.d/HOSTNAME
     sudo invoke-rc.d dnsmasq restart
    
Replace the instances of `HOSTNAME` (only the uppercase ones) for your hostname
  1. And another file /usr/local/sbin/wpa2dnsmasq:

     #!/bin/bash
     
     case "$2" in
         CONNECTED)
             echo "Connected on $(date +"%D %I:%M") " >> /var/log/wpa2dnsmasq.log
             sh /usr/local/sbin/set_ip_in_dnsmasq > /dev/null 2>&1
             ;;
         DISCONNECTED)
             echo "Disconnected on $(date +"%D %I:%M") " >> /var/log/wpa2dnsmasq.log
             ;;
     esac
    
  2. Edit /etc/nsswitch.conf where it says hosts remove [NOTFOUND=return] from that line

  3. Configure Apache to serve for subdomains:

  4. Create a new file /etc/apache2/sites-available/HOSTNAME.local.conf:

     <VirtualHost *:80>
       ServerName HOSTNAME.local
       ServerAlias *.HOSTNAME.local
     
       # This will be the wildcarded document root. Any folder you create in /var/www$
       VirtualDocumentRoot /var/www/%-3
     
       <Directory />
         Options FollowSymLinks
         AllowOverride All
       </Directory>
     </VirtualHost>
    
Again, replace the instances of `HOSTNAME` (only the uppercase ones) for your hostname
  1. Enable the vhosts module: sudo a2enmod vhost_alias

  2. Add the new vhost conf: sudo a2ensite HOSTNAME.com.conf

  3. Restart Apache: sudo service apache2 restart

  4. Configure workstation to use the Pi DNS:

  5. Create two files on the workstation: - .set-wifi-dns-to-dhcp.bat

         @echo off
         netsh interface ip set dns "Wi-Fi" dhcp
    
- `.set-wifi-dns-to-hostname.bat`

          @echo off
          cls
        
          ipconfig /flushdns
          
          for /f "tokens=1,2 delims=[]" %%A in ('ping HOSTNAME ^| find "Pinging"') do set ipaddress=%%B
          
          IF [%ipaddress%] == [] GOTO TheEnd
          
          netsh interface ipv4 add dnsserver "Wi-Fi" address=%ipaddress% index=1
          netsh interface ipv4 add dnsserver "Wi-Fi" address=8.8.8.8 index=2
          
          :TheEnd

Replace `HOSTNAME` for your Pi's hostname
  1. Add two tasks to the Task Schedular both containing a trigger on Log: Microsoft-Windows-NetworkProfile/Operational and source NetworkProfile, - one on Event ID 10000 with an action to start .set-wifi-dns-to-hostname.bat - and one on Event ID 10001 with an action to start .set-wifi-dns-to-dhcp.bat
You'll want to check the preset setting of the tasks as well to make sure they'll run as intended
8. Some tweaks
  • Putty can automaticly run some commands once connected. For example cd /var/www ; screen -Rd will change the directory to the folder containing the websites and re-attach the last Screen session. Saving you time and effort on commands you'll run everytime anyway
@BillyNate
Copy link
Author

Would be a great improvement to have the Pi create an access point, connect your device to it and select a network from a GUI.

Something like this: https://planb.nicecupoftea.org/2016/03/20/wifi-connect-quick-wifi-access-point-to-tell-a-raspberry-pi-about-a-wifi-network/

@BillyNate
Copy link
Author

Might want to add Watchdog, Firewall and Fail2ban like http://blog.self.li/post/63281257339/raspberry-pi-part-1-basic-setup-without-cables does

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment