Introducing the FlexSearch Plugin for Nikola


I wanted to have search functionality in this site, which is powered by Nikola SSG. After some research I decided to create a new plugin using Flexsearch and the plugin is not available in Nikola Plugin repository.


I use this site a lot as personal repository of stuff I forget. This means I refer to it when I have to do something and I no longer remember what command it was. I also refer people here when they ask something I´ve already answered here. My usual workflow was to go through my articles and use the search feature from the browser, but that was not that efficient because sometimes I only remember that one phrase of that one post.

Well, this is no longer necessary because now this site has full-text search functionality, courtesy of yours truly. This is a new Nikola Plugin, under MIT License (so that you can just use it as you want) and the FlexSearch Library.

How does this work?

Great that you ask. This is a static site. That means that whenever I post a new article I have to rebuild the site to generate HTML from my source (markdown, rst, asciidoc and others) from my git repository. In other words, this site does not use any database. The search functionality has 3 steps:

  1. When the site is build, a search:index.json is build. This index contains all the titles, slugs and body of all my articles.
  2. There is a search box now in th main menu. This does nothing else than calling a javascript snippet, which in turn uses the FlexSearch Library, to use that search_index as input and return a list of post that matches your search query.
  3. The small javascript snippet renders the search results in a div for you to browse.

That´s all. It is completely offline, no Google, Databases, third party services or whatever. Pretty cool, isn´t it?

Of course, I´m not the first one to think about this. There are many examples out there. These are some of them


If you are using Nikola for your site, you are welcome to give it a try.

To install the plugin just run

nikola plugin -i flexsearch_plugin

and follow the instructions.


How to fix incrementing mount names on reboot in Ubuntu/Linux Mint


To prevent your internet disks from being mounted with incrementing names (e.g., name1, name2) on each reboot, configure static mount points using the /etc/fstab file. This avoids conflicts with services like Docker that use bind volumes.


Each time I restarted my computer running Ubuntu/Linux Mint, my additional disks were mounted with incrementing names. This breaks all symbolic links and history because another service, Docker in my case, uses the path before it is mounted.

Why was this happening? I did not care to check how were the additional internal disks being mounted. I just connected them and started to use them. To be fair, I don't restart my computer that often (around once a year, see the image below), so it took me almost a year to find this situation.


Long story short, I restarted my computer and many thing did not work anymore, and the mount points were the cause of it.

Steps to Fix the Issue

1. Find the UUID of the Disk

Use the lsblk command to list all block devices and their UUIDs:


You can also use the disk manager in your desktop environment to find the UUID. In my case, KDE, it looks like this:

disk manager kde uuid

Note down the UUID of the disk you want to mount.

2. Edit /etc/fstab

Open the /etc/fstab file with a text editor:

sudo nano /etc/fstab

3. Add an Entry for Your Disk

Add an entry for your disk using its UUID:

UUID=<your-uuid> /mnt/your-mount-point ext4 defaults 0 2

Replace <your-uuid> with the actual UUID and /mnt/your-mount-point with your desired mount point.

4. Understand the fstab Options (optional, most of the time the defaults will work)

  • defaults option: A shorthand for standard mount options, including:
  • rw (read-write)
  • suid (allow setuid bits)
  • dev (interpret device files)
  • exec (allow execution of binaries)
  • auto (can be mounted with mount -a)
  • nouser (only root can mount)
  • async (asynchronous I/O)

  • 0 (dump): This field is used by the dump utility to decide if the filesystem needs to be dumped. 0 means ignore.

  • 2 (pass): The order in which fsck checks the filesystem for errors during boot. 0 means don't check, 1 is reserved for the root filesystem, and 2 is for all other filesystems.

5. Create Mount Points

If you don't have the mount points already, create them:

sudo mkdir -p /mnt/your-mount-point

In my case I did already have them.

6. Mount the Drives

Restart your computer or run the following command to mount the drives immediately:

sudo mount -a

In my case I had to restart the system, as that was the easiest way to get everything normal again.

Side notes

As sidenote, some of the issues I had were:

  • Nextcloud Desktop could not sync anymore, as it did not find the destination folder.
  • The quick accesses on doplhin file manager were no longer correct.
  • all my zoxide paths were broken.

That was enough for me to fix this, as I couldn't take it anymore. :)

Some References

Introducing the GitHub Widget Plugin for Nikola


The GitHub Widget Shortcode Plugin for Nikola lets you embed a customizable widget showcasing a GitHub repository's details in your site.


Today, I'm excited to announce that my GitHub Widget Plugin for Nikola has been merged! This plugin allows you to embed a GitHub repository widget directly into your Nikola-generated site, displaying key details of the repository.

Nikola is a static site generator that offers great flexibility. I've already written about it [a few times](, and it's what's powers this site. However, embedding GitHub repository details required custom solutions—until now. My new plugin provides an easy way to integrate this functionality using a simple shortcode.

Why is this important? Because somehow I've been using GitHub more for public code, such as my espanso-compatible TextExpander Android App. Thus, I plan to have a section on this site to list such projects, and I was missing a way to show updated information from each repository.

With this shortcode I can just do this (Source)

{{% github_widget %}}dacog/textexpander_android {{%/github_widget %}}`
and I get the following


This is a basic text expander app for android. Use it as a espanso companion app, as it parses the yaml files in espanso/match

Languages: Kotlin

  • ⭐ Stars: 12
  • Forks: 1
  • 👁 Watchers: 2
  • ❗ Open Issues: 0

This looks a lot better than just a link 😁

How It Works

It was a bit trial and error, as I had not used the GitHub API before.

The first approach was to use requests to call the api endpoints (such as{repo}/commits) to get the json response and use that. But after that I also wanted to get the latest commits and the latest release, if available. And then I got an api rate limit error, with a nice message:

  "message": "API rate limit exceeded for (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
  "documentation_url": ""

That meant, of course, that I now had to get a token to avoid the error. I tried following the GitHub API Documentation for AUTH, but without success. And then it got me... there should already be a library for this... and there was.

I installed PyGithub and refactored my code to use it. That meant I removed most of my code, as I no longer had to call each endpoint on my own.

Authentication worked instantly and I no longer had the api rate limit error.

That's the short story. Now let's explain how to use this.


You need to have a working nikola setup. If you dont have one, you can check this article: link://slug/nikola-blog-setup

To install the plugin, run the following command:

nikola plugin -i github_widget

Optional Configuration

For enhanced API usage, add your GitHub API token to

# Add your GitHub API token here
GITHUB_API_TOKEN = 'your_github_api_token_here'

This step is optional but recommended to avoid API rate limit issues.

Your personal token should allow access to the repositories and its contents. Read-only permission is enough.

Using the Shortcode

Here are some examples of how to use the shortcode in your markdown files: (Source)

// Basic Example
{{% github_widget %}}user/repo{{% /github_widget %}}

// Example with Avatar and Custom Width
{{% github_widget avatar=true max_width=400px %}}user/repo{{% /github_widget %}}

// Example with Latest Release and Commit Info
{{% github_widget avatar=true latest_release=true latest_commit=true max_width=400px %}}user/repo{{% /github_widget %}}


You can customize the widget to display various details such as the repository owner's avatar, the latest release, and the latest commit. Adjust the max_width parameter to fit the widget into your site's layout.

Visual Examples

Here's what the widgets look like with the example shortcodes:

Basic Example

Basic Example

With Avatar and Custom Width

With Avatar

With Latest Release and Commit Info

With Latest Info

CSS Customization

To style the widget, you can use the following CSS:

/* github shortcode */
.github-widget {
    display: flex;
    align-items: center;
    border: 1px solid #ddd;
    padding: 10px;
    margin: 10px 0;
    border-radius: 5px;
    background-color: #f9f9f9;

.github-widget-image {
    margin-right: 10px;

.github-widget img {
    border-radius: 50%;

.github-widget .repo-info {
    display: flex;
    flex-direction: column;

.github-widget .repo-info h3 {
    margin: 0;
    font-size: 1.2em;

.github-widget .repo-info p {
    margin: 5px 0;
    font-size: 0.9em;
    color: #555;

.github-widget .repo-info ul {
    list-style: none;
    padding: 0;
    display: flex;
    gap: 10px;

.github-widget .repo-info ul li {
    font-size: 0.8em;
    color: #333;

.github-widget h4 {
    color: black;


The GitHub Widget Plugin for Nikola makes it easy to display detailed information about any GitHub repository on your site. With simple configuration and usage, it's a great addition for any developer's blog or project page.


How to Optimize and Free Up Disk Space on Debian/Ubuntu Servers with Docker Containers


Manage disk space on Debian/Ubuntu servers and Docker containers by removing unnecessary packages, cleaning up caches, and pruning Docker objects.


I needed to free up space as I had a small VPS with full storage, and my notebook and desktop computers had also a really high disk usage, although I did not have that many files, but I do use a lot of docker.

After researching I did not find a guide with everything I needed (explanations included), thus here it is.


Package Manager (apt)

Remove packages that are no longer required

sudo apt-get autoremove

Clean Up APT Cache

Check the space used by the APT cache:

sudo du -sh /var/cache/apt

Clean up the APT cache:

sudo apt-get autoclean
sudo apt autoclean

Delete cache files:

sudo apt-get clean
sudo apt clean

Clear Systemd Journal Logs

Check the disk usage of systemd journal logs:

journalctl --disk-usage

Clean logs older than 3 days:

sudo journalctl --vacuum-time=3d


Docker takes a lot of space compared to vanilla servers. Check link:/slug/change-docker-data-directory-vps-optimization for a related post on the overlay2 and how to move docker data root to another volume/ drive.

Check system usage

Check overall system usage:

docker system df

For more detailed information:

docker system df -v

Use docker system prune

(from documentation)

WARNING! This will remove:

  • all stopped containers
  • all networks not used by at least one container
  • all dangling images
  • all build cache
docker system prune
Use Docker Container Prune

Warning: This will remove all stopped containers. Refer to the documentation for more details.

docker container prune # Remove all stopped containers
Use Docker Image Prune

Remove unused images (Remove all dangling images. If -a is specified, will also remove all images not referenced by any container.)

Quick note:

What are Docker Dangling Images?

  • Images that have no tag and are not referenced by any container source
  • Untagged layers that serve no purpose but still consume disk space.
  • Not automatically removed by Docker and need to be cleaned up manually. source
docker image prune

Use docker volume prune

Remove all unused local volumes. Unused local volumes are those which are not referenced by any containers. By default, it only removes anonymous volumes.

docker volume prune # remove only anonymous (unnamed) volumes

This command removes only anonymous (unnamed) volumes by default.

To remove all unused volumes:

docker volume prune -a # remove all unused volumes


Exciting News: My Upcoming Book "The Digital Marketer’s Playbook" is about to launch

I am thrilled to share some exciting news about my forthcoming book "The Digital Marketer’s Playbook: How to Effectively Collaborate with Agencies, Freelancers, and Digital Marketing Experts," to be published by Apress (Springer-Nature). The book is targeted for release by the end of Q3 or Q4 2024. That's this year!

If you've followed my blog, you might recall that I initially conceived this project as a short book. My idea was to write a practical guide with the main topics related to digital marketing. It has now evolved into a comprehensive resource. Designed for professionals grounded in marketing or business and for those particularly interested in the field, it guides readers through the complexities of digital marketing, emphasizing effective collaboration with various partners. I think the title of the book is also self-explanatory. 😁

The Journey and Collaboration

The book has evolved significantly over the past few months. My first post about it marked the beginning of this journey. Since then, ten months later, I've moved away from the idea of self-publishing for this project, choosing instead to sign to go with traditional publishing. This decision came after discussing the book proposal with Shivangi Ramachandran, an Apress Senior Editor (Acquisitions), which ended with me signin with Apress (Springer-Nature).

Partnering with them and working closely with Shiva and Sowmya Thodur (Production Editor), brought about substantial changes. After signing, I received a lot of guidelines regarding the structure how the book, which made me realize that the chapters were more that just a compilation of important points and I had to elaborate on them. These changes quickly expanded the book into a comprehensive 250+ page resource. That structured approach to writing required me to rethink and rewrite many sections of the book.

Throughout this journey, I have dedicated countless hours refining the content, often late into the night. My amazing wife’s patience has been invaluable, and I cannot thank her enough for her support. Throughout the entire process, she also served as a thoughtful partner, sharing her insights and candid comments.

Additionally, the Unperfekthaus in Essen provided a perfect environment with their focus room and endless coffee, where I spent nearly three days a week until closing time last month to finish the manuscript.

I also have to thank my colleagues at MEHRKANAL, especially Miri and Mario, for enduring my questions and serving as sparring partners on several book topics. They often heard me talk about the book, perhaps more than they would have liked. Victor and Eva, who gave me detailed feedback on the first version of the Table of Content. Damian, Tom, Holger, Christian also listened to my thoughts on the book and gave their feedback. There are many others whose names escape my memory, as it's again late into the night.

Although many of them saw this as just another item on my never ending list of personal projects, I'm thrilled it has become a reality. 😎

I wrapped up the manuscript in early June, fueled by an impressive coffee intake—seriously, about 4-6 cups per session! Thanks to the patience of many, it's now in the capable hands of the Apress team for review. Can't wait to share it with you soon!

A quick preface before diving into the details

This project has not only deepened my grasp of familiar topics; it has also allowed me to enrich the manuscript with innovative content driven by the latest trends and technologies in digital marketing.

Some chapters turned out shorter than anticipated, while others demanded more detail. I focused on keeping the content both core and practical, but ultimately, you'll be the judge of that.

Stay tuned for more updates and sneak peeks of the book! I am excited to share this resource with those of you eager to master digital marketing.

If you want to be among the first to explore "The Digital Marketer’s Playbook," please fill out the form below.

What will you learn by reading the book?

This book is my effort to provide you an all-inclusive resource to enhance your understanding of digital marketing and equip you with the skills and knowledge to work effectively with various partners in the field.

My goal throughout its pages is to provide you with everything you need to communicate your requirements to your partners, understand what they do and ask the right questions when you need to. I define digital marketing as a process, and that's also how the book is structured.

Within its pages, I guide you through the foundational concepts of digital marketing. You'll grasp what digital marketing is, familiarize yourself with crucial terms like digital assets, advertising channels, and customer awareness, and learn to distinguish between walled gardens and the open internet. This knowledge will be essential for discussing your goals and your campaigns implementations with your partners. I also describe the landscape of taxes and laws regarding digital marketing and how it can impact your digital marketing efforts.

As you dive deeper, I'll show you how to set up and structure digital marketing campaigns effectively. You'll understand bid strategies, ad quality, and the importance of placements and inventory. We'll explore various campaign types and their significance, focusing on how to craft a briefing to get impactful creatives, messages, and copy to achieve marketing success and align your digital marketing initiatives with your business goals.

Finally, I offer practical examples tailored to various company types, detailing key factors to consider based on company size, resources, and business structure. I also share my perspective on using artificial intelligence in digital marketing, discussing both its benefits and risks. Additionally, I provide an overview of social media and its role in digital marketing.

Ready to dive deeper into digital marketing? Sign up below to receive updates on "The Digital Marketer’s Playbook" and access exclusive digital marketing resources.

Quick and simple Local WordPress Setup for Lazy Developers

Quick and simple WordPress Setup for Lazy Developers

I needed a fast way to set up WordPress locally. I tried various methods, but they were either too complex or didn't work. So, I created a simple, lazy solution.

This is by no way secure, but it runs on the first try 😁

The code is in this GitHub repository. Feel free to use it.


Set up a local WordPress development environment easily with Docker Compose using this repository. One command sets up WordPress with WP-CLI, MariaDB, and PHPMyAdmin, plus autogenerated aliases for quick management. A second command sources these aliases. Perfect for quick, lazy local development. Not secure for production use.

Languages: Shell

  • ⭐ Stars: 0
  • Forks: 0
  • 👁 Watchers: 1
  • ❗ Open Issues: 0

How It Works

This setup revolves around 4 files:

1 docker-compose.yml:

This file:

  • Uses the latest official containers for WordPress, MariaDB, PHPMyAdmin, and WP-CLI.
  • Sets up a wordpress database with user and password root.
  • Launches a WordPress instance linked to the database.


This script:

  • Detects whether you have docker-compose or docker compose and uses the correct one.
  • Sets your UID and GID in a .env file.
  • Generates an alias file for quick commands.


This script:

  • Creates the WordPress directory.
  • Sets permissions to 777 (yes, it's insecure).
  • Starts Docker Compose.


Autogenerated by or Source it to get these aliases:

  • dc: Docker Compose commands.
  • wpcli: WP-CLI commands.
  • wpbackup: Backs up the database to ./backups.
  • wpdown: Backs up and then stops and removes containers and volumes.

How to Use

First you need to clone the repository:

git clone
cd lazy-docker-compose-wordpress-setup

Run these commands to get started:

chmod +x
chmod +x

Now you are good to go. You will see a new folder wordpress is created in the path you were in.

Now you can:

  • Check http://localhost:8000 for the WordPress site
  • Check http://localhost:8080 for PHPMyAdmin. User and password is root

You receive this information also when you run

Using the Aliases

alias dc

  • Bring up the services:
dc up -d
  • Stop the services:
dc down
  • Stop and remove volumes:
dc down -v
  • View the status of the services:
dc ps

alias wpcli

Run WP-CLI as root (it includes --allow-root):

  • Check WordPress version:
wpcli core version
  • Install a plugin:
wpcli plugin install hello-dolly --activate
  • Update WordPress core:
wpcli core update
  • Create a new post:
wpcli post create --post_title='My New Post' --post_content='This is the content of the post.' --post_status=publish


Back up the database to ./backups:



Back up the database and files, then stop and remove everything:



Here are some other methods to consider:

  1. Local by Flywheel: User-friendly local WordPress setup with advanced features. To be fair, I completely forgot about this when I was trying to get WordPress to run locally. This is way more powerful, but you need many clicks... and you need to fill a form to download it.
  2. DevKinsta: Offers local development with easy deployment to Kinsta hosting. I haven't tried this one.

How to change the Screen Resolution of a Guest-OS (Ubuntu) in Hyper-V with PowerShell on Windows 11


To change the screen resolution of a VM in Hyper-V, use PowerShell. The command requires the VM name and the desired resolution.


Unlike in VirtualBox, in Hyper-V I could not find a GUI option to change the screen resolution directly. Instead, I had to use PowerShell to adjust the display settings of your virtual machine.


  1. Identify the VM Name

Find the name of your VM in Hyper-V Manager. (Search for Hyper-V Manager in the start menu to access it)

Hyper-V Manager VM Name

  1. Open PowerShell

Open a PowerShell terminal on your host machine.

  1. Execute the Command

Use the following PowerShell command, replacing "Ubuntu 22.04 LTS2" with your VM's name and adjusting the resolution as needed:

Set-VMVideo -VMName "Ubuntu 22.04 LTS2" -HorizontalResolution 1920 -VerticalResolution 1080 -ResolutionType Single
  • HorizontalResolution: The width of the screen in pixels (e.g., 1920).
  • VerticalResolution: The height of the screen in pixels (e.g., 1080).
  • ResolutionType: Set to Single for a single monitor setup.


How to set up a Nikola-powered blog with multi-markup support


This article guides you through creating a blog using Nikola, a static site generator that supports Markdown, reStructuredText, and Jupyter Notebooks. I'll use the Bootblog theme and detail how to host the code in a private repository on GitHub or GitLab, with a preference for GitLab. Deployment steps to Cloudflare are covered in a separate article (link provided). For editing, VSCode or PyCharm is recommended, though any text editor works.


Nikola is a versatile static site generator that is perfect for researchers, educators, and bloggers who want to incorporate rich content like Jupyter Notebooks into their posts. It's Python-based, easy to customize, and supports various content types.

After extensive research and testing various static site generators, I chose Nikola as my blogging platform. While Nikola may not be as trendy as some newer generators that frequently pop up in tech articles, my priority was finding a tool that offered both stability and flexibility—qualities that are sometimes overlooked in favor of following trends.

Nikola stood out for me for several reasons:

  • Stability: The project has been actively maintained for over eight years, indicating a mature and dependable platform.
  • Flexibility: Written in Python, Nikola is particularly advantageous for those involved in DevOps and Data Science. It supports a wide array of formats and markup languages including AsciiDoc, Markdown, Jupyter Notebooks, and HTML and allows importing metadata and content also from several sources (WordPress, Pelican and others). Here you have a cheat sheet for some markup languages
  • Extensibility: The availability of shortcodes and plugins enhances its functionality, allowing for a high degree of customization and integration. I've created some shortcodes myself for my personal use case
  • Deployment Versatility: It can be deployed to virtually any platform, though I personally use Cloudflare Pages for its simplicity and performance.
  • Version Control Friendly: The content being stored in plain formats in a Git repository (I use GitLab) means that it's not only secure but also highly manageable and version-controlled.

This combination of features makes Nikola an ideal choice for me (and I dare say for those who value a stable, extendable, and developer-friendly blogging environment).

What is a static site generator and what's the difference with normal CMSs

A static site generator (SSG) is a tool used to produce HTML websites by compiling source files written in various markup languages like Markdown or reStructuredText. Unlike traditional content management systems (CMSs) that dynamically build a page every time a user accesses it, SSGs generate (compile) all pages at once during development. This process results in a set of static HTML files which can be easily hosted and served.

Key Differences Between SSGs and Traditional CMSs

  • Performance: Static sites generally load faster than their CMS counterparts because they consist of simple HTML files, eliminating the need to query a database or execute server-side scripts on each request.
  • Security: With fewer moving parts and no database interactions, static sites are less vulnerable to common web attacks such as SQL injection and XSS (Cross-Site Scripting).
  • Scalability: Hosting static files is straightforward and can handle high traffic with less overhead than dynamic sites.
  • Cost: Static sites can be hosted on any simple web server or services like GitHub Pages and Cloudflare Pages often for free, reducing the cost associated with web hosting.
  • Maintenance: Static sites require less maintenance since they don’t involve managing a server or database. Updates are made by regenerating and redeploying the site, rather than through an online interface. This means you don't need to update anything, and you may use an old version forever, so long it runs locally.

However, traditional CMSs like WordPress or Drupal offer advantages in scenarios requiring frequent updates, user interaction, or complex dynamic functionalities. They provide a user-friendly interface that allows non-technical users to easily manage content and make updates in real-time without touching the underlying code. And traditional CMSs are friendlier for a normal user.


Here's how to set it up on any major operating system and prepare it for hosting on Cloudflare.

1. Install Nikola

First, you need to install Nikola. It's Python-based, so ensure Python is installed on your system.

I recommend to use a virtual environment. I usually use miniconda. You can check the install instructions here.

Once you have Python installed (with or without a virtual environment) you need to install nikola.

pip install Nikola[extras]

2. Create Your Nikola Site

Generate your new Nikola site with:

nikola init mysite
cd mysite

3. Configure Nikola

Edit in your site directory to set up the Bootblog theme and enable support for Markdown, reStructuredText, and Jupyter Notebooks:

# Add bootblog to your theme
THEME = "bootblog"

# Enable support for Markdown, reStructuredText, and Jupyter Notebooks
    "rest": ['.rst'],
    "markdown": ['.md'],
    "ipynb": ['.ipynb']

4. Setting Up Version Control

GitHub vs. GitLab

GitHub: - More popular and widely used. - Integrates well with other tools and services. - Provides free private repositories with a limit on collaborators.

GitLab: - Offers free private repositories with unlimited collaborators. - Includes built-in CI/CD features. - I prefer GitLab for its comprehensive DevOps capabilities.

Using GitLab

Create anew account on on the free plan and then create a new private repository in GitLab and push your site:

git init
git remote add origin [your-gitlab-repository-url]
git add .
git commit -m "Initial commit"
git push -u origin master

5. Edit and Update Your Blog

For updating your blog, use VSCode or PyCharm, though any text editor will suffice. These IDEs offer great support for Python and Markdown, enhancing the blogging workflow.

For steps on deploying your blog to Cloudflare, refer to my detailed guide here: Deploying Nikola Site to Cloudflare.

Nikola has a deploy command, but I prefer to use the Cloudflare pipeline to auto-publish on git push.


Setting up a Nikola blog is straightforward (but requires more steps than setting a blog on It supports a variety of content formats and can be easily integrated into modern workflows and tools like GitLab and Cloudflare for a robust blogging setup. The best of it is that you are not dependent on a specific platform.

Check the Handbook

The handbook on is great and has almost everything you might need for your blog.

I've writen some articles about nikola that might interest you after this one

How to install SSTP VPN on Ubuntu-Based Distros such as Ubuntu, Kubuntu, KDE NEON, Linux Mint


This guide provides step-by-step instructions on installing and configuring Secure Socket Tunneling Protocol (SSTP) VPN on Ubuntu, Kubuntu, KDE Neon, and other similar distros. Whether you're using GNOME or other desktop environments, this guide covers all necessary steps, including troubleshooting tips.


SSTP VPN is widely used for securely connecting to remote networks. It's especially relevant for Ubuntu-based Linux distributions, which might require different installation steps depending on the desktop environment. This guide simplifies the process, ensuring a smooth VPN setup.


For GNOME-Based Distros (Ubuntu)

1. Install SSTP Packages:

sudo apt install network-manager-sstp sstp-client

2. Open Network Manager:

  • If unsure about accessing Network Manager, run:

3. Creating a New SSTP VPN Connection:

  • Use Network Manager to set up a new SSTP VPN connection.
  • Click on the '+' sign.
  • Select 'Secure Socket Tunneling Protocol (SSTP)' and click 'Create'.
  • Enter the VPN gateway, username, and password.
  • Save the settings.

For Non-GNOME Distros (Kubuntu, Linux Mint, KDE Neon)

1. Install Required Packages:

sudo apt install network-manager-gnome sstp-client network-manager-sstp

2. Accessing Network Manager:

  • Run nm-connection-editor in the terminal.

3. Setting Up SSTP VPN:

  • Click on the '+' sign.
  • Select 'Secure Socket Tunneling Protocol (SSTP)' and click 'Create'.
  • Enter the VPN gateway, username, and password.
  • Save the settings.

4. Connecting to VPN:

  • Connect via your network manager (tested on KDE).


  • Restarting NetworkManager Services: Sometimes, it's necessary to restart network services for changes to take effect. Use sudo service network-manager restart in the terminal.
  • Other SSTP Versions I use the following versions
dpkg -l | grep sstp
ii  libsstp-api-0                                 1.0.17-1                                                                     amd64        Connect to a Microsoft Windows 2008 server using SSTP VPN
ii  network-manager-sstp                          1.3.0-0ubuntu1                                                               amd64        network management framework (SSTP plugin core)
ii  network-manager-sstp-gnome                    1.3.0-0ubuntu1                                                               amd64        network management framework (SSTP plugin GNOME GUI)
ii  sstp-client                                   1.0.17-1                                                                     amd64        Connect to a Microsoft Windows 2008 server using SSTP VPN


  • Trial and Error
  • sstp documentation

How to install Linux Mint's webapp-manager on Ubuntu/ Kubuntu 22.04


Install Linux Mint's WebApp Manager on Ubuntu/Kubuntu 22.04 by downloading the .deb file and using wget and apt commands. This guide provides a quick and easy method for installation, suitable for KDE Plasma 5, KDE Plasma 6, GNOME, and more.


Linux Mint's WebApp Manager allows users to create web apps that feel like native applications on their desktop (They get their own icon, menu entry and isolated browser profile, and you can select which browser to use). This guide focuses on installing it on Ubuntu, Kubuntu and KDE Neon based on 22.04, avoiding the complexities and potential issues of adding Linux Mint's repositories directly.

I love Linux Mint but the last few months I migrated to KDE Plasma as Desktop environment. This meant (of course) testing new distros to check if there was any distro with better Plasma integration (it does not come with Linux Mint by default).

After changing distros, I really missed the Webapp Manager from Linux Mint, thus this guide.

Why This Method?

While some sources suggest adding Linux Mint's repositories to install the WebApp Manager, this method can be problematic. Linux Mint is a standalone distro, built on Ubuntu or Debian (depending on the version). Adding its repositories directly to Ubuntu or Kubuntu without proper configuration (for example, setting sources prios) can lead to package conflicts and system instability. By downloading and installing the .deb file directly, we bypass these issues. However, it's important to note that this method doesn't provide automatic updates for the WebApp Manager.

Steps to Install

All in one

cd ~/Downloads
sudo apt  install ./webapp-manager_1.1.5_all.deb
sudo apt install -f  # in some cases there are missing packages and this will install those.

Or step by step

1. Open Terminal and Navigate to Downloads Directory:

cd ~/Downloads

2. Download the .deb Package

Use the wget command to download the latest version of the WebApp Manager.


3. Install the Downloaded Package

Use apt install command to install the package.

sudo apt install ./webapp-manager_1.1.5_all.deb

4. Resolve Dependencies

If there are missing packages, use the following command to install them.

sudo apt install -f

5. Launch WebApp Manager

Search for 'Web Apps' in your desktop environment's menu to start using the WebApp Manager.


This should work on almost any Debian/ Ubuntu based distro, but I tested on Linux Mint with Plasma 5, KDE Neon with Plasma 6.


  • This answer on Stackoverflow