Add an application
This chapter tells a maintainer how to add an application that operators can deploy from the panel, such as Mastodon, PeerTube or Pixelfed. The maintainer guide tells how to check, deploy and test the change after you add it.
Use Pixelfed as an example: core/components/operator/pixelfed/ has each part
that this chapter names. In this chapter, <app> is the name of the new
application, in lowercase, for example pixelfed.
What you do not change
The data model makes most of the application from one component. From
components.<app>, the code makes these items, and you do not edit them:
- The operator option
applications.<app>, from themoduleof the component. - The form of the panel and the JSON schema of the API, through
core/applications-type.nix. - The catalog of the API, with the title, description, home page and icon,
through
core/applications-catalog.nix. - The NixOS system
nixosConfigurations.operator-<app>and the deploy attributesoperator-tf-<app>andoperator-tf-incus-<app>, from the node in the roster (see Add the node). - The DNS names, from the
domainandsubdomainoptions.
The panel and the API have no code for each application. The panel keeps the configuration of a deployment as JSON, thus a new application needs no database migration.
The data model page tells what each field of a component does.
Write the component
-
If upstream publishes a JSON schema of its configuration, pin it with
npins, aspixelfed-config-schemainnpins/sources.json. If the nixpkgs package needs a fix, add an overlay innix/overlays/<app>.nix, and add it tonix/overlays/default.nix. -
Make
core/components/operator/<app>/default.nix. It setscomponents.<app>:components.<app> = {
inherit name;
package = pkgs.<app>;
artwork = ./artwork.nix;
optional = true;
module = import ../../nixosService.nix { ... };
implementation = cfg: lib.optionalAttrs cfg.enable { ... };
};-
descriptionandhomepagecome frompackage.metaif you do not set them. -
artworkis the path of a file in this repository that gives the logo of the application. Use the logo that the upstream project supplies:# core/components/operator/<app>/artwork.nix
{ pkgs, ... }:
{
icon = "${pkgs.<app>.src}/<path to the logo>.svg";
# Optional: a variant for dark backgrounds.
# iconDark = "${pkgs.<app>.src}/<path to the dark logo>.svg";
} -
moduledeclares the options that the operator sets.core/components/nixosService.nixmakes it fromsharedOptions.nix, which givesenable,subdomainanddomain, and from the upstreamservices.<app>options that you name inexpose. Name only the options that are the decision of the operator. If an option inexposedoes not exist, the evaluation fails. -
implementationchanges the settings of the operator into requests for resources. Each attribute is a named group with one request, of a resource incore/resources/:Need Request Single sign-on "<app>-oidc".oidcEmail "<app>-smtp".smtpCache "<app>-cache".redisDatabase "<app>-db".postgresqlObject storage and a backup "<app>-bucket".garage, with the helpers ofcore/components/operator/app-resources.nixTLS certificate "tls".ssl.domains = [ cfg.domain ];Open ports "web".firewall.publicTCPPorts = [ 80 443 ];Workload identity "spiffe".spiffe.enable = true;Generated secrets "vars-backend".generateFiles.instances.<app>-appThe other NixOS settings "<name>".nixos-module.moduleA request can have a
nixos-configurationfunction. It gets the result of the resource, for example the OIDC client secret, and sets the NixOS options of the application from it. The hosting resources page lists the options of each request.
-
-
Add
./<app>to theimportsofcore/components/operator/default.nix.
Add the node
Each application runs on its own node. Add the node to the roster in
core/setups/groups/operator.nix, in machines.published:
{
pixelfed = 54;
peertube = 55;
mastodon = 56;
<app> = 57;
}
The name of the node must be the name of the component. The number gives the
documentation addresses 192.0.2.<n> and 2001:db8::<n>, which a deploy
replaces. Use a number that no other node uses.
If you do not add the node, the application is in the form, but a deploy does not deploy it, and no check fails.
Then add the application at this location:
core/default-configuration.json: add"<app>": { "enable": false }, so that the default configuration has each application off.
Audit the options
core/components/operator/operator-facing-options.csv has one row for each
setting of each application. Each row tells if the setting is for the operator
or for Fediversity. Add a row for each services.<app> option, and for each
key of the upstream configuration. A row can use a trailing * for a group of
keys. Use this audit to select the options in expose, and the settings that
the form shows.
Then add the version that you audited to the list in the operator configuration page.
The build does not read the file, thus no check finds a missing row.
Add the checks
-
Make
core/components/operator/<app>/test.nix. It callsmkAppTestfromcore/components/operator/testing/lib.nix, which deploys the application on one node, with an SSO provider, a mail relay, a directory and object storage beside it. Add a test script that logs in and uses the application. -
In
core/checks/default.nix, add the test as a check, and give it a description:test-<app>-service = runNixOSTest {
imports = [ ../components/operator/<app>/test.nix ];
_module.args.sources = sources;
};The description becomes the
meta.descriptionof the check, which the flake attributes page shows. No check finds a missing description. -
In
core/checks/ci.nix, tell CI where to run the check, and on which changes. Copy the entry oftest-pixelfed-service. If a check has no entry, the evaluation fails. -
In
.forgejo/workflows/nix-flake-check.sh, add a case foroperator-<app>besideoperator-pixelfed. Without it, CI builds the node on each change of the repository. -
Make the CI workflows again:
bash .forgejo/workflows/nix-flake-check.shThis adds
checks-test-<app>-service.yaml, and a job for the node innixosConfigurations-operator.yaml. CI fails if the workflows are not up to date.
The apps-tf, apps-tf-incus and apps-api tests deploy only Pixelfed, as a
sample of all applications. You do not change them.
Update the specifications and the documentation
No check finds these, thus look at each one:
- Add
core/specs/008-components/operator/<app>.md, aspixelfed.md. - In the components specification, add the application to FR-004 and to the index of components.
- In the operator configuration page and in the concepts page, add the application to the lists of applications.
Check the result
Do the steps of Check a change without a deploy in the maintainer guide:
nix build ./core#nixosConfigurations.operator-<app>.config.system.build.toplevel
nix build ./core#checks.x86_64-linux.test-<app>-service
Then test the operator branch from the panel: the form shows the new application from the schema of your branch.