RaspberryPi Webserver
RaspberryPi Webserver
So its a good candidate for a webserver, either as part of your home automation system, or just for
experimentation.
This post describes how I configured a Raspberry Pi using a light-weight web server application.
I'll start by discussing the principle before moving on to describe how I did it.
In the beginning
Although the RaspberryPi was developed to meet the needs of young people, and jump-start the next
generation of Computer Scientists, to me its just a technical playground.
Do I need a web server hanging on the internet?
I don't know. But I'd like to experiment with one, just for the hell of it!
I also have this woolly notion that I might like to be able to touch my Android phone and turn the lights on
and off in our bird box...from anywhere in the world!
The plan is to build a Raspberry Pi web server and connect it to our home network.
With the Pi web server linked up like this:-
...I can access my personal web pages simply by pointing the browser on my laptop or phone to the web
servers local IP address and port number.
So assuming my Raspberry Pi has an IP address of: 192.168.0.77 and I've used port 9080 for the web server,
I point the browser at: http://192.168.0.77:9080/ to view the default page.
But if I want to access my web server from outside the relative safety of my local network, I'll need to punch
another hole in my firewall like this:-
Pi web server: internet access
...which I can do by re-configuring my router, allowing me to access my web server using my internet IP
address + port: http://123.45.67.89:9080/
I think I should be able to safely remote into my Pi via the local network using VNC or RDP. But to safely
remote into my Pi from the internet, I need to use SSH and open up a second port (22) to the outside world.
How to configure
I started with a new Raspbian install and entered:-
sudo raspi-config
Note: all commands like this one, in this font are entered in the terminal
I didn't change the default user (pi) but I did change to a complicated (safer) password. I also enabled SSH,
changed the host name (...well I don't want 6 Pi computers called raspberrypi) and made the usual hash-up
of trying to select the correct keyboard & locale.
At some point I updated/upgraded the software and did a firmware upgrade:-
sudo apt-get update
sudo apt-get upgrade
sudo rpi-update
As this system will be headless once the initial configuration has been completed, I also added RDP so I can
use a GUI interface in addition to SSH:-
sudo apt-get install xrdp
The next step is to install the light-weight webserver lighttpd (a.k.a. Lighty):-
sudo apt-get install lighttpd
The server-side scripting language PHP looks like fun, so I've installed that too:-
sudo apt-get install php5-common php5-cgi php5
The fastcgi-php module should be enabled to allow the webserver to handle PHP:-
sudo lighty-enable-mod fastcgi-php
You should see a message about enabling changes, so do this:-
sudo service lighttpd force-reload
Your new web directory /var/www is currently owned by root, so change owner and group to www-data:-
sudo chown www-data:www-data /var/www
You want to be able to edit web files as user "pi" so add the pi user to the www-data group:-
sudo usermod -a -G www-data pi
Now you just need read-write-execute permissions:-
sudo chmod ug=rwx /var/www
So if you are following this, you are almost ready to access the default web page locally by using a suitable
LAN address.
The final step is to tell the web server which port to use. I also wanted a second web-site, so I created a new
folder on the Pi: /var/www/sec, and in the lighttpd config file: /etc/lighttpd/lighttpd.conf I added a few extra
lines:-
server.document-root = "/var/www"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www-data"
server.groupname = "www-data"
server.port = 9080
$SERVER["socket"]==":9090"{
server.document-root = "/var/www/sec"
}
...so now, after a system reboot, I can access the primary site as:-
http://192.168.0.77:9080/
...where I can see the default home page...
...and the secondary site as:-
http://192.168.0.77:9090/
Headless access
As mentioned, I have installed xrdp so that I can remote access the Pi using Remmina on Linux as a
graphical session (or if you must use Windows, you can use Remote Desktop Connection).
I think this should be safe, but DO check this out for yourself. I can only remote-in this way over the local
network, not via the internet.
I thought it might not be safe to enable any folder shares, so I cannot move files between the Pi and my
laptop over my network.
However, by using SSH (secure shell) and SCP (secure copy) I can safely transfer files and also remotely
access the Pi locally or via the internet. (Again, on Windows use can use Putty and pscp.exe).
1. adding a Custom Service to the Services table (i.e specify Type=TCP, port number=9080 & giving it
a name or ID)
2. include this "Inbound Service" in the Firewall Rule list (specifying service id & Pi local IP address).
3. repeating this process for the second port (9090)
4. if you need SSH access over the internet, open port 22 using the same approach
1. ask your ISP for a static IP address (this is not the best approach)
2. sign up to a DNS service. I haven't used one, but Duck DNS is free and seems to have a good
reputation.
Conclusion
Well, it's a start. In a subsequent post, I will discuss how to create a WebSocket using Tornado, which
should give near-real-time two way communication between my Android phone and RaspberryPi.
I copied some code from the net and gave it a try, but unfortunately it didn't want to play.
I built a fresh web server by installing Lighttpd and PHP as described in this earlier post. My new server can only be
accessed on my personal network, and this is by using a browser on another networked computer.
The RaspberryPi web server IP is (in my case) 192.168.0.22 and I've set the lighttpd port to 9080. So the url:
192.168.0.22:9080/ takes me to the /var/www folder on the web server.
In order to communicate with the GPIO I also installed Gordon Henderson's wiringPi as covered in this post.
My php test program (which I've added to /var/www) is called gpio_test.php and looks like this:-
It basically reads the current output level (or status) of GPIO pin 7, and tries to invert it (e.g. toggle "0" to "1" or "1"
to "0"). So each time I refresh the page in the web browser, I should see the output change state.
I haven't actually bothered to connect a light to pin 7, and it doesn't matter which GPIO pin I choose for this test.
When this is run by remotely entering: 192.168.0.22:9080/gpio_test.php in a web browser, I get this simple black on
white page:-
The program returns an error code each time it tries to read the state of GPIO Pin 7. Error code 127 is "command not
found" and this is happening because the user account does not have permission to access the GPIO.
By adding "sudo" to each of the execute commands like this:-
...where the error code = 0 (no error) and each time I refresh the page, the output state/level changes.
However, it is not a great solution to allow the user www-data to run anything with root permissions. I need to find
the location of the program "gpio" then restrict www-data accordingly.
I can find the path for gpio by using the "whereis" command in a terminal like this:-
whereis gpio
...which returns:-
gpio: /usr/local/bin/gpio
So back in the sudoers file I modify the previously entered line to:-
...and now user www-data has elevated permissions to control the gpio function, but nothing else.
What next?
The next step is to build a useful (or maybe just an interesting) application.