YunoHost first impressions

What is YunoHost?

Debian based Linux distribution focused on managing web services located on a single instance. Mission is to provide small organizations a way to maintain their own web services without relying on big cloud providers. Target audience includes non-governmental organizations(NGOs) and local communities. YunoHost doesn’t try to provide it’s own solutions to common needs. Instead it bundles already existing software in so-called apps, which are exposed to end users with single-click installation in similar fashion to how it works in modern mobile phones.

Community

Some documentation is written in french up to this day. While community gradually switches to English, a lot of posts on forum are still written exclusively in french. Community plays a crucial role in development, since YunoHost is maintained mainly by volunteers with support from grants and donations. Changes happen mostly in 2 GitHub organizations:

Technological stack

While YunoHost tries to not constrain installed applications, there are some common services which provide consistent authentication and access:

  • Nginx - Webserver handling all HTTP/HTTPS traffic. It’s not mandatory to use it, but it’s also serving YunoHost’s administration panel and has exclusive control over ports 80 and 443. Configuration is enhanced with SSOWat, making it possible to restrict access to applications, even if they don’t support access control natively.
  • Let’s Encrypt - Method for generating free TLS certificates for websites. It’s not required to use it, but it allows to secure newly created instance almost instantly.
  • OpenLDAP - User credentials and access information are stored centrally in this database. Applications may choose to not integrate with LDAP at all, but that’s a go to solution.
  • fail2ban - In modern times freshly installed virtual private server typically receive a tens or even hundreds of SSH break-in attempts. This service ensures, that brute-force attacks from single IP are blocked after a few tries. It means, that administrator can also accidentally be locked out of instance, if he/she repeats authentication attempts too many times.
  • Postfix and Dovecot - Classical open source combo for handling incoming and outgoing e-mail messages, while exposing mailboxes to users.
  • rspamd - Spam filtering solution for e-mail.
  • Metronome - XMPP server.
  • Services specific to YunoHost like administrative panel written in Python.

On top of that YunoHost supports many common databases and interpreters like MySQL, NodeJS and PostgreSQL. They are configured during installation of applications.

Comparison to other solutions

Package managers

APT, Pacman, Yum and others focus on providing everything required to use some software, including binary files and sometimes example configuration files. YunoHost apps act more like set of instructions on installing and managing some services. Unlike traditional packages, they make a lot of assumptions about how software will be operated and don’t contain any source code or binary files. While traditional repositories are sufficient to install packages, YunoHost apps often require internet access to fetch some extra files from internet. It would be very hard to sandbox them.

Configuration management systems

Ansible, Puppet, Saltstack and others focus on management of distributed infrastructure. They are way more flexible than YunoHost’s conventions but it would take a significant amount of time to recreate similar setup in them. Unlike YunoHost they don’t offer any integrations like SSOWat or admin panel out-of-the-box, so they are more like a basic building blocks compared to YunoHost.

Mainstream Linux distributions(Debian, RedHat, Ubuntu, Arch Linux)

While being based on Debian, YunoHost is not using deb format for it’s own packages. It’s not supposed to be a universal operating system by design. Currently the main focus is web applications. Also unlike mainstream distributions, it requires services to support more lifecycle actions like backing up, restoring and reconfiguring.

What exactly are YunoHost apps?

A bunch of shell scripts with configuration templates and metadata. Metadata is stored in TOML or JSON format, depending of packaging format version. App definition requires developer to provide a set of hooks for service management, including:

  • Installation
  • Removal
  • Backup
  • Restoration
  • Upgrade
  • Reconfiguration(optional)
  • Changing access URL(optional)

Additionally a few good starting resources are provided:

  • New application template
  • App helpers - These are Bash functions for handling commonly used resources like Nginx virtual hosts or NodeJS versions.
  • App resources - Declarative way of using App helpers. They are very convenient, because a lot of lifecycle actions like installation and removal, are handled automatically, when app is declaring them in manifest.

Not all helpers have corresponding resources yet, but the general direction seems to be to use resources whenever possible. Of course there are also cases where there are no helpers for a certain resource. That’s where manual shell scripting comes into play. General rule for handling resources is to try the following solutions in order:

  1. Is it enough to declare resource in manifest?
  2. Is there a helper for managing a resource?
  3. Can resource management be automated with shell?

Sometimes more complicated effects are achievable by configuring services directly using helper to figure out environment configuration like:

ynh_mysql_execute_as_root --sql="GRANT ALL PRIVILEGES ON \`${db_prefix}_%\`.* TO '${app}'@'localhost';"

Above example allows to provision access for application, which creates databases dynamically.

Even with all this documentation there are still many unwritten conventions like extending shared services configuration or registering long-running processes. During packaging, it’s the best to clone some popular apps(like NextCloud and PeerTube) from YunoHost-Apps organization on GitHub and figure out solutions to problems by referring to them.

Limitations and problems

  • app scripts rely heavily on system state and versions. Because of that, adding support for new Debian versions is a very long and error-prone process.
  • Some conventions are too limiting. For example it’s assumed that each application should be related to exactly one domain. Some web application use alternative domain for serving static content. Invoking ynh_webpath_register twice with different domains ends in error. It can be worked around, but then it’s harder to reason about configuration from administrative panel.
  • Assumptions have been made how scripts should look like. Most of the times they can be skipped as a linter warnings, but other times they impose artificial limitations during testing.
  • App scripts don’t conform to commonly accepted Bash scripting standards. There’s a lot of space for word-splitting and other common pitfalls. App scripts are by definition a trusted code, which runs as root so this decision is understandable, but it’s harder to implement error handling this way. On the other hand they are not supposed to be standalone programs, so keeping them as simple as possible is desired.
1 Like

Nice writeup! :fire:

I didn’t know that the maintainers decided against using shellcheck. I wonder if they will be willing to reconsider :innocent:

I agree that sometimes the French language barrier is frustrating, but I at least once managed to break through it using Firefox’s built-in translation feature.

Upgrading Debian version can be a pain, indeed, however from my personal experience and memory the migration from 10 to 11 was much smoother than from 9 to 10, so there is visible progress.

Sometimes something breaks (I always fear making upgrades to bigger apps so I check my backups twice beforehand), but overall I believe it saves me sooo much time! I (co)administer 3 instances of yuno and I recommend it to everyone (except if they want to host Matrix on it - they should use https://github.com/spantaleev/matrix-docker-ansible-deploy instead :wink:

@Jakski it seems the maintainers might change their minds :innocent: