NixOS and NextCloud

I spent a few hours upgrading my NextCloud server from version 26 to 28. Sadly, it was not a pleasant process, mainly because there were some index changes that were conflicting and the migration code kept having a problem with creating indexes with one name for oc_table_name because it conflicted with table_name. This is probably because I have a relatively old NextCloud setup that has been migrated from OwnCloud over the years and didn't use table prefixes.

Unfortunately, that meant I ended up having to do a lot of:

  • DROP INDEX index_name ON table_name; in mysql
  • systemctl restart nextcloud-setup.service || systemctl status nextcloud-setup.service
  • Look at the error, go back to the beginning with the new name

That took about an hour to get through and pretty much points out that I also aren't using the proper indexes because half of those tables are empty and the other have isn't. However, table_name in the above example was sometimes the prefixes (oc_table_name) and other times it was the non-prefixed (table_name) version so that is just something I'm going to live with.

Once I finished, it complained about missing indexes, so I had to run this:

nextcloud-occ db:add-missing-indices

Which probably put all the indexes I dropped and the migrations put on the wrong table back to the table that is actually used.

Finally, there were still a few other errors about “interned_strings_buffer” and memcached not working. I figured some of these were related to me losing my database instance on my hosting provider, which meant I moved the database from a dedicated server to the same one as the NextCloud server.

Below the Nix file I use to set up NextCloud so it doesn't give me any warnings and has backups properly set up.

# nextcloud.nix
{ config
, pkgs
, ...
}:
let
  host = "nextcloud.example.com";
  backup-name = "restic";
in
{
  # Set up the user in case you need consistent UIDs and GIDs. And also to make
  # sure we can write out the secrets file with the proper permissions.
  users.groups.nextcloud = { };
  users.users.nextcloud = {
    isSystemUser = true;
    group = "nextcloud";
  };

  # Set up backing up the database automatically. The path will be in
  # `/var/backups/mysql/nextcloud.gz`.
  services.mysqlBackup.databases = [ "nextcloud" ];

  # Restic is already set up to back up the mysql directory but
  # we also set it up to backup the data.
  services.restic.backups.${backup-name}.paths = ["/var/lib/nextcloud/data"];

  # Set up secrets. This is a sops-nix file checked in at the same folder as
  # this file.
  sops.secrets = {
    nextcloud-admin-password = {
      sopsFile = ./secrets.yaml;
      mode = "0600";
      owner = "nextcloud";
      group = "nextcloud";
    };

    nextcloud-db-password = {
      sopsFile = ./secrets.yaml;
      mode = "0600";
      owner = "nextcloud";
      group = "nextcloud";
    };

    nextcloud-secrets = {
      sopsFile = ./secrets.yaml;
      mode = "0600";
      owner = "nextcloud";
      group = "nextcloud";
    };
  };

  # Set up Nextcloud.
  services.nextcloud = {
    enable = true;
    package = pkgs.nextcloud28;
    https = true;
    hostName = host;
    secretFile = "/var/run/secrets/nextcloud-secrets";

    phpOptions."opcache.interned_strings_buffer" = "13";

    config = {
      dbtype = "mysql";
      dbname = "nextcloud";
      dbhost = "localhost";
      dbpassFile = "/var/run/secrets/nextcloud-db-password";

      adminuser = "admin";
      adminpassFile = "/var/run/secrets/nextcloud-admin-password";
    };

    settings = {
      maintenance_window_start = 2; # 02:00
      default_phone_region = "en";
      filelocking.enabled = true;

      redis = {
        host = config.services.redis.servers.nextcloud.bind;
        port = config.services.redis.servers.nextcloud.port;
        dbindex = 0;
        timeout = 1.5;
      };
    };

    caching = {
      redis = true;
      memcached = true;
    };
  };

  # Set up Redis because the admin page was complaining about it.
  # https://discourse.nixos.org/t/nextlcoud-with-redis-distributed-cashing-and-file-locking/25321/3
  services.redis.servers.nextcloud = {
    enable = true;
    bind = "::1";
    port = 6379;
  };

  # Setup Nginx because we have multiple services on this server.
  services.nginx = {
    enable = true;
    virtualHosts."${host}" = {
      forceSSL = true;
      enableACME = true;
    };
  };

  networking.firewall.allowedTCPPorts = [ 80 443 ];
}

Hopefully, this will help others if they encounter the same problems as me since I couldn't find these answers with web searching.

Metadata

Categories:

Tags: