How I setup Codiad web IDE on my Raspberry Pi 3 with Ubuntu Server 15.10.3, Nginx and PHP

There are times when I get the urge to work on project source codes that reside on my Raspberry Pi 3 LEMP server while I am on the move. Setting up a web based IDE on my Raspberry Pi 3 is one way to enable me to code while I am on the move, so long as I have a device with a web browser that is connected to the internet. Since I had already setup a LEMP server to run WordPress on my Raspberry Pi 3 and that Codiad is written in PHP, Codiad is an ideal web based IDE that I can set up on my Raspberry Pi 3.

This post documents how I setup Codiad web IDE on my Raspberry Pi 3. To make this post complete, I had taken some of the steps mentioned in my other posts on Raspberry Pi and replicated it in this post.

Getting the hardware

The hardware that I used for this setup is as follows:

  1. A Raspberry Pi 3 motherboard
  2. A PiBlox LEGO® Compatible Case
  3. A SanDisk Ultra 32GB microSDHC UHS-I Card with Adapter

As my laptop came with a SD card reader, I did not have to get a SD card reader.

Getting the Ubuntu Server 15.10.3 image for my Raspberry Pi 3 onto the micro SD card

After I got the hardware that I needed, the next step was to get the Ubuntu Server 15.10.3 image for my Raspberry Pi 3. The awesome folks at Ubuntu Pi Flavour Maker had made a few variations of Ubuntu images available for me to download.

I downloaded a copy of the Ubuntu Server Standard 15.10.3 image onto my windows machine via torrent.

Once I got the .xz file, I used 7-zip to extract the .img file. I then used Win32 Disk Imager to write the .img file into the SanDisk microSD card via the SD card drive on my laptop.

Booting into Ubuntu Server 15.10.3 on my Raspberry Pi 3

Once Win32 Disk Imager completed writing the Ubuntu Server 15.10.3 image onto my SanDisk microSD card, I removed it from my SD card reader and inserted it to the SD card slot on the Raspberry Pi 3 motherboard. Note that unlike the Raspberry Pi 2, the microSD slot of the Raspberry Pi 3 motherboard is not a spring loaded one. This means that you just push to insert your microSD card and pull to remove your microSD card.

I then attached my trusty mouse, keyboard, monitor, a RJ45 network cable from my DLink router and my old samsung charger to my Raspberry Pi 3 motherboard. After turning on the power, the login screen appears. The default username is 'ubuntu' and the password is 'ubuntu'.

Adding a new user

I do not like a default username for my web server, even though it is not going to be used as the production server. Hence, I first added a new user via the command as follows:

sudo adduser techcoil

I then went through the following Q and As:

Adding user `techcoil' ...
Adding new group `techcoil' (1000) ...
Adding new user `techcoil' (1000) with group `techcoil' ...
Creating home directory `/home/techcoil' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for techcoil
Enter the new value, or press ENTER for the default
	Full Name []: Techcoil
	Room Number []: #1234
	Work Phone []: 12345678
	Home Phone []: 12345678
	Other []: 12345678

After I had created my new user account, I proceeded to add it to the sudo group so that I was able to continue with installing the necessary software:

sudo adduser techcoil sudo

Deleting the default user

Once I had created my user, I proceeded to delete the default user.

I first restarted the server:

sudo reboot

After the server booted up again, I logged in with my new user.

Once I had logged into the server, I typed the following in the terminal to delete the default user:

sudo deluser --remove-home ubuntu

Resizing the file system of my Ubuntu Server 15.10.3 image to utilize the entire microSD card space on my Raspberry Pi 3

By default, the Ubuntu Server 15.10.3 image does not utilize the entire microSD card space on my Raspberry Pi 3.

Therefore, I proceeded on to resize the file system of my Ubuntu Server 15.10.3 image to utilize the entire microSD card space on my Raspberry Pi 3.

Adding swap space to my Ubuntu Server 15.10.3 image

1 GB of ram is not going to be enough to run GitBucket alongside the other pieces that run the WordPress instance on my Raspberry Pi 3. As such, I also went on to add swap space to the Ubuntu Server 15.10.3 image so as to complement the 1GB of ram on my Raspberry Pi 3.

Installing Nginx on my Ubuntu Server 15.10.3

I installed Nginx with the following command:

sudo apt-get install nginx

After the installation had completed, I ran the following command:

curl -0 localhost

And got the following output:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

This output assured me that my Nginx web server was successfully installed.

Installing PHP

As Codiad web IDE is written in PHP, I went on to install the PHP binary and the PHP Fast Process Manager. To do so, I ran the following commands in the terminal:

sudo apt-get install php5 php5-fpm

After the installation had completed, I entered the following command:

sudo systemctl status php5-fpm

And got the following verification:

● php5-fpm.service - The PHP FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php5-fpm.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2016-04-06 12:52:55 UTC; 4min 59s ago
 Main PID: 7300 (php5-fpm)
   Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
   CGroup: /system.slice/php5-fpm.service
           ├─7300 php-fpm: master process (/etc/php5/fpm/php-fpm.conf)
           ├─7302 php-fpm: pool www
           └─7303 php-fpm: pool www

Apr 06 12:52:55 ubuntu-standard systemd[1]: Starting The PHP FastCGI Process....
Apr 06 12:52:55 ubuntu-standard systemd[1]: Started The PHP FastCGI Process ....
Apr 06 12:52:58 ubuntu-standard systemd[1]: Started The PHP FastCGI Process ....
Hint: Some lines were ellipsized, use -l to show in full.

Installing PHP modules that are required by Codiad web IDE

The Codiad web IDE that I had downloaded requires, mbstring, zip and openssl PHP libraries. Since mbstring and zip were not packaged with the PHP binary that I had installed in the previous step, I installed php-mbstring and php-zip by running the following command:

sudo apt-get install php-zip php-mbstring

Downloading the latest copy of Codiad web IDE

At the time of this writing, the latest stable release for Codiad web IDE is v.2.7.5. To download the source code for Codiad v.2.7.5, I ran the following commands in the terminal:

cd /var/www
sudo wget https://github.com/Codiad/Codiad/archive/v.2.7.5.tar.gz
sudo tar -xvzf v.2.7.5.tar.gz
sudo rm v.2.7.5.tar.gz

After the commands had completed, I got the Codiad web IDE source code at /var/www/Codiad-v.2.7.5.

Changing the owner of the /var/www/Codiad-v.2.7.5 directory to www-data

In order for Codiad to work, we will need to give write permissions to the www-data user. Hence, I ran the following command to change the owner of the /var/www/Codiad-v.2.7.5 directory to the www-data user:

sudo chown -R www-data:www-data Codiad-v.2.7.5/

Creating a type A DNS record to point Codiad Web IDE

After I had gotten the prerequisites to run Codiad on my Raspberry Pi 3, I went ahead to create a type A DNS record to point to the Codiad Web IDE instance hosted on my Raspberry Pi 3. To do so, I leverage on Digital Ocean to create a subdomain from one of my existing URL to point to the public IP address that my ISP had given my home router.

Configuring Nginx to serve Codiad web IDE via URL for initial setup

With the type A DNS record created, Digital Ocean's name server will send the web browser the public IP address of my home router, which has a Network Address Translation entry to point to the private IP address of my Raspberry Pi. With that public IP address, the web browser will be able to establish a TCP/IP connection to send HTTP requests over to my Raspberry Pi 3. Each HTTP request that it sends will have the following header:

Host: ide.anexistingurl.com

With this header, I would then need to configure the Nginx server running on my Raspberry Pi 3 to

  1. redirect HTTP requests tagged with Host: ide.anexistingurl.com over to the PHP FPM server.
  2. tell the PHP FPM server to use the PHP codes in /var/www/Codiad-v.2.7.5 to serve the HTTP requests.

To do so, I first ran nano to create a new configuration file inside the /etc/nginx/sites-enabled directory:

sudo nano /etc/nginx/sites-enabled/ide.anexistingurl.com.conf

And populate the /etc/nginx/sites-enabled/ide.anexistingurl.com.conf with the following contents:

server {
	listen   80;
	root /var/www/Codiad-v.2.7.5;
	index index.php index.html;

	server_name ide.anexistingurl.com;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to index.html
		try_files $uri $uri/ /index.html;
	}

	error_page 404 /404.html;

	# redirect server error pages to the static page /50x.html
	error_page 500 502 503 504 /50x.html;
	location = /50x.html {
		root /usr/share/nginx/www;
	}

	# pass the PHP scripts to FastCGI server 
	location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;

                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
	}
}

Configuring a free SSL certificate with Let's Encrypt

A SSL certificate will ensure that the communication between my browser and my Codiad Web IDE server endpoint remain encrypted. And with Let's Encrypt, I was able to create a free SSL certificate with a trusted Certificate Authority. Hence, with Let's Encrypt, I will be able to have secured connections from my browser to my Codiad Web IDE running on my Raspberry Pi 3, without any warnings from my browser that the SSL certificate that it received was not issued by a trusted certificate authority.

Allowing traffic to /.well-known uri path

The /.well-known uri path would be accessed by Let's Encrypt server to validate that I was running the Let's Encrypt client on my Raspberry Pi 3 during the generation of the SSL certificate. Hence, I added the following location block in the previous Nginx configuration:

	location ~ /.well-known {
		allow all;
	}

The addition of the location block resulted in the following Nginx configuration:

server {
	listen   80;
	root /var/www/Codiad-v.2.7.5;
	index index.php index.html;

	server_name ide.anexistingurl.com;

	location ~ /.well-known {
		allow all;
	}

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to index.html
		try_files $uri $uri/ /index.html;
	}

	error_page 404 /404.html;

	# redirect server error pages to the static page /50x.html
	error_page 500 502 503 504 /50x.html;
	location = /50x.html {
		root /usr/share/nginx/www;
	}

	# pass the PHP scripts to FastCGI server 
	location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;

                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
	}
}

I then restarted Nginx to take the configuration changes:

sudo systemctl restart nginx.service

Getting the Let's Encrypt client application to create a free certified SSL certificate and the corresponding private key

With the uri ready for validation, I then proceeded to get the Let's Encrypt client application.

I first installed Git:

sudo apt-add-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git -y

And then use Git to clone a copy of the Let's Encrypt client application onto the local file system of my Raspberry Pi 3:

cd /opt
sudo git clone https://github.com/letsencrypt/letsencrypt.git

After the cloning had completed, I then ran the Let's Encrypt client application:

/opt/letsencrypt/letsencrypt-auto certonly -a webroot --webroot-path=/var/www/Codiad-v.2.7.5 -d ide.anexistingurl.com 

Generating a strong Diffie-Hellman group

I also generated a strong Diffie-Hellman group for Openssl to perform the Diffie-Hellman (DH) key-exchange:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Configuring Nginx to use the Let's Encrypt SSL certificate and private key for serving HTTPS traffic

I opened up /etc/nginx/sites-enabled/ide.anexistingurl.com.conf which I had created earlier:

sudo nano /etc/nginx/sites-enabled/ide.anexistingurl.com.conf

and replaced its contents with the following text:

server {
        listen   80;
        server_name ide.anexistingurl.com;
        return 301 https://$host$request_uri;
}

# For ssl
server {
        ssl on;

        ssl_certificate /etc/letsencrypt/live/ide.anexistingurl.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ide.anexistingurl.com/privkey.pem;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DH$
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security max-age=15768000;
        default_type application/octet-stream;
        listen 443;

        root /var/www/Codiad-v.2.7.5;
        index index.php index.html;

        server_name ide.anexistingurl.com;

        location ~ /.well-known {
                allow all;
        }

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to index.html
                try_files $uri $uri/ /index.html;
        }

        error_page 404 /404.html;

        # redirect server error pages to the static page /50x.html
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
                root /usr/share/nginx/www;
        }

        # pass the PHP scripts to FastCGI server
        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;

                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                # With php5-fpm (or php7-fpm, ie on Ubuntu 16.04):
                fastcgi_pass unix:/var/run/php5-fpm.sock;
        }
}

The first server block would make my Nginx server listen on port 80 for requests reaching ide.anexistingurl.com and redirect all traffic to its HTTPS counterpart.

The second server block would configure my Nginx server to serve SSL traffic on port 443 for ide.anexistingurl.com. In that block, I point my server to the strong Diffie-Hellman group, the Let's Encrypt certified SSL certificate and the private key.

I kept the location block to requests made to the /.well-known prefix so that I could renew my SSL certificate for ide.anexistingurl.com with the Let's Encrypt client application in the future.

With the that, I restarted Nginx to take the configuration changes for my Nginx to serve HTTPS requests for my Codiad Web IDE:

sudo systemctl restart nginx.service

Specifying the directories where Codiad IDE can take as absolute paths for the projects that I want to work on

By default, Codiad IDE only allows absolute path to projects contained in its own source code root directory and /home. Since I want to work on projects that are contained in /var/www, I opened up /var/www/Codiad-v.2.7.5/config.php:

sudo nano /var/www/Codiad-v.2.7.5/config.php

and changed the following line:

define("WHITEPATHS", BASE_PATH . ",/home");

to:

define("WHITEPATHS", BASE_PATH . ",/home,/var/www/");

Completing the initial setup for Codiad

Once my Nginx server had restarted successfully, I used my web browser to access ide.anexistingurl.com and was returned the following screen:

Codiad initial setup screen shot

This screen allowed me to create my first Codiad IDE user with a first project to work on. The directory that I provided in this screen had to be owned by the www-data user; if not, Codiad web IDE will not be able to use that directory to work on the source codes within that directory.

After I had filled in the fields and clicked the install button, I got the following screen to work on the source codes that was contained within the directory that I had supplied in the previous screen:

Codiad project explorer screen shot

In this case, I had supplied the directory where I had placed my Codiad Web IDE as the project that I want to work on.

Buying the Raspberry Pi 3 hardware to host your own Codiad Web IDE

If you do not have the Raspberry Pi 3 hardware mentioned in this post yet, you may want to purchase them from Amazon. Simply click on the button below to add the Raspberry Pi 3 hardware to your cart. You may remove anything that you already have or replace some of the hardware with other hardware.


About Clivant

Clivant a.k.a Chai Heng enjoys composing software and building systems to serve people. He owns techcoil.com and hopes that whatever he had written and built so far had benefited people. All views expressed belongs to him and are not representative of the company that he works/worked for.