Running a Linux Web Server on an Android device
Summary
With the GnuRoot program, it's possible to run a linux operating system on Android without "rooting" the device. With this ability, servers like Sinatra, Rails, Node, etc. can run webapps on localhost. With the help of a NPM library called localtunnel, it's possible to expose the local server to the broader internet.
Step 1: Make sure there is available hard drive space
There should be at least 1GB of available hard drive space to store the Linux OS. It is also possible to install to an SD card, but I didn't try it because the performance is inferior.
Step 2: Install GnuRoot Debian
Download GnuRoot Debian on the play store. It's a 60 MB download.
Step 3: Install Linux
Open the program and click "install/reinstall". This will compile and install the Linux operating system. Once the installation is finished, the GnuRoot program will close.
Note on some buggy UI stuff
Note that the GnuRoot app has a little bug where the terminal window doesn't show up after it's been backgrounded and re-opened. When re-opening the app after backgrounding it, get back to the terminal by pressing the back button. If the installation screen is just black (empty), that means the installation is complete
Step 4: Setup Linux environment
Open the GnuRoot app, and switch to the "launch" tab. Click "launch" to start the terminal.
The first thing you should run is
apt-get update
This updates the package list, which is needed to install programs.
It's probably a good idea to also run apt-get upgrade at this point, which will make sure the OS is up-to-date with the last fetched package list.
Next,
apt-get install build-essential
This installs tools for the C language and is required to install many other programs.
Installing is easy enough. Run
apt-get install ruby ruby-dev
This sets up the ruby, irb, and gem commands.
Next, install Sinatra, which is the simple web server I'll use. Optionally run
echo "gem: --no-document" >> .gemrc
to prevent gems from installing documentation (which takes forever). Install Sinatra with
gem install sinatra
Next install NodeJs with
apt-get install nodejs
One might alternatively use a PPA for this, but for simplicity's sake this tutorial just uses the standard package. Some libraries will expect a binary called node, but on linux it is actually called nodejs. To preempt these errors, run
ln -s /usr/bin/nodejs /usr/bin/node
Which will let node be used as an alias for nodejs.
Next, install NPM, the package manager for Node, with
apt-get intall npm
Finally, install localtunnel with
npm install -g localtunnel
Step 5: Write & run web server
Start by writing instructions for a simple webserver. Run
echo "require 'sinatra'; get('/') { 'hello world' }" >> app.rb
Run the web server with ruby app.rb &. The ampersand will background the process.
Run the localtunnel listener with lt --port 4567. After a few seconds, a url will be printed. Enter this url in any web browser to see "hello world" as a response.
Caveats
There is an issue with firewall and localtunnel. It only works for a few minutes. But then it exits with an error. See this thread for more info.