## Actors
- Maintainers
The group maintaining this repository.
We are creating the deployment workflows and service configurations, and curate changes proposed by contributing developers.
- Developers
People with the technical background to engage with our work, and may contribute back, build on top of, remix, or feel inspired by our work to create something better.
- Hosting provider
They provide and maintain the physical infrastructure, and run the software in this repository, through which operators interact with their deployments.
Hosting providers are technical administrators for these deployments, ensuring availability and appropriate performance.
We target small- to medium-scale hosting providers with 20+ physical machines.
- Operator
They select the applications they want to run.
They don't need to own hardware or deal with operations.
Operators administer their applications in a non-technical fashion, e.g. as moderators.
They pay the hosting provider for registering a domain name, maintaining physical resources, and monitoring deployments.
- User
They are individuals using applications run by the operators, and e.g. post content.
## Glossary
- [Fediverse](https://en.wikipedia.org/wiki/Fediverse)
A collection of social networking applications that can communicate with each other using a common protocol.
- Application
User-facing software (e.g. from Fediverse) configured by operators and used by users.
- Configuration
A collection of settings for a piece of software.
> Example: Configurations are deployed to VMs.
- Provision
Make a resource, such as a virtual machine, available for use.
- Deploy
Put software onto computers.
The software includes technical configuration that links software components.
- Migrate
Move service configurations and deployment (including user data) from one hosting provider to another.
- Resource
A [resource for NixOps4](https://nixops.dev/manual/development/concept/resource.html) is any external entity that can be declared with NixOps4 expressions and manipulated with NixOps4, such as a virtual machine, an active NixOS configuration, a DNS entry, or customer database.
- Resource provider
A resource provider for NixOps4 is an executable that communicates between a resource and NixOps4 using a standardised protocol, allowing [CRUD operations](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) on the resources to be performed by NixOps4.
Refer to the [NixOps4 manual](https://nixops.dev/manual/development/resource-provider/index.html) for details.
> Example: We need a resource provider for obtaining deployment secrets from a database.
- Runtime backend
A type of digital environment one can run operating systems such as NixOS on, e.g. bare-metal, a hypervisor, or a container runtime.
- Runtime environment
The thing a deployment runs on, an interface against which the deployment is working. See runtime backend.
- Runtime config
Configuration logic specific to a runtime backend, e.g. how to deploy, how to access object storage.
## Technologies used
### [NixOS](https://nixos.org/)
NixOS is a Linux distribution with a [vibrant](https://repology.org/repositories/graphs), [reproducible](https://reproducible.nixos.org/) and [security-conscious](https://tracker.security.nixos.org/) ecosystem.
As such, we see NixOS as the only viable way to reliably create a reproducible outcome for all the work we create.
Considered alternatives include:
- containers: do not by themselves offer the needed reproducibility
#### [npins](https://github.com/andir/npins)
Npins is a dependency pinning tool for Nix which leaves recursive dependencies explicit, keeping the consumer in control.
Considered alternatives include:
- Flakes: defaults to implicitly following recursive dependencies, leaving control with the publisher.
### [SelfHostBlocks](https://nlnet.nl/project/SelfHostBlocks/)
SelfHostBlocks offers Nix module contracts to decouple application configuration from implementation details, empowering user choice by providing sane defaults yet a [unified interface](https://nlnet.nl/project/SelfHostBlocks/).
Offered contracts include back-ups, reverse proxies, single sign-on and LDAP.
In addition, we have been in contact with its creator.
Considered alternatives include:
- nixpkgs-provided NixOS service modules: support far more applications, but tightly coupled with service providers, whereas we expect them to [sooner or later](https://discourse.nixos.org/t/pre-rfc-decouple-services-using-structured-typing/58257) follow suit.
- NixOS service modules curated from scratch: would support any setup imaginable, but does not seem to align as well with our research-oriented goals.
### [OpenTofu](https://opentofu.org/)
OpenTofu is the leading open-source framework for infrastructure-as-code.
This has led it to offer a vibrant ecosystem of 'provider' plugins integrating various programs and services.
As such, it can facilitate automated deployment pipelines, including with — relevant to our project — hypervisors and DNS programs.
Considered alternatives include:
- Terraform: not open-source
### [Proxmox](https://proxmox.com/)
Proxmox is a hypervisor, allowing us to create VMs for our applications while adhering to our goal of preventing lock-in.
In addition, it has been [packaged for Nix](https://github.com/SaumonNet/proxmox-nixos) as well, simplifying our requirements to users setting up our software.
Considered alternatives include:
- OpenNebula: seemed less mature
### [Garage](https://garagehq.deuxfleurs.fr/)
Garage is a distributed object storage service.
For compatibility with existing clients, it reuses the protocol of Amazon S3.
Considered alternatives include:
- file storage: less centralized for backups
### [PostgreSQL](https://www.postgresql.org/)
PostgreSQL is a relational database.
It is used by most of our applications.
Considered alternatives include:
- Sqlite: default option for development in many applications, but less optimized for performance, and less centralized for backups
### [Valkey](https://valkey.io/)
Valkey is a key-value store.
It is an open-source fork of Redis.
Considered alternatives include:
- Redis: not open-source
### [OpenSearch](https://opensearch.org/)
OpenSearch offers full-text search, and is used for this in many applications.
It is an open-source fork of ElasticSearch.
Considered alternatives include:
- ElasticSearch: not open-source
### [OctoDNS](https://github.com/octodns/octodns)
OctoDNS is a DNS server that may be configured using the Nix-native [NixOS-DNS](https://janik-haag.github.io/NixOS-DNS/).
Considered alternatives include:
- PowerDNS: offers a front-end option, but less geared toward the use-case of configuring by Nix
### [Authelia](https://github.com/authelia/authelia)
Authelia is a single sign-on provider that integrates with LDAP.
Considered alternatives include:
- KaniDM: does not do proper LDAP
- Authentik: larger package with focus on many things we do not need
- Keycloak: larger package with focus on many things we do not need
### [lldap](https://github.com/lldap/lldap)
Lldap is a light LDAP server, allowing to centralize user roles across applications.
Considered alternatives include:
- 389 DS: older larger package
- FreeIPA: wrapper around 389 DS
### [Attic](https://github.com/zhaofengli/attic)
Attic is a multi-tenant Nix cache featuring recency-based garbage collection written in Rust.
Considered alternatives include:
- cache-server: distributed cache written in Python that seems more of a research project than an actively maintained repository.
## Architecture
At the core of Fediversity lies a NixOS configuration module for a set of selected applications.
We will support using it with different run-time environments, such as a single NixOS machine or a ProxmoX hypervisor.
Depending on the targeted run-time environment, deployment will further involve OpenTofu as an orchestrator.
We further provide a [reference front-end](https://git.fediversity.eu/Fediversity/Fediversity/src/branch/main/panel) to configure applications.
To ensure reproducibility, we also offer Nix packaging for our software.
To reach our goals, we aim to implement the following interactions between [actors](#actors) (depicted with rounded corners) and system components (see the [glossary](#glossary), depicted with rectangles).

### Service portability
The process of migrating one's applications to a different host encompasses:
1. domain registration: involves a (manual) update of DNS records at the registrar
1. deployed applications: using the reproducible configuration module
1. application data:
- back-up/restore scripts [using SelfHostBlocks](https://shb.skarabox.com/contracts.html)
- application-specific migration scripts, to e.g. reconfigure of connections/URLs
### Data model
Whereas the bulk of our configuration logic is covered in the configuration schema, our reference front-end application does in fact store data.
The design for its data model to support the desired functionality is as follows, using the crow's foot notation to denote cardinality:
### Host architecture
Whereas the core abstraction in Fediversity is a NixOS configuration module, a more full-fledged example architecture of the web host use-case we aim to support as part of our exploitation would be as follows, where VMs in question run Fediversity to offer our selected applications:

## Break-down of project milestones
Whereas details of the implementation may need to be decided as the technical challenges involved become clear, we can already give a higher-level planning of relevant milestones and some of their salient features:
1. [implement a way to run online services emphasising user autonomy and data portability](https://git.fediversity.eu/Fediversity/Fediversity/issues/347)
1. [Finalize architecture doc](https://git.fediversity.eu/Fediversity/Fediversity/issues/39)
1. [code-based migration data model](https://git.fediversity.eu/Fediversity/Fediversity/issues/103)
1. [migrating application data between hosting providers](https://git.fediversity.eu/Fediversity/Fediversity/issues/100)
1. [code-based migration data model](https://git.fediversity.eu/Fediversity/Fediversity/issues/103)
1. [enable back-ups of application](https://git.fediversity.eu/Fediversity/Fediversity/issues/123)
1. [Create a deployment migration string](https://git.fediversity.eu/Fediversity/Fediversity/issues/77)
1. [Start deployment migration](https://git.fediversity.eu/Fediversity/Fediversity/issues/78)
1. [application offering generalised](https://git.fediversity.eu/Fediversity/Fediversity/issues/369)
1. [NixOS configuration as the core abstraction](https://git.fediversity.eu/Fediversity/Fediversity/issues/339)
1. [disseminate our results by engaging the open-source community to further expand on work in this direction](https://git.fediversity.eu/Fediversity/Fediversity/issues/348)
1. [automated dev-ops workflows](https://git.fediversity.eu/Fediversity/Fediversity/issues/224)
1. [Backups for Forgejo](https://git.fediversity.eu/Fediversity/Fediversity/issues/29)
1. [use dedicated Nix builder](https://git.fediversity.eu/Fediversity/Fediversity/issues/366)
1. [initial focus on single application for development](https://git.fediversity.eu/Fediversity/Fediversity/issues/327)
1. [unify versioning](https://git.fediversity.eu/Fediversity/Fediversity/issues/279)
1. [Automated dependency updates](https://git.fediversity.eu/Fediversity/Fediversity/issues/65)
1. [infrastructure automatically deployed using continuous deployment](https://git.fediversity.eu/Fediversity/Fediversity/issues/177)
1. [Full integration test](https://git.fediversity.eu/Fediversity/Fediversity/issues/277)
1. [CI rejects failing deployments](https://git.fediversity.eu/Fediversity/Fediversity/issues/102)
1. [code reviewers can suggest changes](https://git.fediversity.eu/Fediversity/Fediversity/issues/302)
1. [fediversity apps reused in infra](https://git.fediversity.eu/Fediversity/Fediversity/issues/370)
1. [derive users and their keys from the keys directory](https://git.fediversity.eu/Fediversity/Fediversity/issues/199)
1. [Nix package overlays upstreamed](https://git.fediversity.eu/Fediversity/Fediversity/issues/248)
1. [Separate test environments for staging vs. production](https://git.fediversity.eu/Fediversity/Fediversity/issues/69)
1. [support password-protected personal SSH keys for deploying services in development](https://git.fediversity.eu/Fediversity/Fediversity/issues/272)
1. [Write all modules with destructured arguments](https://git.fediversity.eu/Fediversity/Fediversity/issues/93)
1. [ephemeral state is automatically provisioned](https://git.fediversity.eu/Fediversity/Fediversity/issues/314)
1. [external developers empowered to contribute](https://git.fediversity.eu/Fediversity/Fediversity/issues/288)
1. [code reviewers can suggest changes](https://git.fediversity.eu/Fediversity/Fediversity/issues/302)
1. [Reproducible proxmox installation](https://git.fediversity.eu/Fediversity/Fediversity/issues/325)
1. [Continuous Integration builds available in a public cache](https://git.fediversity.eu/Fediversity/Fediversity/issues/92)
1. [docs: document having to load nix dev shell for pre-commit hook](https://git.fediversity.eu/Fediversity/Fediversity/issues/98)
1. [Update documentation on services](https://git.fediversity.eu/Fediversity/Fediversity/issues/86)
1. [knowledge base](https://git.fediversity.eu/Fediversity/Fediversity/issues/243)
1. [Document the semantics of our various domains](https://git.fediversity.eu/Fediversity/Fediversity/issues/210)
1. [Describe the hardware infrastructure needed to run Fediversity yourself](https://git.fediversity.eu/Fediversity/Fediversity/issues/68)
1. [reproducible project infrastructure](https://git.fediversity.eu/Fediversity/Fediversity/issues/336)
1. [NixOS configuration as the core abstraction](https://git.fediversity.eu/Fediversity/Fediversity/issues/339)
1. [fediversity apps reused in infra](https://git.fediversity.eu/Fediversity/Fediversity/issues/370)
1. [Generate documentation on the deployments from the code](https://git.fediversity.eu/Fediversity/Fediversity/issues/89)
1. [Write all modules with destructured arguments](https://git.fediversity.eu/Fediversity/Fediversity/issues/93)
1. [module upstreamed to nixpkgs](https://git.fediversity.eu/Fediversity/Fediversity/issues/333)
1. [panel bundled into Fediversity configuration](https://git.fediversity.eu/Fediversity/Fediversity/issues/342)
1. [exploit our work by enabling reproducible deployments of an initial set of portable applications](https://git.fediversity.eu/Fediversity/Fediversity/issues/349)
1. [applications deployed on command](https://git.fediversity.eu/Fediversity/Fediversity/issues/99)
1. [ProxmoX back-end supports multiple users](https://git.fediversity.eu/Fediversity/Fediversity/issues/313)
1. [Proxmox resources are provisioned to deploy services to](https://git.fediversity.eu/Fediversity/Fediversity/issues/116)
1. [Deployed services are accessible under the configured domain](https://git.fediversity.eu/Fediversity/Fediversity/issues/76)
1. [kick-started initial feedback cycle](https://git.fediversity.eu/Fediversity/Fediversity/issues/225)
1. [ProxmoX back-end supports multiple users](https://git.fediversity.eu/Fediversity/Fediversity/issues/313)
1. [Proxmox resources are provisioned to deploy services to](https://git.fediversity.eu/Fediversity/Fediversity/issues/116)
1. [Users can configure their desired sub-domains in the online panel, so that the deployed services are assigned the desired sub-domains](https://git.fediversity.eu/Fediversity/Fediversity/issues/142)
1. [provision admin accounts for deployed services](https://git.fediversity.eu/Fediversity/Fediversity/issues/178)
1. [users can update their deployment configurations](https://git.fediversity.eu/Fediversity/Fediversity/issues/158)
1. [use immutable buckets from VMs](https://git.fediversity.eu/Fediversity/Fediversity/issues/185)
1. [Databases are provisioned so that services can use a central storage](https://git.fediversity.eu/Fediversity/Fediversity/issues/115)
1. [VMs use central file storage](https://git.fediversity.eu/Fediversity/Fediversity/issues/138)
1. [reproduce DNS VM](https://git.fediversity.eu/Fediversity/Fediversity/issues/200)
1. [SMTP service is provisioned so that applications can send emails](https://git.fediversity.eu/Fediversity/Fediversity/issues/117)
1. [fediversity apps reused in infra](https://git.fediversity.eu/Fediversity/Fediversity/issues/370)
1. [ephemeral state is automatically provisioned](https://git.fediversity.eu/Fediversity/Fediversity/issues/314)
1. [panel staging/production configuration](https://git.fediversity.eu/Fediversity/Fediversity/issues/136)
1. [code passes security check](https://git.fediversity.eu/Fediversity/Fediversity/issues/291)
1. [brought into production](https://git.fediversity.eu/Fediversity/Fediversity/issues/228)
1. [Have a DNS service running to allow users to tie services to their own domain](https://git.fediversity.eu/Fediversity/Fediversity/issues/104)
1. [garbage collection of unallocated resources](https://git.fediversity.eu/Fediversity/Fediversity/issues/188)
1. [Relevant email accounts are provisioned such that the operator may be contacted](https://git.fediversity.eu/Fediversity/Fediversity/issues/118)
1. [reference front-end is decoupled from version of configuration module](https://git.fediversity.eu/Fediversity/Fediversity/issues/304)
1. [specification published](https://git.fediversity.eu/Fediversity/Fediversity/issues/334)
1. [REST API available](https://git.fediversity.eu/Fediversity/Fediversity/issues/368)
1. [Hosting providers can update their operators' deployments](https://git.fediversity.eu/Fediversity/Fediversity/issues/159)
1. [code passes security check](https://git.fediversity.eu/Fediversity/Fediversity/issues/291)
1. [nix-less bootstrap](https://git.fediversity.eu/Fediversity/Fediversity/issues/332)
1. [key features improving user experience supported](https://git.fediversity.eu/Fediversity/Fediversity/issues/289)
1. [upstream configuration options exposed](https://git.fediversity.eu/Fediversity/Fediversity/issues/195)
1. [allow disabling service while retaining data](https://git.fediversity.eu/Fediversity/Fediversity/issues/186)
1. [enqueuing deployment syncs](https://git.fediversity.eu/Fediversity/Fediversity/issues/242)
1. [user can have multiple deployments](https://git.fediversity.eu/Fediversity/Fediversity/issues/241)
1. [ProxmoX deployment allows scaling resources assigned to a VM](https://git.fediversity.eu/Fediversity/Fediversity/issues/119)
1. [View difference between configured and deployed state](https://git.fediversity.eu/Fediversity/Fediversity/issues/143)
1. [visualise schema changes](https://git.fediversity.eu/Fediversity/Fediversity/issues/213)
1. [aid needed actions on schema update](https://git.fediversity.eu/Fediversity/Fediversity/issues/214)
1. [single sign-on (SSO) for services](https://git.fediversity.eu/Fediversity/Fediversity/issues/212)
1. [delegating user management](https://git.fediversity.eu/Fediversity/Fediversity/issues/337)
1. [pooling instances to shared VMs](https://git.fediversity.eu/Fediversity/Fediversity/issues/322)
1. [on migration, allow reconfiguring monolithic vs distributed](https://git.fediversity.eu/Fediversity/Fediversity/issues/341)
1. [connecting an existing identity management service](https://git.fediversity.eu/Fediversity/Fediversity/issues/161)