Skip to content

Running Mobilizon on NixOS

The NixOS module for Mobilizon is a community maintained way of installing and running Mobilizon. It allows for trouble-less installation and maintenance, though new versions might take a few days to reach the NixOS channels. Also if you use a stable channel like NixOS 23.11, you'd only receive security updates and patch releases.

This guide assumes some knowledge about NixOS:

  • Rudimentary understanding of the Nix configuration language
  • How to add configuration to /etc/nixos/configuration.nix
  • How to rebuild your system


  • A NixOS machine running nixos-unstable or at least the NixOS 23.11 stable release, with a publicly routable IPv4 address.
  • A domain name (or subdomain) for the Mobilizon server, e.g., pointing A (and optionally AAAA) records to your IP addresses.
  • An SMTP server to deliver emails


Setting up the installation is entirely done by configuring the service in your system definition. No commands need to be entered or other configuration files need to be touched, except for optionally providing a SMTP password.

Use this configuration and edit it according to your needs.

{ config, lib, pkgs, ... }: {

  services.mobilizon = {
    enable = true;
    settings =
        # These are helper functions, that allow us to use all the features of the Mix configuration language.
        # - mkAtom and mkRaw both produce "raw" strings, which are not enclosed by quotes.
        # - mkGetEnv allows for convenient calls to System.get_env/2
        inherit ((pkgs.formats.elixirConf { }).lib) mkAtom mkRaw mkGetEnv;
          ":mobilizon" = {

            # General information about the instance
            ":instance" = {
              name = "My mobilizon instance";
              description = "A descriptive text that is going to be shown on the start page.";
              hostname = "";
              email_from = "";
              email_reply_to = "";

            # SMTP configuration
            "Mobilizon.Web.Email.Mailer" = {
              adapter = mkAtom "Swoosh.Adapters.SMTP";
              relay = "your.smtp.server";
              # usually 25, 465 or 587
              port = 587;
              username = "";
              # See "Providing a SMTP password" below
              password = mkGetEnv { envVariable = "SMTP_PASSWORD"; };
              tls = mkAtom ":always";
              allowed_tls_versions = [
                (mkAtom ":tlsv1")
                (mkAtom ":\"tlsv1.1\"")
                (mkAtom ":\"tlsv1.2\"")
              retries = 1;
              no_mx_lookups = false;
              auth = mkAtom ":always";


  # In order for Nginx to be publicly accessible, the firewall needs to be configured.
  networking.firewall.allowedTCPPorts = [
    80  # HTTP
    443 # HTTPS

  # For using the Let's Encrypt TLS certificates for HTTPS,
  # you have to accept their TOS and supply an email address.
  security.acme = {
    acceptTerms = true; = "";


This will by default setup a Nginx proxy, fetch Let's Encrypt certificates for HTTPS, generate secrets and provision a PostgreSQL database on the local system.

Provide the SMTP password

You can just provide the SMTP password by setting services.mobilizon.settings.":mobilizon"."Mobilizon.Web.Email.Mailer".password, but putting a password into the Nix config is discouraged, as this secret will then end up world readable. Best is to read it at runtime, by using the config from above, activate the system once and then add the following line to /var/lib/mobilizon/

export SMTP_PASSWORD=yoursupersecretpassword

Set additional Mix configuration options

The services.mobilizon.settings attribute set directly translates to the Mix configuration file, so you can set all kinds of options. See the module options for provided defaults.


The following locations need to be backed up to be able to fully recover an instance after data loss:

  • The directory /var/lib/mobilizon containing uplodaded pictures and generated secrets.
  • The PostgreSQL database mobilizon_prod, e.g. by setting up services.postgresqlBackup and then backing up the file in /var/backup/postgresql.

Using a remote PostgreSQL database

By default, the module automatically provisions a local PostgreSQL database called mobilizon_prod.

The following config configures Mobilizon to use a remote PostgreSQL database, using TLS client certificates:

{ config, lib, pkgs, ... }: {

  services.mobilizos.settings."Mobilizon.Storage.Repo" = let
    inherit ((pkgs.formats.elixirConf { }).lib) mkAtom mkRaw mkGetEnv;
  in {
    socket_dir = null;
    hostname = "hostname.of.your.db";
    username = "username";
    database = "databasename";
    ssl = true;
    ssl_opts = {
      "cacertfile" = "${./ca.crt}";
      "certfile" = "/var/lib/mobilizon/client.crt";
      "keyfile" = "/var/lib/mobilizon/client.key";
      "verify" = mkAtom ":verify_peer";
      # This needs to wrapped in single ticks, therefore the mkRaw call.
      "server_name_indication" = mkRaw "''";
    show_sensitive_data_on_connection_error = true;


This won't setup a local PostgreSQL database then, but also won't delete one already created.

Last update: September 12, 2023