Nextlcoud with Redis distributed cashing and file locking

I have been playing around with Nextcloud on NixOS. So far everything is working well, however I am not having successes getting Nextcloud to uses Redis for distributed cache (memcache.distributed) and file locking (memcache.locking). Below is a link to the Nextcloud documentation on this topic, I have successfully followed this in the past to get it setup on a Debian install.

Memory caching — Nextcloud latest Administration Manual latest documentation

The following is my attempt at a Nix config to get this working. FYI, I know it is not best practices to put password in plan text in a Nix config. At his point, I am just testing and doing this more for ease.

# /etc/nixos/nextcloud.nix

{config, pkgs, ...}:
{
  # Nextcloud Configuration
  services.nextcloud = {
    enable = true;
    package = pkgs.nextcloud25;
    hostName = "redacted";
    https = true;
    maxUploadSize = "10G";
    caching.redis = true;

    config = {
      # Further forces Nextcloud to use HTTPS
      overwriteProtocol = "https";

      # ISO 3611-1 country codes for automatic phone-number detection
      defaultPhoneRegion = "redacted";

      # Nextcloud PostegreSQL Database Configuration
      dbtype = "pgsql";
      dbuser = "nextcloud";
      dbhost = "/run/postgresql";
      dbname = "nextcloud";
      dbpassFile = "${pkgs.writeText "dbpass" "redacted"}";

      # Setup Admin User
      adminuser = "admin";
      adminpassFile = "${pkgs.writeText "adminpass" "redacted"}";
    };

   extraOptions = {
      # Setup Redis
      memcache.distributed = "\OC\Memcache\Redis";
      memcache.locking = "\OC\Memcache\Redis";
      filelocking.enabled = true;
      redis = {
         host = "/run/redis-nextcloud/redis.sock";
         port = 0;
      };

      # Setup Mail
	#redacted 

    };
  };

  # Setup Nextcloud virtual host to listen on ports
  services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
    forceSSL = true;
    enableACME = true;
  };

  # Enable PostgreSQL
  services.postgresql = {
    enable = true;
    package = pkgs.postgresql_14;

    # Ensure the database, user, and permissions always exist
    ensureDatabases = [ "nextcloud" ];
    ensureUsers = [
     { name = "nextcloud";
       ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
     }
    ];

  # Enable Redis
  services.redis.servers.nextcloud = {
    enable = true;
    user = "nextcloud";
    unixSocket = "/run/redis-nextcloud/redis.sock";
    port = 0;
  };
}

I have tested this by running the following command:

sudo -u nextcloud redis-cli -s /run/redis-nextcloud/redis.sock monitor

When I do this, I get the “OK” indicating that Redis is up in running. However, when I open the Nextcloud web interface and poke around, I don’t see the terminal filling with text. The text filling up the terminal is what I would expect, as this is what I have seen on a Debian install I have. Also, I can stop the Redis Systemd unit and on the NixOS install Nextcloud work fine, whereas on the Debian install Nextcloud give an error. All this is leading me to believe that I don’t have NixOS/Nextcloud setup correctly to uses Redis.

Any suggestion on how to get Redis distributed cashing and file locking for Nextcloud working on NixOS? Is my config even on the right track?

Thank you

1 Like

I have been playing around with this a bit more and the issues seem to be with the following lines under services.nextcloud.extraOptions in the .nix config.

      memcache.distributed = "\OC\Memcache\Redis";
      memcache.locking = "\OC\Memcache\Redis";

This leads to the following in the /var/lib/nextcloud/config/config.php:

  'memcache' =>
  array (
    'distributed' => '\\OC\\Memcache\\Redis',
    'locking' => '\\OC\\Memcache\\Redis',
  ),

The above kind of looks correct, but does not seem to be working. This is evident by the redis-cli monitor test and when you go to the Nextcloud serverinfo page, e.g.:

https://redacted/ocs/v2.php/apps/serverinfo/api/v1/info

<memcache.local>\OC\Memcache\APCu</memcache.local>
<memcache.distributed>none</memcache.distributed>
<filelocking.enabled>yes</filelocking.enabled>
<memcache.locking>none</memcache.locking>

However, when I set these two option manually:

nextcloud-occ config:system:set memcache.distributed --value '\OC\Memcache\Redis'
nextcloud-occ config:system:set memcache.locking --value '\OC\Memcache\Redis'

I get the following in /var/lib/nextcloud/config/config.php:

  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'memcache.distributed' => '\\OC\\Memcache\\Redis',

This does work with both the redis-cli monitor test and when you go to the Nextcloud serverinfo page, e.g.:

https://redacted/ocs/v2.php/apps/serverinfo/api/v1/info

<memcache.local>\OC\Memcache\APCu</memcache.local>
<memcache.distributed>\OC\Memcache\Redis</memcache.distributed>
<filelocking.enabled>yes</filelocking.enabled>
<memcache.locking>\OC\Memcache\Redis</memcache.locking>

I am not really sure how to resolve this such that these two option can be set in the .nix config and have Nextcloud accept them. Does anyone have a suggestion?

Thank you

1 Like

Are there any updates on this one? I’m having the same problem on NixOS 23.05.

I’m using this on one of my installs.

  services.redis.servers.nextcloud = {
    enable = true;
    bind = "::1";
    port = 6379;
  };

  systemd.services.nextcloud-setup.serviceConfig.ExecStartPost = pkgs.writeScript "nextcloud-redis.sh" ''
    #!${pkgs.runtimeShell}
    nextcloud-occ config:system:set redis 'host' --value '::1' --type string
    nextcloud-occ config:system:set redis 'port' --value 6379 --type integer
    nextcloud-occ config:system:set memcache.local --value '\OC\Memcache\Redis' --type string
    nextcloud-occ config:system:set memcache.locking --value '\OC\Memcache\Redis' --type string
  '';
3 Likes

OK, i see. Thanks a bunch… I also thought, perhaps i missed something obvious in my config.

You have to quote the names of options that contain dots in them, otherwise, as you have observed, the NixOS module will generate a nested array, which is not what you want. You also have to escape the backslashes. Like this:

extraOptions = {
  # ...
  "memcache.distributed" = "\\OC\\Memcache\\Redis";
  "memcache.locking" = "\\OC\\Memcache\\Redis";
  # ...
};

This way, you should be getting the same values in the generated config file as by calling occ.