Ambrose's profile


Learning about systems that scale, occasionally taking apart (physical and digital) things. Currently serving NS under the CyberNSF scheme, until 2022.

Infrastructure 2017: Router Setup

After getting the hardware and installing embedded pfSense to a flash drive is configuration. My initial intention was to have my servers and home network (which guests use) on separate VLANs. However, I quickly realised that enabling VLANs caused poorer network performance, so I went back to a single network and used static DHCP allocations.

But I was still getting lower than 500Mbps speeds. My CPU was running at a 100%. While messing with settings, I found an odd solution: Enabling PowerD in System > Advanced > Miscellaneous. With it enabled, I could finally get close-to-gigabit speeds on wired clients!

My guess would be that PowerD allowed the CPU to run at higher clock rates.

After using this machine for a few days, I'm satisfied at the performance it delivers, for only $120 SGD! I'd recommend this to you for building a home server or router as a low-cost, low-power setup.

The case for this PC is not rackmounted, so I created a small shelf using a slab of wood and L brackets

Infrastructure 2017: Router Hardware

October last year, I switched my routing to a virtual machine running pfSense, in the hopes of having better control over my home network. Turns out, many hiccups have occurred since the move. Issues with OpenVPN (which I have since disabled), Linux bridges being reassigned after software updates and other seemingly random issues. The virtual network card also caused a reduction in maximum throughput, saturating at 200Mbps instead of the 800Mpbs previously on the RT-N56U.

Since then, I've also been wanting to make the switch from services (like this blog and GitLab) running in user accounts and virtual machines to containers. Containers are isolated environments for processes to run in, providing the isolation of a virtual machine with close to native performance.

So here's the start to a series on the upgrade of our infrastructure to a new setup powered by containers! I'll also be documenting progress and code on GitHub.

To start off the upgrade, I needed a better router (because my sibl

Linux & Bash: Reverse proxying a webapp

In this blog post we will be setting up nginx to reverse proxy your webapp. You'll need nginx set up, and your webapp running and listening on a known port.

Let's edit the default site. Here's the default configuration, with less comments:

sudo nano /etc/nginx/sites-enabled/default
server {

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.php index.html index.htm index.nginx-debian.html;

    server_name _;
    include hhvm.conf;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ /index.php?$args;


Reverse proxying in nginx is using the directive (configuration option) proxy_pass. The documentation describes the syntax as:

Syntax: proxy_pass URL;
Context: location, if in location, limit_except

The context is the blocks that the directive can be used in. The location block specifies location-specific directives. An example

Linux & Bash: Running a webapp

In this blog post we will be setting up a systemd unit for our webapp. systemd helps manage background system services and mount points. A systemd unit is a definition for that service. systemd also can do dependency management.

There are many types of units in systemd, but I will go through the most relevant unit, the service unit.

Service units define how to start, stop and reload the process, when to restart the process in the case of an error, dependencies the service requires to have started, and many other options.

Take a look at the manual page for systemd service unit files:

man systemd.service

Unit files are placed in /etc/systemd/system/, and there are three main sections [Unit], [Install] and [Service].

[Unit] defines information about the unit that is independent of the type of unit. This includes things like description, dependencies. This is an example from MariaDB:

# /lib/systemd/system/mariadb.service
# ...

Description=MariaDB database server

Linux & Bash: Getting Wordpress

Now that we have nginx, HHVM and MariaDB installed, we can get into installing Wordpress! Wordpress is a comprehensive blogging platform and content management system (CMS) written in PHP. (This blog runs on Ghost, which is good if you're only blogging.) If you're building a content-driven website, Wordpress is something to consider.

As mentioned in the previous posts, HHVM and nginx gives us a faster-performing PHP webserver, as compared to a default LAMP installation. With some more effort, HHVM and nginx can be tuned even further for better performance, but that's an article for another day.

Wordpress is known for it's ease of installation. First, let's download Wordpress:

cd ~  # Enter into our home directory
wget  # Download the file at the URL 

Now, let's unzip the archive.

user@hostname:~$ unzip 
The program 'unzip' is currently not installed. You can install it by typing:
sudo apt install unzip

Whoops, the program unzip is not insta

Linux & Bash: Installing MariaDB

In this blog post we will be installing MariaDB, continuing off the previous blog post where we installed HHVM and nginx. MariaDB is a fork of MySQL dedicated to keep MariaDB open. It is fully compatible with MySQL, except for the introduction of extra features.

MariaDB, like HHVM, is available in an external repository.

sudo apt-key adv --recv-keys --keyserver hkp:// 0xF1656F24C74CD1D8
sudo add-apt-repository "deb $(lsb_release -sc) main"

As mentioned in the previous article, this imports public keys that are used to sign the packages published in the repository, and then adds the repository to the list of repositories for Ubuntu to look up.

sudo apt update
sudo apt install mariadb-server

During the installation, the command will prompt you to set the password for the root database user. Set one and remember it. DigitalOcean has an article on changing it if you lost access as the root use

Linux & Bash: Running PHP

In this blog post I'll guide you through installing HHVM (HipHop VM) to run Hack/PHP on a web server. I'll be using Nignx and Debian/Ubuntu. HHVM requires a 64-bit operating system, so be sure to download the 64-bit edition of Ubuntu.

Firstly, install nignx. nginx is a high-performance web server and load balancer. You will be using the load balancing feature in a future article, but for now, nginx will help to serve your static files (typically CSS and JS) and pass your dynamic files (PHP files, in this case) to HHVM to process.

sudo apt install nginx

Here, you are using Ubuntu's package manager apt to install the package nginx. You can search for packages on the command line by doing apt search <query>.

To ensure nginx starts on bootup, you need to enable it.

sudo systemctl enable nginx
sudo systemctl start nginx

The second program starts nginx immediately, thus you do not need to reboot right now.

You can visit http://localhost/ to check if nginx is installed and started:


Linux & Bash: Git hosting with SSH

In this blog post, I'll guide you through setting up a Git remote repository in a Linux server. This guide assumes that you have SSH set up, and understand the basics of Git.

Git remotes are just minimal Git repositories without the working tree. The working tree enables you to edit the files within the repository, while the actual revision history is hidden in the .git folder. Minimal Git repositories, formally called bare repositories, are created as so:

mkdir ~/magician.git
cd ~/magician.git
git init --bare

You can have a look at the contents of the bare repository:

user@hostname:~/magician.git$ ls
HEAD        description info        refs
config      hooks       objects

Bare repositories are useless on their own. You have to clone them to make them useful:

cd ~
git clone ~/magician.git
cd magician

Now you can make changes to your repository. For now let's just create the file hello-world.txt:

touch hello-world.txt
git add hello-world.txt
git commit -m "Added first file"

Linux & Bash: Getting SSHed

In this blog post I'll go through the basics of using SSH.

SSH stands for Secure Shell. It is a "cryptographic network protocol for operating network services securely over an unsecured network." Wikipedia It is modernly used to connect to Linux servers for management and occasionally used by programs for secure connections between machines.

SSH is a service that runs on Linux. Most Linux distributions don't come with SSH installed by default. You can install it in Ubuntu with the following command:

sudo apt intall openssh-server
sudo systemctl enable ssh # ensures starts on boot
sudo systemctl start ssh

Now that SSH is up, we can try SSHing into our Linux system from another machine on the same network. If the machine is a physical one, you need to obtain the local IP address of the machine. If it's virtual, you can either port forward it or obtain the local IP address of the virtual interface.


The most common SSH client for windows is PuTTY. You can get it by visit

Linux & Bash: VirtualBox port forwarding

In this blog post, I'll guide you through port-forwarding services in VirtualBox to access services like SSH and Nginx from your host. It's pretty simple.

Open up the settings to your virtual machine.

Go to "Network".

Expand the advanced settings.

Click on the "Port Forwarding" button.

Add an entry.

Give the entry a name. Let's set up SSH port forwarding first.

The host port can be any number from 1 to 65535. I'm prefixing the guest port with 10 to get my host port. They can also be the same port numbers, but it may conflict with ports open on your host machine. Leave the other fields as-is.

We should also forward the HTTP port.

Now, any incoming connection to your host machine would be forwarded to your guest machine. For example, if your virtual machine has Nginx or Apache installed and listening on the default port 80, you can access the website on your host machine by visiting http://localhost:1080/

Screenshot the web in any size

Here's a quick tip to grab screenshots of your website or webapp in any size.

Open Chrome DevTools, and find the "Device Toolbar" button.

This opens up a really useful tool for responsive web design. Set the screen size you want to capture. You might want to do some math for 16:10.

Now click on the menu and capture that screen!

Awesome! Thanks, Google Chrome!

The MakerForce Show #1

The MakerForce Show is a podcast recorded, produced and edited by MakerForce. We talk about ideas, hardware, software and occasionally interview friends.

Download: MP3 or OGG (RSS)

#1: The Beginning of the End

Trump just won. We go thorugh our experience at IDEA Hacks, and then mention Android's market share, last week's MacBook release, USB Type-C, touch, X, chips angled at not 45°, self-driving, electric cars and public transport.

Intro music: ZigZag by KevinMacLeod