Practical Elixir: Home Server

Recently I have been turning to Elixir to solve some personal projects. It is a great general purpose language.

Like a lot of people I am mostly working from home. This involves working over a VPN to access some of the essential services that the client uses. The VPN client infrequently disconnects which is typically only noticed when one of these services become inaccessible.

It would be useful to be notified that this has happened. I found another Elixir project ( that had solved the notification problem but specifically for ex_unit. The trick is to install a CLI notification tool and execute that with appropriate parameters.

Once I had this I could use a simple webclient (HTTPoison) to check that a typical page exists that is only available behind the VPN.

This was wrapped in a specific GenServer that reran the check every minute. Having an Application and a Supervisor allows this to be started using iex -S mix.

This solved the problem but did require an iex session to be running. The next step was to use a Release to create something that could be run in the background. This only needed a simple `mix release`.

At this point I now had a service that can run as a background task. Shutting it down was a little clumsy – I’d need to find the shutdown script or manually kill it. It would be far simpler if there was a web interface so that it can be stopped via this (or a generic curl command).

Adding a trivial web interface was a simple matter of adding cowboy_plug to the application and configuring some routes. This allows the application to be cleanly shutdown using System.stop/0. Wrapping this in a task allows the web request to return a result before the shutdown.

Aside cowboy_plug has recently gained a dependency upon :telemetry, which needs to be added to your extra_applications. This section allows your application to request the optionally started Erlang application be run. Remember in Erlang terminology an application is more like a library rather than the whole project, which is called a release.

Now that I had a project that could do something in the background and notify the user the obvious thing was to make the GenServer more generic so that it can run any job on a schedule. This also allows me to keep the specific endpoints I am hitting outside a public repo.

This is the route that led to writing home_server. It now checks and notifies that the machine can connect to the internet (another intermittent issue) and has a config file that if present will monitor that URL and provide a custom message.

This project is still at an early stage. I plan to improve the config file as the current version is somewhat naive. It also needs a better solution for starting the processes from the config file.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s