WIP roles for easy selfhosting based on ansible
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
southerntofu 32a6a8a26b Merge pull request 'Add support for Archlinux in .common, tor and webserver' (#1) from pep./ansible-selfhosted:bouah into main 1 year ago
.archlinux/tasks New role: .archlinux 1 year ago
.common .common: lint 1 year ago
.debian/tasks Move joinjabber recipes to dedicated submodule 2 years ago
.go/tasks Move joinjabber recipes to dedicated submodule 2 years ago
.rust/tasks Move joinjabber recipes to dedicated submodule 2 years ago
chatbridge Move joinjabber recipes to dedicated submodule 2 years ago
jabberserver Fix docs links 2 years ago
mailserver Move joinjabber recipes to dedicated submodule 2 years ago
tls Move joinjabber recipes to dedicated submodule 2 years ago
tor tor: make systemd override use different user per distribution 1 year ago
webserver webserver: add TODO re TLS in nginx template 1 year ago
LICENCE Move joinjabber recipes to dedicated submodule 2 years ago
README.md Fix docs links 2 years ago
deploy.sh Forgot to include deploy.sh 2 years ago
main.yml Move joinjabber recipes to dedicated submodule 2 years ago



WARNING: This is a codename and will change.

In this repository, you will find all you need to setup your own server. It contains:

  • Ansible roles to implement the services
  • a deploy.sh script to apply these settings on a server (run as root)


To configure your server, you will need a dedicated folder to keep track of all the configuration. It is recommended to version this folder with git or mercurial (or the tool of your choice). This repository should then be cloned as a submodule in the roles folder. Assuming you want to store server data in /etc/server, you could do:

# mkdir /etc/server; cd /etc/server
# git init
# git submodule add https://codeberg.org/southerntofu/ansible-selfhosted /etc/server/roles

Now, you should:

  • copy the deploy.sh script to your server's folder
  • configure the server in config.yml
    • here's some example configs: joinjabber.org
    • the complete configuration format is explained in this README, as well as in the README of individual roles linked in this document
  • run ./deploy.sh
  • enjoy?

Your server configuration folder should look like this in the end:

  • config.yml
  • deploy.sh
  • roles/


We currently support the following high-level services:

  • webserver (docs, todo): setup static websites (with git source and build command) or reverse proxies, with automatic TLS/Tor support
  • WIP mailserver (docs, todo): setup mailboxes and aliases, with automatic TLS/Tor support
  • jabberserver (docs, todo): setup MUC servers and/or anonymous/guest vhosts, with automatic TLS/Tor support
  • chatbridge (docs): a bot to bridge connections across instant messaging networks (IRC, Matrix, Jabber/XMPP) such as matterbridge

Some roles are intended as building blocks for other roles, though they may come in handy in specific situations:

  • tls: request a TLS certificate from letsencrypt for a domain, and optionally some aliases (docs, todo)
  • tor: setup a Tor onion service acting as a reverse proxy for a local service (docs, todo)

Some additional roles we'd like to support in the future:

  • nameserver: setup primary/secondary DNS server

There is also some roles acting as package managers, as explained later in this document.


The configuration file from the server is config.yml. In addition to specific role configuration, there's a number of high-level settings in there, explained in this section.

Base settings

In order to operate properly, the server needs a certain number of base settings:

  • hostname: the main domain name for the server
  • aliases: a list of domain names also vaild for this server, which will be included in the main TLS certificate
  • contact: contact information used by some roles
    • email: a list of contact emails (default: contact@ followed by hostname)
    • xmpp_muc: a list of Jabber/XMPP chatrooms (default: None)
    • xmpp_users: a list of Jabber/XMPP users (default: None)


TODO: Package managers should be better documented and their interface standardized. WTF does go not accept https://github.com/ as valid repository source and require to strip the scheme?

The configuration file contains a packages field, which is a mapping of package managers to a list of packages for them to install. How the list of packages is treated may be different for every package manager. For example:

  debian: [ "tmux" ]
    - "lsd"
    - bin: "zola"
      repo: "https://github.com/southerntofu/zola"
      version: "bugfix-index-translations"

This configuration snippet above will setup three packages:

Internally, every package manager is a role prefixed by a dot, to avoid confusion with other roles (services). We currently support the following package managers:

Note: .common is a reserved role name, and cannot be used for a common package manager.


The configuration file has a services field, which is a list of services (roles) to setup on the server. In most cases, it should contain the .common role, which will perform the base setup. For example:

  - ".common"
  - "webserver"

This snippet above will configure the base server, as well as a webserver. The webserver configuration, like any other service configuration, is kept in a separate field so the services remains human-readable. The field containing the configuration for a specific service wears the same name as the service (role) itself. For example, webserver configuration lives in a webserver field in the configuration file. Inside a service configuration, global settings are usually defined in a settings key, for example webserver.settings.


Most services can be configured to serve different domains/users. These specific configuration blocks are separated into what we call virtualhosts, or vhosts for short. Each such vhost for a service is configured in the vhosts list, inside the service configuration block. For example, webserver.vhosts. How to configure a vhost for a specific service is left to interpretation, and you should refer to service docs in order to find out what kind of settings a vhost may accept/require, and what the service will do with those settings.

Note: Some services may use similar concepts, though not called "vhosts". For example, chatbridge service uses chans for multiple configurations.


A service may support different use-cases for each vhost. While these are usually defined using the template setting of a vhost, we provide a high-level shorthand method for defining separate profiles without typing it out for each individual vhost. Each service profile is a top-level configuration key inside the service configuration, wearing the name of the service profile, and containing a list of vhosts which will be loaded with template set to this profile name. Take the following configuration snippet:

    - host: "example.org"
      template: "static"
      git: "https://git.example.org/foo/bar"
    - host: "example.net"
      template: "static"
      git: "https://git.example.net/foo/bar"

The above snippet is strictly equivalent to:

    - host: "example.org"
      git: "https://git.example.org/foo/bar"
    - host: "example.net"
      git: "https://git.example.net/foo/bar"


A deploy.sh script is provided to make deploying easier. It's intended to be run as root from the server itself, and optionally accepts positional arguments representing a list of services to (re)configure, instead of following the services list defined in the configuration file:

# # Setup the server according to config.yml
# ./deploy.sh
# # Only reconfigure webserver
# ./deploy.sh webserver


This document is the top-level documentation. In addition, you may find documentation about:

Copyleft (license)

This project is protected by AGPLv3 license. We believe the fruit of human labor should belong to humanity as a whole, and privatization of resources and knowledge is harmful. If you don't have time to read the full license, you may:

  • redistribute this project with or without further modification, under the same license
  • use this project to serve your personal needs, without restriction (if the user-facing services are used by anyone else but you, it is not considered personal usage and falls under the next category)
  • use this project to help/serve other persons, under the condition that you share every modification publicly under the same license