Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/wallabag: init #54863

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Expand Up @@ -723,6 +723,7 @@
./services/web-apps/tt-rss.nix
./services/web-apps/selfoss.nix
./services/web-apps/virtlyst.nix
./services/web-apps/wallabag.nix
./services/web-apps/youtrack.nix
./services/web-servers/apache-httpd/default.nix
./services/web-servers/caddy.nix
Expand Down
188 changes: 188 additions & 0 deletions nixos/modules/services/web-apps/wallabag.nix
@@ -0,0 +1,188 @@
{ config, lib, pkgs, ... }:

with lib;
let
cfg = config.services.wallabag;

poolName = "wallabag";

phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock";

configFile = pkgs.writeTextFile {
name = "wallabag-config";
text = cfg.conf;
destination = "/config/parameters.yml";
};

appDir = pkgs.buildEnv {
name = "wallabag-app-dir";
ignoreCollisions = true;
checkCollisionContents = false;
paths = [ configFile "${cfg.package}/app" ];
};

in {
options = {
services.wallabag = {
enable = mkEnableOption "wallabag";

user = mkOption {
type = types.str;
default = "nginx";
description = ''
User account under which both the update daemon and the web-application run.
'';
};

dataDir = mkOption {
type = types.path;
default = "/var/lib/wallabag";
description = ''
Data directory.
'';
};

package = mkOption {
Ekleog marked this conversation as resolved.
Show resolved Hide resolved
type = types.package;
default = pkgs.wallabag;
description = ''
Wallabag package to use.
'';
};

hostName = mkOption {
type = types.str;
description = ''
Name of the nginx virtualhost to use and setup.
'';
};

poolConfig = mkOption {
type = types.lines;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be turned into an attrset that's automatically turned into lines via something like toKeyValue {} cfg.poolConfig. This could make the merging behavior more pleasant.

default = ''
pm = dynamic
pm.max_children = 75
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 20
pm.max_requests = 500
catch_workers_output = 1
'';
description = ''
Options for wallabag's PHP pool. See the documentation on <literal>php-fpm.conf</literal> for details on configuration directives.
'';
};

conf = mkOption {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might deserve an example, or at least a link to wallabag's docs in the description.

type = types.str;
description = ''
Contents of the wallabag configuration file (parameters.yml)
'';
};
};
};


config = mkIf cfg.enable {

services.phpfpm.poolConfigs = {
"${poolName}" = ''
listen = "${phpfpmSocketName}";
listen.owner = nginx
listen.group = nginx
listen.mode = 0600
user = ${cfg.user}
group = nginx
env[WALLABAG_DATA] = ${cfg.dataDir}
${cfg.poolConfig}
'';
};
services.phpfpm.phpOptions = ''
max_execution_time = 120
'';

services.nginx.enable = mkDefault true;

services.nginx.virtualHosts."${cfg.hostName}" = {
root = "${cfg.package}/web";

extraConfig = ''
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
'';

locations."/" = {
extraConfig = ''
try_files $uri /app.php$is_args$args;
'';
};

locations."~ ^/app\\.php(/|$)" = {
extraConfig = ''
fastcgi_pass unix:${phpfpmSocketName};
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include ${pkgs.nginx}/conf/fastcgi_params;

fastcgi_param SCRIPT_FILENAME ${cfg.package}/web/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT ${cfg.package}/web;
fastcgi_read_timeout 120;

internal;
'';
};

locations."~ /(?!app)\\.php$" = {
extraConfig = ''
return 404;
'';
};
};

systemd.services.wallabag-install = {
description = "Wallabag install service";
wantedBy = [ "multi-user.target" ];
before = [ "phpfpm-wallabag.service" ];
after = [ "mysql.service" "postgresql.service" ];
path = with pkgs; [ coreutils php phpPackages.composer ];

serviceConfig = {
User = cfg.user;
Type = "oneshot";
RemainAfterExit = "yes";
PermissionsStartOnly = true;
};

preStart = ''
mkdir -p "${cfg.dataDir}"
chown ${cfg.user}:nginx "${cfg.dataDir}"
'';

script = ''
echo "Setting up wallabag files in ${cfg.dataDir} ..."
cd "${cfg.dataDir}"

rm -rf var/cache/*
rm -f app
ln -sf ${appDir} app
ln -sf ${cfg.package}/composer.{json,lock} .

export WALLABAG_DATA="${cfg.dataDir}"
if [ ! -f installed ]; then
php ${cfg.package}/bin/console --env=prod doctrine:database:create --if-not-exists --no-interaction
php ${cfg.package}/bin/console --env=prod doctrine:migrations:migrate --no-interaction
# Until https://github.com/wallabag/wallabag/issues/3662 is fixed
yes no | php ${cfg.package}/bin/console --env=prod wallabag:install
touch installed
else
php ${cfg.package}/bin/console --env=prod doctrine:migrations:migrate --no-interaction
fi
php ${cfg.package}/bin/console --env=prod cache:clear
'';
};
};

meta = with stdenv.lib; {
maintainers = with maintainers; [ nadrieril ];
};
}
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Expand Up @@ -208,6 +208,7 @@ in
upnp = handleTest ./upnp.nix {};
vault = handleTest ./vault.nix {};
virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
wallabag = handleTestOn ["x86_64-linux"] ./wallabag.nix {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does wallabag work only on x86_64-linux?

wordpress = handleTest ./wordpress.nix {};
xautolock = handleTest ./xautolock.nix {};
xdg-desktop-portal = handleTest ./xdg-desktop-portal.nix {};
Expand Down
71 changes: 71 additions & 0 deletions nixos/tests/wallabag.nix
@@ -0,0 +1,71 @@
import ./make-test.nix ({ pkgs, ...}: {
name = "wallabag";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ nadrieril ];
};

nodes = {
# The only thing the client needs to do is curl
client = { ... }: { };

wallabag = { config, pkgs, ... }: {
networking.firewall.allowedTCPPorts = [ 80 ];

services.wallabag.enable = true;
services.wallabag.hostName = "wallabag";
services.wallabag.conf = ''
parameters:
domain_name: http://wallabag
database_driver: pdo_pgsql
database_driver_class: ~
database_host: localhost
database_port: null
database_name: wallabag
database_user: wallabag
database_password: password
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to not put the database password in the store? I'm thinking it might make sense to just pass the path to the wallabag config file instead of passing the whole file here, in a manner similar to networking.supplicant.*.configFile.path, for security reasons.

database_path: null
database_table_prefix: wallabag_
database_socket: null
database_charset: utf8
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
locale: en
secret: xxxxxxXXXXXXXxxxxxxxxxxxXxXxxx
twofactor_auth: false
twofactor_sender: no-reply@wallabag.org
fosuser_registration: false
fosuser_confirmation: false
from_email: no-reply@wallabag.org
rss_limit: 50
rabbitmq_host: localhost
rabbitmq_port: 5672
rabbitmq_user: guest
rabbitmq_password: guest
rabbitmq_prefetch_count: 10
redis_scheme: tcp
redis_host: localhost
redis_port: 6379
redis_path: null
redis_password: null
'';

services.postgresql = {
enable = true;
initialScript = pkgs.writeText "pgsql_initial_script" ''
create role wallabag with login password 'password';
create database wallabag with owner wallabag;
'';
};
};
};

testScript = let
in ''
startAll();
$wallabag->waitForUnit("multi-user.target");
$client->waitForUnit("multi-user.target");
$client->succeed("curl -sSf http://wallabag/login");
'';
})