Latest Blog Posts

KTOR WAR hosting on Jetty9 using an NGINX proxy

This tutorial will guide you through creating an example KTOR project which will be hosted with Jetty9 and uses NGINX as a proxy which points a domain to the jetty9 server.

The project

To start this of we'll create a project using the KTOR project generator:

https://start.ktor.io/

For the purposes of this tutorial we'll be creating a project for 'example.com' which is the default for the project generator. The only change we'll make for this tutorial is setting the engine to Jetty (under 'Adjust project settings')

For this to work as a web package we'll need to make a few adjustments to the project:

New file: /src/main/webapp/WEB-INF/web.xml

This is the deployment descriptor file, it was taken directly from the KTOR documentation

<?xml version="1.0" encoding="ISO-8859-1" ?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <servlet>
        <display-name>KtorServlet</display-name>
        <servlet-name>KtorServlet</servlet-name>
        <servlet-class>io.ktor.server.servlet.ServletApplicationEngine</servlet-class>
        <init-param>
            <param-name>io.ktor.ktor.config</param-name>
            <param-value>application.conf</param-value>
        </init-param>
        <async-supported>true</async-supported>
    </servlet>

    <servlet-mapping>
        <servlet-name>KtorServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

Edit file: /src/main/kotlin/com/example/Application.kt

Let's create a new method for the webapp which doors everything the embedded server does but without starting the embedded server. We move all the existing functionality into another function and call that from both the embedded server and the web applet.

fun main() {
    embeddedServer(Jetty, port = 8080, host = "0.0.0.0") {
        start(this)
    }.start(wait = true)
}
/**
 * For running via WAR
 */

fun Application.module() {
    start(this)
}

fun start(app: Application)
{
    app.configureRouting()
    app.configureTemplating()
    app.configureMonitoring()
    app.configureHTTP()
    app.configureSecurity()
    app.registerUserRoutes()
}

New file: /src/main/resources/application.conf

This file is required for running as a webapp, it tells jetty what function it needs to run and in which file to find it.

ktor {
    application {
        modules = [ com.example.ApplicationKt.module ]
    }
}

Edit file: /build.gradle.kts Finally we add the war element into the plugins section of build gradle

plugins {
    application
    ...
    id ("war")
}

Now we can build the war file with the following command:

gradle :main war

This will build a war file in the build directory. We can copy that to the server, in this example we'll be storing the war file at:

/var/www/vhosts/example.war

The server

First off let's install the packages we need:

sudo apt-get install default-jre nginx jetty9

Jetty runs on port 8080 by default and uses XML to define the separate Web apps it's serving. Let's create the following new file:

sudo nano /usr/share/jetty9/webapps/example.xml

With the following contents:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="contextPath">/</Set>
  <Set name="war">/var/www/vhosts/example.war</Set>
  <Set name="virtualHosts">
    <Array type="java.lang.String">
      <Item>example.com</Item>
    </Array>
  </Set>
</Configure>

This file tells jetty to listen to the domain example.com and point any traffic to the location of our war file. The war file can go anywhere but I've decided to go with /var/www/vhosts/. It's also worth noting that the virtualHosts child group is an array allowing you to easily have multiple (sub)domains pointing to the same war file.

We now reload jetty to pick up the new file:

sudo service jetty9 force-reload

Now Jetty is ready, let's set up an Nginx proxy to take any incoming traffic on port 80 and point it to jetty on port 8080:

**New file: /etc/nginx/site-available/example.com

server {
    listen 80;

    server_name example.com;

    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;

        proxy_pass http://127.0.0.1:8080/;
        proxy_redirect     off;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }

    if ($request_uri = /index.php) {
        return 301 $scheme://$host;
    }
}

Now let's enable the site, we do this with a simple symbolic link from the available site directory to the enabled site directory. This means if something goes wrong, we only need to remove the link while we fix things instead of trying to fix a live configuration file:

cd /etc/nginx/sites/enabled
sudo ln -s ../sites-available/example.com

It's good practice to test the configuration before reloading it:

sudo nginx -t

If everything is alright we can load it in:

sudo nginx reload

HTTPS (optional)

If you're wanting to secure your application with HTTPS then you can do so for free using Let's Encrypt.

To start of we'll install the certbot package:

sudo apt-get install certbot

With that installed we need to then update the nginx config file by adding the following into the server block:

server {
    ...
    location /.well-known/acme-challenge {
        root /var/www/letsencrypt;
    }
}

We need to enable this change by reloading nginx:

sudo service nginx reload

Now we can finally request a new certificate with the following:

sudo certbot --nginx -d example.com

The --nginx parameter will make certbot update the virtualhost file for us. It will change the existing block to listen on port 443 (https) and reference the newly created certificates. It will also create a new http server block as well to redirect any non https traffic.

Kotlin & KTOR

KTOR

When it comes to android development I really love working with the Kotlin language, I can see why Google changed from Java to Kotlin as the default language.

With web development I find PHP to be fine but it can fell like a chore to work with. Perhaps it's having to work with old projects for work with bad code along with the lack of strict data types but I find it to be quite unenjoyable to use these days. Perhaps it's also partially down to have experienced, in my opinion, a better language.

Over the last couple of weeks I've been learning about Kotlin for web development using KTOR. As a basic test I decided to recreate my site to see how easy or would be and I can happily say it's been a mostly great experience. The main down side has been a bit of a lack of documentation, especially with getting it set up on the server using Jetty9. I've managed to get it up and running but I'll probably have to write up the process so I have a reference in the future.

Southpaw 2.0

It's been the cards for a while but I've decided to finally move away from WordPress. That main issue with WordPress is that because it's such a popular platform, it will always be a prime target for attacks and exploits.

Another thing which is a bit of a minor annoyance to me is backing up, everything is stored in the database so the while thing has to be backed up and restored if needed. Also potential is is that of the database is corrupted then you could potentially lose everything.

Updating can also be a complete minefield, especially if you're using plugins. You need to make sure everything is kept up to date because of the aforementioned security issues and if there's any incompatability between the core files or the plugins, your whole site can break.

I've therefore decided to switch things up a bit and make my own platform to suit my own needs. The key factors being:

  • Fast
  • Easy to backup
  • Secure

Data

I've had the idea for a while now of using markdown for blog posts, it's nice to write and is perfect for source control add it's plain text. This would solve the backing up concerns of storing all the data in a database.

This did however bring up the consideration of whether to use a database at all. Because all the core blog data will be stored in external files, would a dedicated database be overkill? At this point I've decided to go ahead without one, purely because this site is quite small. If it reaches a larger size and the speed is impacted then perhaps I'll add a database to the setup. My current thinking would be that the values in the database would be completely built up from the markdown files so if the database was lost for whatever reason, it could be easily regenerated from the files. The database would also allow the usual benefits of easily filter and sort the data.

Structure

If no database is going to be used then an alternative method for storing structure data will be needed so I went with JSON.

The JSON will be used for the routes and the structure of each page:

routes.json

[
    {
        "url":"/",
        "page":"home"
    },
    {
        "url":"/blog.*?",
        "page":"blog"
    }
]

pages.json

{
    "global":{
        "template":"main.html",
        "templateVars":{
            "nav":"nav.html"
        }
    },
    "pages":{
        "home":{
            "templateVars":{
                "pageContent":"pages/home.html",
                "meep": "bah!",
                "test": "meh",
                "homeClass": "home"
            }
        },
        "blog":{
            "blog": {
                "base": "/blog/"
            },
            "templateVars":{
                "pageContent": "blog.html",
                "blogContent": "wheeeee"
            }
        }
    }
}

The routes JSON simply takes a regular expression of a URL and points it to an entry in the pages JSON. The pages JSON defines global and page based variable replacements which can be either plain text or HTML template files.

We'll also use JSON to automatically build up the structure of the categories and the posts. To do this we'll scan the markdown directory for any new files, scan their headers and update any structure JSON files where necessary.

Runners v0.0.5

It's been another hiatus since the last update but there's been a fair amount of progress made recently.

I've finally gotten around to improving the UI in some areas. The task screen has been completely remade to remove the majority of the text and use icons instead. Tapping on an icon will show a text popup with the description.

v005 Task UI

Another important addition has been changing how text is stored, it’s now done in a way to allow automatic language switching within the game based on the device.

The map has also been completely remade due to software issues (more on this below). During the recreation, I’ve decided to add in a few different biomes to help split up the map. This still needs a lot of work but the variety of environments will help to make the world a bit more interesting. It’s still a work in progress so the edges between the biomes still needs work.

Biome 1Biome 2

Alongside the actual game development, the tools used to help create the game have also changed. Originally I was using Tilesetter to create the map but unfortunately due to bugs in the software, it caused additional work with parts of the map having to be recreated multiple times. I’ve since moved over to using Tiled which does essentially the same task as Tilesetter but appears to be still in active development. On top of that, Tiled also has a lot of features already implemented which are still on the Tilesetter roadmap which I’ve been waiting for to help with production.

Recently there has also been a lot more planning on the whole project including features to add and what needs fixing/changing. One essential point is the pricing. Originally it was planned to make the game completely paid but now it will be a freemium type game with ads that can be removed with a one-off payment.

Dungeon Live Wallpaper

Over the last month I've been working on a small project I could piece together pretty quickly. It's essentially a dungeon crawler themed wallpaper which runs in the background with the hero exploring each level, once he's checked out each room he'll seek out the stairs.

What's left?

There's a few ideas left to add in, the main one is to add more variations including room content, wall sets and enemies. I also like the idea of making it more RPG style giving the hero health and the ability to pick up health potions