winther blog

Self-hosting linkding for managing my postroll

I have been looking for a different way to manage link sharing in the postroll and I have found a good solution by self-hosting linkding. It is an open source simple bookmarking service making it easy to both manage a private collection of bookmarks and facilitate sharing links. It is available on bookmarks.sysctl.dk and even comes with an RSS feed.

Setup was pretty straightforward using Docker with a simple Nginx reverse proxy:

upstream linkding {
  server 127.0.0.1:9090;
}

server {
    server_name bookmarks.sysctl.dk;

    location / {
	    proxy_pass http://linkding;
	    proxy_set_header Host $host;
	    proxy_set_header X-Forwarded-Proto $scheme;
    }
}

To get the links integrated directly into the postroll, I used the REST API in linkding, but I had to wrap it with a parsing script I run locally on the server that rewrites the JSON to something that is easier to work with. With some simple JavaScript the list of links is then dynamically created:

<ul id="postroll"></ul>

<script>
fetch('https://sysctl.dk/links.json')
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        const list = document.getElementById('postroll');
        data.forEach(item => {
            const li = document.createElement('li');
            const a = document.createElement('a');
            a.href = item.url;
            a.textContent = item.title;
            li.appendChild(a);
            const domainText = document.createTextNode(` [${item.domain}]`);
            li.appendChild(domainText);
            list.appendChild(li);
        });
    })
    .catch(error => console.error('Error fetching data:', error));
</script>

Only thing needed is to allow CORS in Nginx serving the JSON file:

add_header Access-Control-Allow-Origin https://winther.sysctl.dk;

This works fine for now, though I want to tweak it a bit with an indication of when it was last updated and perhaps some better error handling.

Some #links will still get their own blog post, but this setup removes some friction for me to keep the postroll updated.

#tech