Async Conf – An Asynchronous Online Conference

Ever since the world of tech conferences went to shit last year, I’ve not attended any virtual ones. They don’t appeal to me at all. The main reason is that when I attend conferences, it’s to meet up with my fellow attendees, greet old friends, meet new ones, and discuss all manner of topics. Attending talks and workshops is usually a secondary activity, and I typically only attend a handful, generally, those that really interest me. Trying to replicate the in-person format via a virtual event holds no interest to me whatsoever, without that in-person element.

A couple of nights ago, an idea for a different type of virtual conference came to me, one that I might prefer actually to be part of.

Based on the limited (45 votes) feedback I got, it seems a number of folks I know on social media would be interested to be part of such an event, and so I’ve decided to make it happen.


For now, I’m calling it async conf. Firstly, because I can make use of the JavaScript async keyword for the website.

async () => { 
    return "conf" 

Secondly, well, I’m sometimes terrible at naming things. 😞 I’m open to ideas, but I want the name to reflect the asynchronous nature of the conference, and be web technology related.

I also don’t want it to be tied to one specific web technology that I’m involved in, I’d prefer it to be something more open to a wider audience.

Next up is cost. I’m going to need a few pieces to make this happen.

  • A domain – currently, the one I want will cost $20 if I can buy the damn thing.
  • Hosting – I can get away with using one of my own SpinupWP managed servers, but it might be a good idea to at least host the site on its own DigitalOcean instance. I’ll probably need it for at least a month, so $10.
  • A website – it’s going to need to allow member registration as well as the ability to host member restricted content. I could roll something myself with Laravel, but it will probably be easier to use WordPress and something like Paid Memberships Pro. I also happen to know the PMPro folks, and I might be able to swing a free license from them if I need any of their paid add ons.
  • Time zone-based emails – I might have to develop myself, as I’m not sure of any existing WordPress plugin that does this. Basically, attendees need to set their time zone and a time at which they would like to receive the email.
  • Email deliverability – no idea what this might cost, but Mailgun starts at $35 a month for 50 000 emails, and I doubt I would need that much.
  • Video hosting – I have no idea what I’m going to need here. Vimeo’s Pro plan has 20GB of streaming and 1TB of storage. Hopefully, that should be enough, at around $25. The other option is to go with YouTube and use unlisted videos, which might not be a bad idea.
  • Pop up Slack-style messaging platform – I already know how I’m going to handle that.

All in all, that works out to around $100 in costs, less if I use YouTube for the video hosting, but it’s a nice round number. If I charge folks $10 to take part, I need 10 attendees to break even. I don’t want to make any money off this, so if I do make a profit, I’ll either be looking to donate the surplus or use it to sponsor open source development.

I’m also going to need help, both in organizing it, and also finding folks to speak. I think once I’ve managed to purchase the domain, and set up the basic site, a call for organisers and speakers is in order.


WordPress Developer Educator at Delicious Brains

This week I started my new journey as the WordPress Developer Educator at Delicious Brains. I could not be more enthusiastic about where this path will take me.

Why Delicious Brains?

Delicious Brains is a WordPress focused company that not only I admire but they have a solid standing in the WordPress community.

They build, in my opinion, some of the best free and paid developer-focused products for WordPress available.

WP Migrate DB has been my default plugin for exporting a WordPress database since I first started developing for WordPress. While I’ve never needed the Pro version, I’ve heard great things about it from people I trust. In my freelance days, I had the opportunity to build an extension for WP Offload Media (when it was still called Offload to S3) for a Codeable client. The experience of working with their code was a delight.

I also had the opportunity to incorporate some of their development team’s open-source packages into my own client projects.

Every time I’ve had the pleasure to work with their open-source code, it’s been well written, clearly documented, and easy to extend.

SpinupWP, their cloud-based server control panel for WordPress, is an exciting product in the self-hosted WordPress space, which was launched to rave reviews. I recently had the opportunity to finally try it out, and I can completely see why folks love it so much.

I had the privilege to share a beer or two with Brad and a part of the team in Berlin in 2019 and had continued chats with them since then online. They are always super helpful and friendly.

When I shared the news of my joining Delicious Brains privately with a few friends who work in WordPress land, they could not speak more highly of the company. As someone said to me in a private message, “They have a great reputation in the ecosystem.” And it’s true; you will probably find it hard to find anyone who doesn’t like the company, the team, or their products.

Finally, and more importantly, Delicious Brains puts out some of the best developer-focused content on the web. They are one of only a few WordPress developer-focused newsletters I subscribe to and make a point of reading every article they publish.

What is a WordPress Developer Educator?

The easiest way to explain that is to quote from the original job posting:

First, this is not a Technical Writer position. While we can appreciate talented writers who can understand technical concepts and explain them to a non-technical audience, this job is not that.

Our audience is developers, so we need a great writer with lots of experience in advanced web development. Or an advanced web developer who is a great writer and wants to explore development through writing full-time.

As the dedicated writer on our team, you’ll write tutorials, documentation, and marketing copy and help our team with their writing. You’ll also do a little customer support and might even help out with the development of our products and sites from time to time.

But you’re a developer. Why throw it all away to be a writer and educator?

As far back as I can remember, I always wanted to be a writer.

My earliest memories are of writing. I would create mostly fantastic stories based on Roald Dahl’s works or science fiction adventures in worlds I would create in my own imagination. As I grew older, this morphed into jokes, anecdotes, and cartoons that gave me an outlet for my teenage angst and an attempt to make sense of the world around me. 

The writing was not something that I ever saw as a possible career path, and so it remained in the realm of a hobby. I didn’t anticipate how the introduction of the internet would change how we consume information and that creating online content would become such a large part of what we do.

I started blogging in 2009, mostly documenting things I learned as a PHP developer, and as time passed, I found that my love of writing could be beneficial to my job. At several companies, the developers were not big on writing things down, so internal developer documentation efforts suffered. This was before we had tools like phpDocumentor. That meant that I would often champion these internal documentation efforts, from new developer manuals to user-facing documentation. The sentence “Is there documentation for this?” is often something that you would have heard me repeating during a stand-up.

In 2016, when I became a freelance WordPress developer, I discovered something interesting. Not only could the art of writing help generate traffic to my blog, which converted into work, but it was also a way of sharing knowledge with a wider audience. Since discovering that my writing enjoyment could be beneficial to my freelance development journey, I’ve spent the past 4 years doing as much writing as possible. I’m proud to say I have published articles about various WordPress related topics for many online platforms, including WPTavern, the Go blog, Jetpack blog, and Smashing Magazine.

Craig at Castos first shared the Delicious Brains job posting with me more than a year ago now. And as much as I told myself I was happy where I was then, the idea embedded itself into the back of my brain and stayed there, popping up now and then. I never did take the plunge, though.

And then, a series of fortunate events occurred. I’d written a post for WPTavern about getting ready for the upcoming PHP 8 release. Brad from Delicious Brains included it in an email about their plugins being PHP 8 ready. I was amazed that he thought my article was useful to his developer community, and that idea in the back of my brain jumped up and started banging on the inside of my eyeballs. The rest, as the saying goes, is history.

Will you still be building software?

I don’t think I’ll ever stop being a developer, much in the same way that I probably never stopped being a writer. I don’t expect to do much product development in my new position, other than possibly coding examples for the developer-focused content I’ll be working on. I’ll still be taking part in any open source projects I currently contribute to, like WP Notify, or on my hobby side projects, like Dev Dad Jokes. It just won’t be what defines me anymore.

To be honest, I’m quite happy about that.


My freeCodeCamp Article on PHP Error Reporting

Earlier this year I shared my professional goals for 2021. One of those goals was that I wanted to seek out more writing opportunities for other online publications.

While the crux of that goal was to get paid to write more, sometimes an opportunity comes along that is worth more than money.

Sometime in 2019, I saw a Twitter conversation with Quincy Larson, the founder of freeCodeCamp.

If you’ve never heard of freeCodeCamp, they are a nonprofit community that helps you learn to code by building projects for other nonprofits. I’ve followed their story since around 2015, and I was really impressed by their curriculum, the way they teach, how varied the community is, and how much great coding content they put out.

So anyway, back to the Twitter conversation, his interest in PHP articles intrigued me, so I sent Quincy a DM, and we got to chatting about it.

Fast forward to 2021, and I’m happy to say that my first PHP related article on freeCodeCamp has been published:

How to Display PHP Errors and Enable Error Reporting on freeCodeCamp.

My goal here is to introduce a new generation to all the fun things that are possible developing in PHP, while also sharing some useful knowledge bombs along the way. I plan to try and put out at least one PHP related article on freeCodeCamp every month.

If you like the post, please feel free to share it directly from the freeCodeCamp site.


Why I (still) love PHPMyAdmin

Sometime in 2019, I was sitting at a conference, when we could still do such things, listening to the first speaker of the day, while getting some Castos support work wrapped up. Someone behind me tapped me on the shoulder, pointed, and laughed saying “You should be using the command line!” It took me a moment to realise what he was mocking me for. I had phpMyAdmin open.

phpMyAdmin is (from their website) “a free software tool written in PHP, intended to handle the administration of MySQL over the Web.” I honestly don’t recall when I first started using it to manage my MySQL databases, but I’m pretty sure it came installed with Wampserver, which was my first PHP local development environment. 16 years later, and I still use phpMyAdmin to this day, both in my local development environment, and, in some cases, to access production databases.

Authors note: if you choose to use phpMyAdmin in a production environment, make sure you secure it properly. This article isn’t about that, but there is plenty of information on how to secure your phpMyAdmin install in the official documentation.

Security concerns around using PHP software to access your production databases aside, I’ve tried all sorts of applications as replacements for phpMyAdmin, from MySQL Workbench to Navicat, and even the command line, and I still come back to phpMyAdmin like an old, comfortable pair of shoes.

1. It’s Free and Open Source

As someone who supports paying for premium products, the fact that it has remained free and open source for 21 years is quite an amazing feat. It’s probably the longest-running piece of open source PHP software still relevant today.

2. It’s easy to install

It can be installed on any web server that supports PHP, which means probably either Apache or Nginx, with one single command. As it’s a PHP web app with an HTML front end, there are no real requirements other than what you might already have for a regular PHP web app.

3. It’s light weight

It’s a PHP app, so it doesn’t take up any extra memory when it’s being used, other than what it needs to perform the next request. The download is only 13mb in size, and that includes all the different language files.

4. The search functionality is pretty cool

This is about my favourite feature of phpMyAdmin, the fact that it has a search form for each table. Using the form, you can search for any data, across any of the fields, in a table, using any combination of operators, including LIKE queries, in a matter of seconds. In my opinion, it’s the fastest way to lookup data when you need to.

I do use a GUI like MySQLWorkbench, mainly when I need to prepare complex SQL queries or export larger sets of specific data because the PHP memory limits sometimes mean exports via PHPMyAdmin can’t cut it, but for the most straightforward tasks, like data lookups, I’ve not found anything on Linux that beats PHPMyAdmin.


Zero-configuration debugging PHP with Xdebug in PHPStorm on Ubuntu

As with many of my blog posts, this one also started with a Tweet

I’ve been using Xdebug on Ubuntu in PHPStorm for going on 4 years now, and as I’ve been actively blogging about my development set up, I thought for sure I’d written about this. Turns out I had not, and so here we are.

Why Zero-configuration debugging?

To be honest, if you can read the Zero-configuration debugging help doc from PHPStorm, you probably don’t need this article. I think that doc might even be the reason I’ve never blogged about it. It really is the quickest way to get up and running debugging your code inside PHPStorm with Xdebug.

The PHPStorm Zero-configuration debugging process requires almost zero configuration. Install a few tools, turn a few things on, hit refresh in your browser, and you’re step debugging your PHP code.

It might not be as completely integrated into your PHPStorm environment as a fully configured set up, but it quickly gets you into the world of debugging PHP line by line.

A note on local environments. This article covers using either Apache or Nginx installed directly on your Ubuntu machine with PHP, and not running inside any virtual environment. It is possible to use this set up if you are using some form of virtualisation, but that’s a topic for another post.

So let’s dive into the details.

Install Xdebug

The Xdebug installation docs include a detailed list of install commands for a wide range of Linux operating systems. On Ubuntu, since 18.04, it’s as straightforward as running the following command.

sudo apt-get install php-xdebug

The instructions also include how to install a specific version of Xdebug if you’re using a different version of PHP than what is available on your version of Ubuntu’s repositories, like if you’re using Ondřej Surý’s PPA.

A note on versions. Depending on your Ubuntu version, the version of Xdebug in the repository might be out of date. For example on my old 20.04 LTS workstation, the Xdebug version is 2.9.3 for some reason, while on my 20.04 LTS laptop it’s 3.0.1, and the latest version is 3.0.2. It’s recommended to use the latest version available version of Xdebug, but I suggest first getting used to it by using the version available in the Ubuntu repositories, before attempting a manual install to make sure you’re always on the latest and greatest.

Once Xdebug is installed, you need to tell PHP to use it, which requires some additions to your php.ini. First, check where the (“Shared Object”) file is located. This is usually in your /usr/lib/php/ directory, in a directory named after a date (eg 20190902). Inside it you’ll find the file, which you need to configure by adding it to your php.ini.


You also need to enable Xdebug debugging , which depending on your Xdebug version, requires a slightly different php.ini line.

;Xdebug 2.x
;Xdebug 3.x

Then, restart your web server, and check that Xdebug has been enabled.

php --version

You should see something like this, which confirms Xdebug is enabled with PHP.

PHP (cli) (built: Dec 26 2020 10:32:51) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.25, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans

Install one of the Xdebug Browser debugging extensions for your browser

The PHPStorm help docs have a list of all the different popular browsers, and the extension(s) needed for each. Essentially all these extensions do is allow you to set a special GET/POST or COOKIE parameter needed to trigger debugging from a browser request. You could do this yourself manually, but who has time for manual processes?

Set up PHPStorm for debugging

At this point, it’s a good idea to validate the Xdebug configuration within PHPStorm. Open the PHPStorm Settings (File -> Setttings) and browse to Languages and Frameworks -> PHP -> Debug.

Under Pre-configuration, click the Validate link.

Make sure the Path to create validation script is set to the web root for your project, and the URL to validation script points to the local URL that you’d use to browse to your projects web root. Click the Validate button, and you should see a list of validation checks passing.

The last thing you need to do is set PHPStorm to start listening for PHP debug connections from the browser. You can set this from the Run menu in PHPStorm.

Once that’s done, you’re good to go.


You can now start adding breakpoints in your code, by clicking in the grey area next to your line numbers in PHPStorm. The breakpoint appears as a red dot, next to the line you want to start debugging at.

You can then use the browser extension for your browser you installed earlier, to turn debugging on from the browser, which ensures the browser will send the special GET/POST or COOKIE parameter on subsequent requests, and refresh the web page.

If you’ve set it all up right, you should see your browser page sit on a loading screen, while the debug toolbar pops up at the bottom of your PHPStorm window.

Success! You can now step through your code, and debug what it’s doing.

Final note, the first time you trigger a debug session for a site/project, PHPStorm will probably pop up a window detecting an incoming debug connection. It then asks to confirm some details about the connection. Mostly you can leave this as the defaults, but it’s good to just check that everything is set correctly.

I’ve found the zero-configuration debugging set up to be the quickest way to start step debugging on PHPStorm, and I’ve not used anything else in the past 4 years. I especially enjoy how I can enable everything in the IDE, but then just turn on the browser extension, to kick things off, and turn it off again when I don’t need it.

During development I still use things like die() or dd()when I want to quickly see the contents of things, and I’ve started using PsySH via Laravel’s artisan tinker or via WP-CLI more and more to test snippets of code and see their output, but Xdebug is essential when I’m hunting down bugs or hard to replicate edge cases.

If you do end up setting up Xdebug, and you find it useful, please consider supporting the project.


Professional Goals for 2021

Yesterday I posted my personal goals for 2021. During the course of drafting that post, I realised I had some goals that were very specifically relevant to my career as a software developer, and therefore my ability to earn income, and some that were not.

Those that were specific to my career, and either directly or indirectly affect my ability to earn income, are probably the ones that I’m more likely to focus on and complete, so I thought it might be useful to separate the two.

If nothing else it provides me two “recap” posts to write towards the end of the year. ;-D

Test Driven Development

In 2019 and 2020 I made a conscious choice to learn how to write proper test suites for my code. I’m still not an expert, but I’m finally comfortable enough with PHPUnit, the Laravel and WordPress Plugin testing environments, and the CodeCeption testing framework, that I have no more reason not to write tests for all of my code.

In 2021 I want to focus on improving my Test Driven Development (TDD) practice. My goal is two fold; I want to make sure that any new code I write first has tests in place for the expected outcomes, and I want to make sure that any existing code I touch, either already has tests in place, or I add them first, before making any changes.

My developer mantra for 2021 is “testing, testing, testing”.

PHP Certification

I’ve had the Zend PHP Certification on my radar for years now. Last year I purchased the study guide, and so this year I’d like to try and complete the certification. It probably doesn’t mean too much in the general scheme of things, but I’ve already learned a few new bits of information from the first few chapters, and it would be nice to add to my professional credentials.

Learn Python

Python is a general-purpose programming language I’ve wanted to learn better for the past two years. There’s a lot of code out there written in Python, much of it in open source projects I’m interested in, but it also has direct relevance to my position at Castos. I’ve started a few Python courses, so this year I’d like to pick one, finish it, and actually be comfortable hacking on some Python code.

CS50’s Introduction to Computer Science

Back when I studied programming, the college where I completed my diploma advertised that the 2 year diploma course, once completed, would be equivalent to the first two years of a 3 year BSc degree in Computer Science. This meant we could take that final year at university, and complete the degree.

Sadly the college didn’t actually keep up to date with the requirements to allow this, so when I enrolled, I wasn’t able to take that option.

I’d still love to properly learn the fundamentals of a computer science degree. The Harvard CS50’s Introduction to Computer Science course is a great and free way to do this, so I’d like to try and complete it during the course of this year.

This doesn’t have a direct impact on my earning potential, but I do feel the fundamentals I can learn from this will help with in my daily problem solving.

Moar Writing

This is one of the few areas where my personal and professional goals are similar. I thoroughly enjoy writing, possibly sometimes more so than development. 2020 was not a good year for me for professional writing gigs. My freelance writing through Skyword essentially stopped at the end of 2019, and I’ve not had the time to actively write for other online publications. So in 2021, I will be looking for more opportunities for paid writing.

Freelancing Ubuntu

Setting Up a Matrix Server on Ubuntu 20.04 – Part 2

In part 1 of this tutorial, I dived into my reasons for setting up a Matrix Synapse homeserver, and how to set up the basics of the server and it’s required software. In part 2, I’m going to register myself an admin account, log into the server using the online chat client, to verify it’s all working as it should, and migrate the database engine from SQLite to Postgres.

A quick reminder, all server commands are run as the root user.

Register an admin user account

Installing the Matrix Synapse server software also installs a few executables on the server, that can be used for specific tasks. register_new_matrix_user is one such executable, and it allows you to register a new user from the command line of the server.

register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml http://localhost:8008

The process will ask you for a user name, password, and whether to make this user an admin or not.

Once you’ve created the user, you can log in to the homeserver via the Element web client hosted at, or download Element for your operating system, and Sign in from the client.

Either way, to sign in to your server, click on the Change link, next to “Sign in to your Matrix account on”.

Enter the server domain as the homeserver URL and click Next.

Enter your user name and password and click Sign in.

Switch Database Engine

While Matrix Synapse shops with SQLite by default, the official documentation suggests this only for testing purposes or for servers with light workloads. Otherwise, it’s recommended to switch to Postgres, as it provides significant performance improvements due to the superior threading and caching model, and smarter query optimiser, and allows the database to be run on separate hardware.

Install Postgres

First step is to install Postgres on the server.

apt install postgresql postgresql-contrib

We then need to create a user for synapse to use to access the database. We do this by switching to the postgres system user, and running the createuser command

su - postgres
createuser --pwprompt synapse_user

The createuser command will ask you for a password, and create the synapse_user with that password.

Now we can create the database, by logging into the Postgres database server, while operating as the postgres system user.


Once logged in, we can create the database, and assign it to the synapse_user

 OWNER synapse_user;

Then we need to allow the synapse_user to connect to the database. The Postgres docs for Synapse talk about possibly needing to enable password authentication, but I found that by default this was already endabled, so all I had to do was add the relevant file to the pg_hba.conf file. I wasn’t sure how to find the pg_hba.conf file on my system, but this Stack Overflow thread explained what commands I could use when logged into the Postgres database server.

show hba_file;

My pb_hba.conf file was located at /etc/postgresql/12/main/pg_hba.conf.

Towards the bottom of the file, I added the Synapse local connection section to allow the synapse user access to Postgres.

# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all               md5
# Synapse local connection:
host    synapse         synapse_user    ::1/128                 md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all               md5
host    replication     all             ::1/128                 md5

Because line order matters in pg_hba.conf, the Synapse Postgres docs make a point of the fact that the Synapse local connection needs to be just above the IPv6 local connections.

Migrating the SQLite data to the Postgres database

In order for the data to be migrated from the SQLite database to the PostgreSQL database, we need to use the synapse_port_db executable, which requires that the homeserver.yaml file includes the correct server_name. So edit the homeserver.yaml, and set the server_name to your domain name from part 1.

nano /etc/matrix-synapse/homeserver.yaml
server_name: ""

The next step is to make a copy of the homeserver.yaml file, in preparation for the Postgres set up

cp /etc/matrix-synapse/homeserver.yaml /etc/matrix-synapse/homeserver-postgres.yaml

Then, edit the new /etc/matrix-synapse/homeserver-postgres.yaml file, so that the database settings point to the newly created Postgres database.

#  name: sqlite3
#  args:
#    database: /var/lib/matrix-synapse/homeserver.db

  name: psycopg2
    user: synapse_user
    password: dbpassword
    database: synapse
    host: localhost
    cp_min: 5
    cp_max: 10

Make sure that the newly created /etc/matrix-synapse/homeserver-postgres.yaml file is owned by the correct system user.

chown matrix-synapse:nogroup /etc/matrix-synapse/homeserver-postgres.yaml

Next step is to copy the SQLite database, so that we can import from the copy, and give that copy the correct permissions.

cp /var/lib/matrix-synapse/homeserver.db /var/lib/matrix-synapse/homeserver.db.snapshot
chown matrix-synapse:nogroup /var/lib/matrix-synapse/homeserver.db.snapshot

We should then stop the matrix-synapse server, before we run the import.

systemctl stop matrix-synapse

Now we can use the synapse_port_db command to import the data from SQLite to Postgres, using the SQLite snapshot, and the Postgres enabled homeserver-postgres.yaml.

synapse_port_db --curses --sqlite-database homeserver.db.snapshot --postgres-config /etc/matrix-synapse/homeserver-postgres.yaml

Once the import successfully completes, we can backup the current SQLite enabled configuration.

mv /etc/matrix-synapse/homeserver.yaml /etc/matrix-synapse/homeserver-old-sqlite.yaml

Finally, we set the Postgres enabled yaml as the default.

mv /etc/matrix-synapse/homeserver-postgres.yaml /etc/matrix-synapse/homeserver.yaml

At this stage, it’s a good idea to make sure that the new /etc/matrix-synapse/homeserver.yaml file has the right permissions set, and if not, set them correctly.

chown matrix-synapse:nogroup /etc/matrix-synapse/homeserver.yaml

And that’s it, log into your Matrix server via the web client or desktop client, and if you’ve completed the import correctly, everything should be working as before.

That concludes the main set up requirements to have a working Matrix homeserver.

I do however plan to have two follow-up posts. In the first, I’ll dive into some of the quirks of signing into and verifying additional clients, once your initial sign-in has been successful.

For the second, I’ll be adding some testers to the mix, and I’ll document and any configuration changes I’ve needed to make, to get things usable as a community communication platform. This one might take a bit longer, as it relies on other folks testing the platform, giving me feedback, and me tweaking the server until it’s a workable solution.

Freelancing Ubuntu

Setting Up a Matrix Server on Ubuntu 20.04 – Part 1

For about the past six months or so, I’ve been interested in the open, decentralized communications standard called Matrix. In May of this year, it was announced on TechCrunch that Automattic had invested $4.6 million into the company behind the Matrix standard. The company in question, New Vector (now rebranded as Element) also develop an open-source chat client, which is a rival to Slack, that runs on the Matrix standard. This is the part that made me sit up and take notice. Matt Mullenweg is the CEO of Automattic and the co-founder and BDFL for WordPress. His decision to invest in this open-source communications standard, which offers an alternative to Slack, could very well mean that in the near future, both the internal communication at Automattic and that of the WordPress project, could end up running on Matrix.

For some time now, myself and the other admins of the WP South Africa Slack community, have been considering switching away from Slack. The main reason for this is that Slack doesn’t offer an option for open source communities to get any premium plan features, so unless we’re prepared to pay $8 USD per person for our over 1000 members we’re stuck with the free version. It also means we don’t “own” our open source community’s communication channels. If Slack ever dropped the free plan, which could happen, we’d be stuck up the proverbial creek.

I decided it was time I took a look at what it would take to get a Matrix homeserver set up, what the pros and cons would be, and if it would be possible to migrate all our users over to our own homeserver.


In order to set up a Matrix homeserver, I would need a web server instance to host it. Fortunately, I have a Digital Ocean account, so spinning up a new basic VPS droplet with Ubuntu 20.04, 1GB of RAM, 1 vCPU and 25GB of storage at $5 a month was a click of a few buttons. The other requirement was to have a public domain pointing to the IP address of the server. I asked Hugh, who manages the domain, to set up an A record in the DNS to point the subdomain to the new server IP address. You can also use a regular top-level domain (eg but if you already have a domain (for example for your community website), using a subdomain for the Matrix server means not needing to purchase a new one.

Initial set up

A note on commands, I’m running all the commands for this server as the root user. If you have access to your web server via another user with sudo privileges, I suggest switching to the root user, it will just make everything easier.

sudo su

The first step with a new server is to make sure the server software is up to date.

apt update && apt upgrade

Then, I needed to ensure that any package dependencies for the matrix-synapse server software are installed.

apt install lsb-release wget apt-transport-https

While there are official matrix-synapse packages in the Ubuntu repositories, the matrix-synapse docs recommend using their own packages. To do that I first had to enable those packages, by adding the GPG key and the matrix-synapse repository for a Debian/Ubuntu-based system.

wget -qO /usr/share/keyrings/matrix-org-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/matrix-org.list

Once the repository is set up, I can get the latest package updates, which will now include the Matrix ones, and install the matrix-synapse homeserver software.

apt update
apt install matrix-synapse-py3

During the install, I enter the chosen domain (in my case our subdomain) as the server name. I can also choose not to send Anonymous Data Statistics, but that’s entirely up to you.

Once it’s all installed, I start the matrix-synapse server, and enable it to auto-start on system boot.

systemctl start matrix-synapse
systemctl enable matrix-synapse

Configure Matrix Synapse

Firstly, I needed to generate a random string which is used as the Matrix Synapse registration secret. This I did using the following command.

cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1

The server outputs the random key, which I copied and saved somewhere safe for later.


No, this isn’t the key for our Matrix homeserver! 🙂

The next step is to edit the homeserver.yaml configuration file, which is in the /etc/matrix-synapse directory. For this tutorial, I’m using nano, but you can use whatever CLI text editor you prefer.

nano /etc/matrix-synapse/homeserver.yaml

I searched for and changed the registration_shared_secret entry, and used the randomly generated key created earlier. It’s important to note that the key should be enclosed by double-quotes.

registration_shared_secret: "YC9h8djIiCaCinWxkE2zt9cgvXYGX25P"

I then saved and closed the homeserver.yaml file.

Then, I restarted the matrix-synapse service, which will apply the new configuration.

systemctl restart matrix-synapse

Generate SSL

My next step was setting up the webserver software Nginx as a reverse proxy for the Matrix Synapse server. Before I could do that, I needed to generate an SSL certificate, to make sure the traffic to and from the server is secure. This can be accomplished using a LetsEncrypt certificate, for which I need to install certbot.

apt install certbot

Once certbot is installed, I generated the SSL certificate, using my email address, and the subdomain we have pointing to the IP address of the webserver.

certbot certonly --rsa-key-size 2048 --standalone --agree-tos --no-eff-email --email -d

Once this is completed, the SSL certificate and chain were saved at /etc/letsencrypt/live/ and the SSL key file was been saved at /etc/letsencrypt/live/ This information will become useful when I set up Nginx in the next step.

Setup Nginx as a Reverse Proxy

Setting up a reverse proxy allows Matrix clients to connect to your server securely through the default HTTPS port (443) without needing to run Synapse with root privileges. So first I install Nginx.

apt install nginx

Once installed, I create a virtual host file, to manage the incoming connections.

nano /etc/nginx/sites-available/matrix

The virtual host file configuration redirects all traffic from port 80 (HTTP) to port 443 (HTTPS), configures the SSL port with the certificates created earlier, redirects any requests to the /_matrix endpoint on the domain to the Matrix Synpse server, and configures port 8448, which is used by the Matrix Federation APIs to allow Matrix homeservers to communicate with each other.

server {
    listen 80;
    return 301 https://$host$request_uri;

server {
    listen 443 ssl;

    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;

    location /_matrix {
        proxy_pass http://localhost:8008;
        proxy_set_header X-Forwarded-For $remote_addr;
        # Nginx by default only allows file uploads up to 1M in size
        # Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
        client_max_body_size 10M;

# This is used for Matrix Federation
# which is using default TCP port '8448'
server {
    listen 8448 ssl;

    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;

    location / {
        proxy_pass http://localhost:8008;
        proxy_set_header X-Forwarded-For $remote_addr;

Once the file is saved and closed, I can enable the Nginx virtual host, and test to make sure there were no issues.

ln -s /etc/nginx/sites-available/matrix /etc/nginx/sites-enabled/
nginx -t

Finally, I restart Nginx, and enable it to start at system boot.

systemctl restart nginx
systemctl enable nginx

UFW Firewall

With the basics set up, it would now be a good idea to add some firewall rules, to ensure the rest of the server ports are locked down. I add the ssh, http, https, and the TCP port ‘8448’ to the UFW firewall using the command below.

for svc in ssh http https 8448
ufw allow $svc

After the rules are added, I enable the firewall and check the firewall rules, using these two commands.

ufw enable
ufw status numbered

At this point, I usually log into the server via SSH in a new terminal just to be sure I’ve not locked myself out of SSH access.

Test the Matrix Synapse homeserver

If everything is set up correctly, at this point you should be able to browse to the below URL, enter the server domain, and check if a successful call can be made to your homeserver.

If you see Success message, congratulations! You’ve successfully set up your Matrix Synapse server. However, there’s still more to be done, which we will dive into in part 2 of this tutorial.

Development Experiences Freelancing Ubuntu

ASUS Zenbook 15 UX533FD review – an Ubuntu friendly developer laptop

I’ve always been a fan of Dell laptops. While often a little more pricey than their counterparts, their laptops are usually well built, typically run Ubuntu without any hassles, and Dell have great after sales service. My last two laptops where Dell.

I’d been eyeing the Dell XPS 15 for about a year, and I had planned to purchase one when I was due for an upgrade. However, sometime back in 2017, someone I follow on Twitter suggested something I had not thought of, the Asus Zenbook range.

Now as a PC gamer, Asus is a well known brand. The produce some of the best PC gaming hardware around. In recent years they’ve switched to more integrated hardware, from tablets (my first Android tablet was an Asus) and more recently to laptops. So I was curious to see how the Zenbook range compared to the Dell XPS range.

The first thing that struck me was the wide range of ZenBook Series laptops available. After some extensive research, I eventually settled on the Asus Zenbook 15 UX533FD.

General impressions

I’ve been using this laptop for almost a year now, and I’m very happy with it. It boots fast, runs all my applications without any problems, and is super light and easy to carry around. Whenever I’m working in it, it never gets hot, and I hardly hear the cooling fans spinning up, so it’s super quiet as well. It has a average of 10 hours battery life if I’m using it for development all day, and an added bonus is that it looks really good, with the Royal Blue finish. You can read more about the tech specs here, but it has everything I need in terms of connections. Finally, the charging cable is also small and light, so when it’s in my laptop backpack I hardly even notice it’s there.

Cost Effective

I always prefer to limit myself to a specific budget, this time around, no more then ZAR25 000. I also tend to have specific minimum hardware requirements when it comes to a work laptop, preferring a decent Intel Core i7 CPU, at least 16GB of RAM and a 512 GB SSD hard drive. I’m not too worried about getting the latest and greatest of the Intel chips, nor do I need a 4k or touch enabled screen. I’m also not concerned about super powerful graphics or the number of additional ports it has, I just need at least one or two USB ports and an HDMI port.

Based on these specifics the Asus Zenbook was the clear winner, being available within my budget at ZAR7000 less than a Dell XPS, configured with almost exactly the same hardware.

Ubuntu friendly

Whether it comes pre-installed with Windows Home or Pro does not really matter to me, as long as I can install Ubuntu on it without any problems. At first I had some issues with getting Ubuntu installed, but after a bit of research online I discovered that updating the laptop firmware to the latest version would resolve any issues. I also decided to install the most recent Ubuntu version, which usually contains the most recent kernel updates and therefore less hardware compatibility issues. The base OS install was a breeze and I didn’t need to jump through any hacky workarounds to get certain things working. I’ve since successfully upgraded the OS to the recent LTS release (20.04), again with very few issues.


I’ll be the first to admit that I know nothing about performance benchmarks, so all I did was find a benchmarking tool on Ubuntu that would give me some scores to compare. Hardinfo seemed to be a solid option, so I ran the benchmark suite on the laptop and compared it to my AMD Ryzen powered workstation.

I was pleased to discover that not only were many of the benchmarks pretty close, but a few of them were better on the laptop, mostly in CPU related tests. I honestly can’t say I can tell the difference when I’m working on my laptop vs the workstation, except when it comes to graphics intensive applications, like games.

CPU Blowfish (lower is better)0.971.05
CPU CryptoHash (higher is better)1284.821058.34
CPU Fibonacci (lower is better)0.550.39
CPU N-Queens (lower is better)5.124.80
CPU Zlib (higher is better)2.351.46
FPU FFT (lower is better)0.800.65
FPU Raytracing (lower is better)2.561.13
GPU Drawing (higher is better)16462.808428.99

I’ve since had quite a few online interactions with other developers who’ve also discovered the joy of the Zenbook range.

So if you’re looking for a small, powerful, good looking, well priced, Ubuntu friendly laptop, you won’t go wrong with an Asus Zenbook.


Show me your WFH set up

Since we’re all currently in the middle of probably the biggest global crisis since World War 2, many folks in my social timeline are posting/sharing their work from home (WFH) pictures. Whenever I share mine, I always feel like I need to explain the tidiness of it all, because my workspace is one area in my life where I do try to keep things in place.

This picture was literally taken at the end of my morning session of work, during my first coffee break. I left the plate and the coffee cup in the picture to prove it.

Besides a few extra items on the desk (that are only here because I’m currently working from home, my battery powered screwdriver, two remotes needed for this office, my running headphones, a few charging adapters, and some extra batteries) this is how I prefer to keep my area of work at all times. I can’t abide an untidy work area, as any clutter that gathers up gets in my way and makes me less productive.

While the space around me not be as tidy (either my office, or currently the garage) I try to keep my desk as a bastion of clarity, almost like it’s a safe haven amongst the madness that is every day life.

What about you, are you a fellow ‘desk neat freak’ or do you feel your workspace should be as comfortable and/or chaotic as your life is. Hit me up in the comments, ideally with pictures, if you’d like to share.