mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-14 06:00:33 +03:00
plausible: init at 1.3.0
This commit is contained in:
parent
fea2b25c74
commit
b06ea1146c
11 changed files with 16591 additions and 0 deletions
270
nixos/modules/services/web-apps/plausible.nix
Normal file
270
nixos/modules/services/web-apps/plausible.nix
Normal file
|
@ -0,0 +1,270 @@
|
|||
{ lib, pkgs, config, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.plausible;
|
||||
|
||||
envSecrets = ''
|
||||
export ADMIN_USER_PWD="$(<${cfg.adminUser.passwordFile})"
|
||||
export SECRET_KEY_BASE="$(<${cfg.server.secretKeybaseFile})"
|
||||
export RELEASE_TMP=/var/lib/plausible/tmp
|
||||
${optionalString (cfg.mail.smtp.passwordFile != null) ''
|
||||
export SMTP_USER_PWD="$(<${cfg.mail.smtp.passwordFile})"
|
||||
''}
|
||||
'';
|
||||
in {
|
||||
options.services.plausible = {
|
||||
enable = mkEnableOption "plausible";
|
||||
|
||||
adminUser = {
|
||||
name = mkOption {
|
||||
default = "admin";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Name of the admin user that plausible will created on initial startup.
|
||||
'';
|
||||
};
|
||||
|
||||
email = mkOption {
|
||||
type = types.str;
|
||||
example = "admin@localhost";
|
||||
description = ''
|
||||
Email-address of the admin-user.
|
||||
'';
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.either types.str types.path;
|
||||
description = ''
|
||||
Path to the file which contains the password of the admin user.
|
||||
'';
|
||||
};
|
||||
|
||||
activate = mkEnableOption "activating the freshly created admin-user";
|
||||
};
|
||||
|
||||
database = {
|
||||
clickhouse = {
|
||||
setup = mkEnableOption "creating a clickhouse instance" // { default = true; };
|
||||
url = mkOption {
|
||||
default = "http://localhost:8123/default";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The URL to be used to connect to <package>postgres</package>. The format
|
||||
is described in <link xlink:href="https://hexdocs.pm/ecto/Ecto.Repo.html#module-urls">
|
||||
the elixir docs</link>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
postgres = {
|
||||
setup = mkEnableOption "creating a postgresql instance" // { default = true; };
|
||||
dbname = mkOption {
|
||||
default = "plausible";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Name of the database to use.
|
||||
'';
|
||||
};
|
||||
socket = mkOption {
|
||||
default = "/run/postgresql";
|
||||
type = types.str;
|
||||
description = ''
|
||||
Path to the UNIX domain-socket to communicate with <package>postgres</package>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
server = {
|
||||
disableRegistration = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Whether to prohibit creating an account in plausible's UI.
|
||||
'';
|
||||
};
|
||||
secretKeybaseFile = mkOption {
|
||||
type = types.either types.path types.str;
|
||||
description = ''
|
||||
Path to the secret used by the <literal>phoenix</literal>-framework. Instructions
|
||||
how to generate one are documented in the
|
||||
<link xlink:href="https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Secret.html#content">
|
||||
framework docs</link>.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
default = 8000;
|
||||
type = types.port;
|
||||
description = ''
|
||||
Port where the service should be available.
|
||||
'';
|
||||
};
|
||||
baseUrl = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Public URL where plausible is available.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
mail = {
|
||||
email = mkOption {
|
||||
default = " hello@plausible.local";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The email id to use for as <emphasis>from</emphasis> address of all communications
|
||||
from Plausible.
|
||||
'';
|
||||
};
|
||||
smtp = {
|
||||
hostAddr = mkOption {
|
||||
default = "localhost";
|
||||
type = types.str;
|
||||
description = ''
|
||||
The host address of your smtp server.
|
||||
'';
|
||||
};
|
||||
hostPort = mkOption {
|
||||
default = 25;
|
||||
type = types.port;
|
||||
description = ''
|
||||
The port of your smtp server.
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
The username/email in case SMTP auth is enabled.
|
||||
'';
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
default = null;
|
||||
type = with types; nullOr (either str path);
|
||||
description = ''
|
||||
The path to the file with the password in case SMTP auth is enabled.
|
||||
'';
|
||||
};
|
||||
enableSSL = mkEnableOption "";
|
||||
retries = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 2;
|
||||
description = ''
|
||||
Number of retries to make until mailer gives up.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = cfg.adminUser.activate -> cfg.database.postgres.setup;
|
||||
message = ''
|
||||
Unable to automatically activate the admin-user if no local DB-managed for
|
||||
postgres (`services.plausible.database.postgres.setup') is enabled!
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
services.postgresql = mkIf cfg.database.postgres.setup {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
services.clickhouse = mkIf cfg.database.clickhouse.setup {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
systemd.services = mkMerge [
|
||||
{
|
||||
plausible = {
|
||||
inherit (pkgs.plausible.meta) description;
|
||||
documentation = [ "https://plausible.io/docs/self-hosting" ];
|
||||
wantedBy = [ "multi-user.target" ]
|
||||
++ optional cfg.database.clickhouse.setup "clickhouse.service"
|
||||
++ optional cfg.database.postgres.setup "postgresql.service";
|
||||
after = optional cfg.database.postgres.setup "plausible-postgres.service";
|
||||
|
||||
environment = {
|
||||
# NixOS specific option to avoid that it's trying to write into its store-path.
|
||||
# See also https://github.com/lau/tzdata#data-directory-and-releases
|
||||
PLAUSIBLE_TZDATA = "/var/lib/plausible/elixir_tzdata";
|
||||
|
||||
# Configuration options from
|
||||
# https://plausible.io/docs/self-hosting-configuration
|
||||
PORT = toString cfg.server.port;
|
||||
DISABLE_REGISTRATION = boolToString cfg.server.disableRegistration;
|
||||
|
||||
ADMIN_USER_NAME = cfg.adminUser.name;
|
||||
ADMIN_USER_EMAIL = cfg.adminUser.email;
|
||||
|
||||
DATABASE_SOCKET_DIR = cfg.database.postgres.socket;
|
||||
DATABASE_NAME = cfg.database.postgres.dbname;
|
||||
CLICKHOUSE_DATABASE_URL = cfg.database.clickhouse.url;
|
||||
|
||||
BASE_URL = cfg.server.baseUrl;
|
||||
|
||||
MAILER_EMAIL = cfg.mail.email;
|
||||
SMTP_HOST_ADDR = cfg.mail.smtp.hostAddr;
|
||||
SMTP_HOST_PORT = toString cfg.mail.smtp.hostPort;
|
||||
SMTP_RETRIES = toString cfg.mail.smtp.retries;
|
||||
SMTP_HOST_SSL_ENABLED = boolToString cfg.mail.smtp.enableSSL;
|
||||
${if cfg.mail.smtp.user != null then "SMTP_USER_NAME" else null} = cfg.mail.smtp.user;
|
||||
};
|
||||
|
||||
path = [ pkgs.plausible ]
|
||||
++ optional cfg.database.postgres.setup config.services.postgresql.package;
|
||||
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
PrivateTmp = true;
|
||||
WorkingDirectory = "/var/lib/plausible";
|
||||
StateDirectory = "plausible";
|
||||
ExecStartPre = "@${pkgs.writeShellScript "plausible-setup" ''
|
||||
${envSecrets}
|
||||
${pkgs.plausible}/createdb.sh
|
||||
${pkgs.plausible}/migrate.sh
|
||||
${optionalString cfg.adminUser.activate ''
|
||||
if ! ${pkgs.plausible}/init-admin.sh | grep 'already exists'; then
|
||||
psql -d plausible <<< "UPDATE users SET email_verified=true;"
|
||||
fi
|
||||
''}
|
||||
''} plausible-setup";
|
||||
ExecStart = "@${pkgs.writeShellScript "plausible" ''
|
||||
${envSecrets}
|
||||
plausible start
|
||||
''} plausible";
|
||||
};
|
||||
};
|
||||
}
|
||||
(mkIf cfg.database.postgres.setup {
|
||||
# Unfortunately `plausible' requires super-user permissions in postgresql, so this
|
||||
# has to be done imperatively here.
|
||||
plausible-postgres = {
|
||||
after = [ "postgresql.service" ];
|
||||
bindsTo = [ "postgresql.service" ];
|
||||
requiredBy = [ "plausible.service" ];
|
||||
partOf = [ "plausible.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
if [ ! -e /var/lib/plausible/.db-setup ]; then
|
||||
mkdir -p /var/lib/plausible/
|
||||
PSQL() {
|
||||
/run/wrappers/bin/sudo -Hu postgres ${config.services.postgresql.package}/bin/psql --port=5432 "$@"
|
||||
}
|
||||
PSQL -tAc "CREATE EXTENSION IF NOT EXISTS citext;"
|
||||
PSQL -tAc "CREATE ROLE plausible WITH LOGIN;"
|
||||
PSQL -tAc "CREATE DATABASE plausible WITH OWNER plausible;"
|
||||
PSQL -tAc "ALTER USER plausible WITH SUPERUSER;"
|
||||
touch /var/lib/plausible/.db-setup
|
||||
fi
|
||||
'';
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ ma27 ];
|
||||
meta.doc = ./plausible.xml;
|
||||
}
|
51
nixos/modules/services/web-apps/plausible.xml
Normal file
51
nixos/modules/services/web-apps/plausible.xml
Normal file
|
@ -0,0 +1,51 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="module-services-plausible">
|
||||
<title>Plausible</title>
|
||||
<para>
|
||||
<link xlink:href="https://plausible.io/">Plausible</link> is a privacy-friendly alternative to
|
||||
Google analytics.
|
||||
</para>
|
||||
<section xml:id="module-services-plausible-basic-usage">
|
||||
<title>Basic Usage</title>
|
||||
<para>
|
||||
At first, a secret key is needed to be generated. This can be done with e.g.
|
||||
<prompt>$ openssl rand -base64 64</prompt>
|
||||
</para>
|
||||
<para>
|
||||
After that, <package>plausible</package> can be deployed like this:
|
||||
<programlisting>{
|
||||
services.plausible = {
|
||||
<link linkend="opt-services.plausible.enable">enable</link> = true;
|
||||
adminUser = {
|
||||
<link linkend="opt-services.plausible.adminUser.activate">activate</link> = true; <co xml:id='ex-plausible-cfg-activate' />
|
||||
<link linkend="opt-services.plausible.adminUser.email">email</link> = "admin@localhost";
|
||||
<link linkend="opt-services.plausible.adminUser.passwordFile">passwordFile</link> = "/run/secrets/plausible-admin-pwd";
|
||||
};
|
||||
server = {
|
||||
<link linkend="opt-services.plausible.server.baseUrl">baseUrl</link> = "http://analytics.example.org";
|
||||
<link linkend="opt-services.plausible.server.secretKeybaseFile">secretKeybaseFile</link> = "/run/secrets/plausible-secret-key-base"; <co xml:id='ex-plausible-cfg-secretbase' />
|
||||
};
|
||||
};
|
||||
}</programlisting>
|
||||
<calloutlist>
|
||||
<callout arearefs='ex-plausible-cfg-activate'>
|
||||
<para>
|
||||
<varname>activate</varname> is used to skip the email verification of the admin-user that's
|
||||
automatically created by <package>plausible</package>. This is only supported if
|
||||
<package>postgresql</package> is configured by the module. This is done by default, but
|
||||
can be turned off with <xref linkend="opt-services.plausible.database.postgres.setup" />.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs='ex-plausible-cfg-secretbase'>
|
||||
<para>
|
||||
<varname>secretKeybaseFile</varname> is a path to the file which contains the secret generated
|
||||
with <package>openssl</package> as described above.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
Loading…
Add table
Add a link
Reference in a new issue