2020-04-24 23:36:52 +00:00
{ config , lib , pkgs , . . . }:
with lib ;
let
cfg = config . services . nextcloud ;
fpm = config . services . phpfpm . pools . nextcloud ;
2022-08-12 12:06:08 +00:00
jsonFormat = pkgs . formats . json { } ;
2021-10-14 00:43:12 +00:00
inherit ( cfg ) datadir ;
2021-10-04 12:37:57 +00:00
phpPackage = cfg . phpPackage . buildEnv {
2021-02-05 17:12:51 +00:00
extensions = { enabled , all }:
( with all ;
2022-11-21 17:40:18 +00:00
# disable default openssl extension
( lib . filter ( e : e . pname != " p h p - o p e n s s l " ) enabled )
# use OpenSSL 1.1 for RC4 Nextcloud encryption if user
2022-12-28 21:21:41 +00:00
# has acknowledged the brokenness of the ciphers (RC4).
2022-11-21 17:40:18 +00:00
# TODO: remove when https://github.com/nextcloud/server/issues/32003 is fixed.
++ ( if cfg . enableBrokenCiphersForSSE then [ cfg . phpPackage . extensions . openssl-legacy ] else [ cfg . phpPackage . extensions . openssl ] )
2021-04-25 03:57:28 +00:00
++ optional cfg . enableImagemagick imagick
2021-02-05 17:12:51 +00:00
# Optionally enabled depending on caching settings
++ optional cfg . caching . apcu apcu
++ optional cfg . caching . redis redis
++ optional cfg . caching . memcached memcached
)
++ cfg . phpExtraExtensions all ; # Enabled by user
extraConfig = toKeyValue phpOptions ;
} ;
2020-04-24 23:36:52 +00:00
toKeyValue = generators . toKeyValue {
mkKeyValue = generators . mkKeyValueDefault { } " = " ;
} ;
phpOptions = {
upload_max_filesize = cfg . maxUploadSize ;
post_max_size = cfg . maxUploadSize ;
memory_limit = cfg . maxUploadSize ;
2021-03-09 03:18:52 +00:00
} // cfg . phpOptions
// optionalAttrs cfg . caching . apcu {
" a p c . e n a b l e _ c l i " = " 1 " ;
} ;
2020-04-24 23:36:52 +00:00
occ = pkgs . writeScriptBin " n e x t c l o u d - o c c " ''
#! ${pkgs.runtimeShell}
cd $ { cfg . package }
sudo = exec
if [ [ " $ U S E R " != nextcloud ] ] ; then
2020-06-18 07:06:33 +00:00
sudo = ' exec /run/wrappers/bin/sudo - u nextcloud - - preserve-env = NEXTCLOUD_CONFIG_DIR - - preserve-env = OC_PASS'
2020-04-24 23:36:52 +00:00
fi
2021-10-14 00:43:12 +00:00
export NEXTCLOUD_CONFIG_DIR = " ${ datadir } / c o n f i g "
2020-04-24 23:36:52 +00:00
$ sudo \
$ { phpPackage } /bin/php \
2020-12-25 13:55:36 +00:00
occ " $ @ "
2020-04-24 23:36:52 +00:00
'' ;
inherit ( config . system ) stateVersion ;
2023-05-24 13:37:59 +00:00
mysqlLocal = cfg . database . createLocally && cfg . config . dbtype == " m y s q l " ;
pgsqlLocal = cfg . database . createLocally && cfg . config . dbtype == " p g s q l " ;
2020-04-24 23:36:52 +00:00
in {
2020-08-20 17:08:02 +00:00
imports = [
2021-10-11 16:52:03 +00:00
( mkRemovedOptionModule [ " s e r v i c e s " " n e x t c l o u d " " c o n f i g " " a d m i n p a s s " ] ''
Please use ` services . nextcloud . config . adminpassFile' instead !
'' )
( mkRemovedOptionModule [ " s e r v i c e s " " n e x t c l o u d " " c o n f i g " " d b p a s s " ] ''
Please use ` services . nextcloud . config . dbpassFile' instead !
'' )
2020-08-20 17:08:02 +00:00
( mkRemovedOptionModule [ " s e r v i c e s " " n e x t c l o u d " " n g i n x " " e n a b l e " ] ''
The nextcloud module supports ` nginx ` as reverse-proxy by default and doesn't
support other reverse-proxies officially .
However it's possible to use an alternative reverse-proxy by
* disabling nginx
* setting ` listen . owner ` & ` listen . group ` in the phpfpm-pool to a different value
Further details about this can be found in the ` Nextcloud ` - section of the NixOS-manual
2022-12-28 21:21:41 +00:00
( which can be opened e . g . by running ` nixos-help ` ) .
2020-08-20 17:08:02 +00:00
'' )
2021-04-25 03:57:28 +00:00
( mkRemovedOptionModule [ " s e r v i c e s " " n e x t c l o u d " " d i s a b l e I m a g e m a g i c k " ] ''
2023-02-16 17:41:37 +00:00
Use services . nextcloud . enableImagemagick instead .
2021-04-25 03:57:28 +00:00
'' )
2020-08-20 17:08:02 +00:00
] ;
2020-04-24 23:36:52 +00:00
options . services . nextcloud = {
2022-09-09 14:08:57 +00:00
enable = mkEnableOption ( lib . mdDoc " n e x t c l o u d " ) ;
2022-11-21 17:40:18 +00:00
enableBrokenCiphersForSSE = mkOption {
type = types . bool ;
default = versionOlder stateVersion " 2 2 . 1 1 " ;
defaultText = literalExpression " v e r s i o n O l d e r s y s t e m . s t a t e V e r s i o n \" 2 2 . 1 1 \" " ;
description = lib . mdDoc ''
This option enables using the OpenSSL PHP extension linked against OpenSSL 1 .1
rather than latest OpenSSL ( ≥ 3 ) , this is not recommended unless you need
it for server-side encryption ( SSE ) . SSE uses the legacy RC4 cipher which is
considered broken for several years now . See also [ RFC7465 ] ( https://datatracker.ietf.org/doc/html/rfc7465 ) .
This cipher has been disabled in OpenSSL ≥ 3 and requires
a specific legacy profile to re-enable it .
If you deploy Nextcloud using OpenSSL ≥ 3 for PHP and have
server-side encryption configured , you will not be able to access
your files anymore . Enabling this option can restore access to your files .
Upon testing we didn't encounter any data corruption when turning
this on and off again , but this cannot be guaranteed for
each Nextcloud installation .
It is ` true ` by default for systems with a [ ] ( #opt-system.stateVersion) below
` 22 .11 ` to make sure that existing installations won't break on update . On newer
NixOS systems you have to explicitly enable it on your own .
Please note that this only provides additional value when using
external storage such as S3 since it's not an end-to-end encryption .
If this is not the case ,
it is advised to [ disable server-side encryption ] ( https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html #disabling-encryption) and set this to `false`.
In the future , Nextcloud may move to AES-256-GCM , by then ,
this option will be removed .
'' ;
} ;
2020-04-24 23:36:52 +00:00
hostName = mkOption {
type = types . str ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " F Q D N f o r t h e n e x t c l o u d i n s t a n c e . " ;
2020-04-24 23:36:52 +00:00
} ;
home = mkOption {
type = types . str ;
default = " / v a r / l i b / n e x t c l o u d " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " S t o r a g e p a t h o f n e x t c l o u d . " ;
2020-04-24 23:36:52 +00:00
} ;
2021-10-14 00:43:12 +00:00
datadir = mkOption {
type = types . str ;
2022-07-14 12:49:19 +00:00
default = config . services . nextcloud . home ;
defaultText = literalExpression " c o n f i g . s e r v i c e s . n e x t c l o u d . h o m e " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
Data storage path of nextcloud . Will be [ ] ( #opt-services.nextcloud.home) by default.
2021-10-14 00:43:12 +00:00
This folder will be populated with a config . php and data folder which contains the state of the instance ( excl the database ) . " ;
'' ;
example = " / m n t / n e x t c l o u d - f i l e " ;
} ;
extraApps = mkOption {
type = types . attrsOf types . package ;
default = { } ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-14 00:43:12 +00:00
Extra apps to install . Should be an attrSet of appid to packages generated by fetchNextcloudApp .
The appid must be identical to the " i d " value in the apps appinfo/info.xml.
2022-08-12 12:06:08 +00:00
Using this will disable the appstore to prevent Nextcloud from updating these apps ( see [ ] ( #opt-services.nextcloud.appstoreEnable)).
2021-10-14 00:43:12 +00:00
'' ;
example = literalExpression ''
{
maps = pkgs . fetchNextcloudApp {
name = " m a p s " ;
sha256 = " 0 0 7 y 8 0 i d q g 6 b 6 z k 6 k j x g 4 v g w 0 z 8 f s x s 9 l a j n v 4 9 v v 1 z j y 6 j x 2 i 1 i " ;
url = " h t t p s : / / g i t h u b . c o m / n e x t c l o u d / m a p s / r e l e a s e s / d o w n l o a d / v 0 . 1 . 9 / m a p s - 0 . 1 . 9 . t a r . g z " ;
version = " 0 . 1 . 9 " ;
} ;
phonetrack = pkgs . fetchNextcloudApp {
name = " p h o n e t r a c k " ;
sha256 = " 0 q f 3 6 6 v b a h y l 2 7 p 9 m s h f m a 1 a s 4 n v q l 6 w 7 5 z y 2 z k 5 x w w b p 3 4 3 v s b c " ;
url = " h t t p s : / / g i t l a b . c o m / e n e i l u j / p h o n e t r a c k - o c / - / w i k i s / u p l o a d s / 9 3 1 a a a f 8 d c a 2 4 b f 3 1 a 7 e 1 6 9 a 8 3 c 1 7 2 3 5 / p h o n e t r a c k - 0 . 6 . 9 . t a r . g z " ;
version = " 0 . 6 . 9 " ;
} ;
}
'' ;
} ;
extraAppsEnable = mkOption {
type = types . bool ;
default = true ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
Automatically enable the apps in [ ] ( #opt-services.nextcloud.extraApps) every time nextcloud starts.
2021-10-14 00:43:12 +00:00
If set to false , apps need to be enabled in the Nextcloud user interface or with nextcloud-occ app:enable.
'' ;
} ;
appstoreEnable = mkOption {
type = types . nullOr types . bool ;
default = null ;
example = true ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-14 00:43:12 +00:00
Allow the installation of apps and app updates from the store .
2022-08-12 12:06:08 +00:00
Enabled by default unless there are packages in [ ] ( #opt-services.nextcloud.extraApps).
Set to true to force enable the store even if [ ] ( #opt-services.nextcloud.extraApps) is used.
2021-10-14 00:43:12 +00:00
Set to false to disable the installation of apps from the global appstore . App management is always enabled regardless of this setting .
'' ;
} ;
2020-04-24 23:36:52 +00:00
logLevel = mkOption {
type = types . ints . between 0 4 ;
default = 2 ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " L o g l e v e l v a l u e b e t w e e n 0 ( D E B U G ) a n d 4 ( F A T A L ) . " ;
2020-04-24 23:36:52 +00:00
} ;
2022-11-02 22:02:43 +00:00
logType = mkOption {
type = types . enum [ " e r r o r l o g " " f i l e " " s y s l o g " " s y s t e m d " ] ;
default = " s y s l o g " ;
description = lib . mdDoc ''
Logging backend to use .
systemd requires the php-systemd package to be added to services . nextcloud . phpExtraExtensions .
See the [ nextcloud documentation ] ( https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/logging_configuration.html ) for details .
'' ;
} ;
2020-04-24 23:36:52 +00:00
https = mkOption {
type = types . bool ;
default = false ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " U s e h t t p s f o r g e n e r a t e d l i n k s . " ;
2020-04-24 23:36:52 +00:00
} ;
package = mkOption {
type = types . package ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " W h i c h p a c k a g e t o u s e f o r t h e N e x t c l o u d i n s t a n c e . " ;
2023-07-15 17:15:38 +00:00
relatedPackages = [ " n e x t c l o u d 2 5 " " n e x t c l o u d 2 6 " " n e x t c l o u d 2 7 " ] ;
2020-04-24 23:36:52 +00:00
} ;
2021-10-04 12:37:57 +00:00
phpPackage = mkOption {
type = types . package ;
2023-07-15 17:15:38 +00:00
relatedPackages = [ " p h p 8 1 " " p h p 8 2 " ] ;
2021-10-04 12:37:57 +00:00
defaultText = " p k g s . p h p " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-04 12:37:57 +00:00
PHP package to use for Nextcloud .
'' ;
} ;
2020-04-24 23:36:52 +00:00
maxUploadSize = mkOption {
default = " 5 1 2 M " ;
type = types . str ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Defines the upload limit for files . This changes the relevant options
in php . ini and nginx if enabled .
'' ;
} ;
skeletonDirectory = mkOption {
default = " " ;
type = types . str ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
The directory where the skeleton files are located . These files will be
copied to the data directory of new users . Leave empty to not copy any
skeleton files .
'' ;
} ;
webfinger = mkOption {
type = types . bool ;
default = false ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Enable this option if you plan on using the webfinger plugin .
The appropriate nginx rewrite rules will be added to your configuration .
'' ;
} ;
2021-02-05 17:12:51 +00:00
phpExtraExtensions = mkOption {
type = with types ; functionTo ( listOf package ) ;
default = all : [ ] ;
2021-10-06 13:57:05 +00:00
defaultText = literalExpression " a l l : [ ] " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-02-05 17:12:51 +00:00
Additional PHP extensions to use for nextcloud .
By default , only extensions necessary for a vanilla nextcloud installation are enabled ,
but you may choose from the list of available extensions and add further ones .
This is sometimes necessary to be able to install a certain nextcloud app that has additional requirements .
'' ;
2021-10-06 13:57:05 +00:00
example = literalExpression ''
2021-02-05 17:12:51 +00:00
all : [ all . pdlib all . bz2 ]
'' ;
} ;
2020-04-24 23:36:52 +00:00
phpOptions = mkOption {
type = types . attrsOf types . str ;
default = {
short_open_tag = " O f f " ;
expose_php = " O f f " ;
error_reporting = " E _ A L L & ~ E _ D E P R E C A T E D & ~ E _ S T R I C T " ;
display_errors = " s t d e r r " ;
" o p c a c h e . e n a b l e _ c l i " = " 1 " ;
" o p c a c h e . i n t e r n e d _ s t r i n g s _ b u f f e r " = " 8 " ;
" o p c a c h e . m a x _ a c c e l e r a t e d _ f i l e s " = " 1 0 0 0 0 " ;
" o p c a c h e . m e m o r y _ c o n s u m p t i o n " = " 1 2 8 " ;
" o p c a c h e . r e v a l i d a t e _ f r e q " = " 1 " ;
" o p c a c h e . f a s t _ s h u t d o w n " = " 1 " ;
" o p e n s s l . c a f i l e " = " / e t c / s s l / c e r t s / c a - c e r t i f i c a t e s . c r t " ;
catch_workers_output = " y e s " ;
} ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Options for PHP's php . ini file for nextcloud .
'' ;
} ;
poolSettings = mkOption {
type = with types ; attrsOf ( oneOf [ str int bool ] ) ;
default = {
" p m " = " d y n a m i c " ;
" p m . m a x _ c h i l d r e n " = " 3 2 " ;
" p m . s t a r t _ s e r v e r s " = " 2 " ;
" p m . m i n _ s p a r e _ s e r v e r s " = " 2 " ;
" p m . m a x _ s p a r e _ s e r v e r s " = " 4 " ;
" p m . m a x _ r e q u e s t s " = " 5 0 0 " ;
} ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
Options for nextcloud's PHP pool . See the documentation on ` php-fpm . conf ` for details on configuration directives .
2020-04-24 23:36:52 +00:00
'' ;
} ;
poolConfig = mkOption {
type = types . nullOr types . lines ;
default = null ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
Options for nextcloud's PHP pool . See the documentation on ` php-fpm . conf ` for details on configuration directives .
2020-04-24 23:36:52 +00:00
'' ;
} ;
2022-09-09 14:08:57 +00:00
fastcgiTimeout = mkOption {
type = types . int ;
default = 120 ;
description = lib . mdDoc ''
FastCGI timeout for database connection in seconds .
'' ;
} ;
2022-04-27 09:35:20 +00:00
database = {
createLocally = mkOption {
type = types . bool ;
default = false ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2023-05-24 13:37:59 +00:00
Create the database and database user locally .
2022-04-27 09:35:20 +00:00
'' ;
} ;
} ;
2020-04-24 23:36:52 +00:00
config = {
dbtype = mkOption {
type = types . enum [ " s q l i t e " " p g s q l " " m y s q l " ] ;
default = " s q l i t e " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " D a t a b a s e t y p e . " ;
2020-04-24 23:36:52 +00:00
} ;
dbname = mkOption {
type = types . nullOr types . str ;
default = " n e x t c l o u d " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " D a t a b a s e n a m e . " ;
2020-04-24 23:36:52 +00:00
} ;
dbuser = mkOption {
type = types . nullOr types . str ;
default = " n e x t c l o u d " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " D a t a b a s e u s e r . " ;
2020-04-24 23:36:52 +00:00
} ;
dbpassFile = mkOption {
type = types . nullOr types . str ;
default = null ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
The full path to a file that contains the database password .
'' ;
} ;
dbhost = mkOption {
type = types . nullOr types . str ;
2023-05-24 13:37:59 +00:00
default =
if pgsqlLocal then " / r u n / p o s t g r e s q l "
else if mysqlLocal then " l o c a l h o s t : / r u n / m y s q l d / m y s q l d . s o c k "
else " l o c a l h o s t " ;
defaultText = " l o c a l h o s t " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2023-05-24 13:37:59 +00:00
Database host or socket path . Defaults to the correct unix socket
instead if ` services . nextcloud . database . createLocally ` is true and
` services . nextcloud . config . dbtype ` is either ` pgsql ` or ` mysql ` .
2020-04-24 23:36:52 +00:00
'' ;
} ;
dbport = mkOption {
type = with types ; nullOr ( either int str ) ;
default = null ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " D a t a b a s e p o r t . " ;
2020-04-24 23:36:52 +00:00
} ;
dbtableprefix = mkOption {
type = types . nullOr types . str ;
default = null ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " T a b l e p r e f i x i n N e x t c l o u d d a t a b a s e . " ;
2020-04-24 23:36:52 +00:00
} ;
adminuser = mkOption {
type = types . str ;
default = " r o o t " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " A d m i n u s e r n a m e . " ;
2020-04-24 23:36:52 +00:00
} ;
adminpassFile = mkOption {
2021-10-11 16:52:03 +00:00
type = types . str ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-02-05 17:12:51 +00:00
The full path to a file that contains the admin's password . Must be
2023-07-15 17:15:38 +00:00
readable by user ` nextcloud ` . The password is set only in the initial
setup of nextcloud by the systemd ` nextcloud-setup . service ` .
2020-04-24 23:36:52 +00:00
'' ;
} ;
extraTrustedDomains = mkOption {
type = types . listOf types . str ;
default = [ ] ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Trusted domains , from which the nextcloud installation will be
2022-12-28 21:21:41 +00:00
accessible . You don't need to add
2022-08-12 12:06:08 +00:00
` services . nextcloud . hostname ` here .
2020-04-24 23:36:52 +00:00
'' ;
} ;
trustedProxies = mkOption {
type = types . listOf types . str ;
default = [ ] ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Trusted proxies , to provide if the nextcloud installation is being
proxied to secure against e . g . spoofing .
'' ;
} ;
overwriteProtocol = mkOption {
type = types . nullOr ( types . enum [ " h t t p " " h t t p s " ] ) ;
default = null ;
example = " h t t p s " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Force Nextcloud to always use HTTPS i . e . for link generation . Nextcloud
uses the currently used protocol by default , but when behind a reverse-proxy ,
2022-08-12 12:06:08 +00:00
it may use ` http ` for everything although Nextcloud
2020-04-24 23:36:52 +00:00
may be served via HTTPS .
'' ;
} ;
2021-03-09 03:18:52 +00:00
defaultPhoneRegion = mkOption {
default = null ;
type = types . nullOr types . str ;
example = " D E " ;
2022-09-09 14:08:57 +00:00
description = lib . mdDoc ''
: : : { . warning }
This option exists since Nextcloud 21 ! If older versions are used ,
this will throw an eval-error !
: : :
2021-03-09 03:18:52 +00:00
2022-09-09 14:08:57 +00:00
[ ISO 3 6 1 1 -1 ] ( https://www.iso.org/iso-3166-country-codes.html )
2021-03-09 03:18:52 +00:00
country codes for automatic phone-number detection without a country code .
2022-09-09 14:08:57 +00:00
With e . g . ` DE ` set , the ` + 49 ` can be omitted for
2021-03-09 03:18:52 +00:00
phone-numbers .
'' ;
} ;
2021-10-06 13:57:05 +00:00
objectstore = {
s3 = {
2022-09-09 14:08:57 +00:00
enable = mkEnableOption ( lib . mdDoc ''
2021-10-06 13:57:05 +00:00
S3 object storage as primary storage .
This mounts a bucket on an Amazon S3 object storage or compatible
implementation into the virtual filesystem .
2021-10-11 16:52:03 +00:00
Further details about this feature can be found in the
2022-09-09 14:08:57 +00:00
[ upstream documentation ] ( https://docs.nextcloud.com/server/22/admin_manual/configuration_files/primary_storage.html ) .
'' ) ;
2021-10-06 13:57:05 +00:00
bucket = mkOption {
type = types . str ;
example = " n e x t c l o u d " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
The name of the S3 bucket .
'' ;
} ;
autocreate = mkOption {
type = types . bool ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
Create the objectstore if it does not exist .
'' ;
} ;
key = mkOption {
type = types . str ;
example = " E J 3 9 I T Y Z E U H 5 B G W D R U F Y " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
The access key for the S3 bucket .
'' ;
} ;
secretFile = mkOption {
type = types . str ;
example = " / v a r / n e x t c l o u d - o b j e c t s t o r e - s 3 - s e c r e t " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
The full path to a file that contains the access secret . Must be
2022-08-12 12:06:08 +00:00
readable by user ` nextcloud ` .
2021-10-06 13:57:05 +00:00
'' ;
} ;
hostname = mkOption {
type = types . nullOr types . str ;
default = null ;
example = " e x a m p l e . c o m " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
Required for some non-Amazon implementations .
'' ;
} ;
port = mkOption {
type = types . nullOr types . port ;
default = null ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
Required for some non-Amazon implementations .
'' ;
} ;
useSsl = mkOption {
type = types . bool ;
default = true ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
Use SSL for objectstore access .
'' ;
} ;
region = mkOption {
type = types . nullOr types . str ;
default = null ;
example = " R E G I O N " ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
Required for some non-Amazon implementations .
'' ;
} ;
usePathStyle = mkOption {
type = types . bool ;
default = false ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2021-10-06 13:57:05 +00:00
Required for some non-Amazon S3 implementations .
Ordinarily , requests will be made with
2022-08-12 12:06:08 +00:00
` http://bucket.hostname.domain/ ` , but with path style
2021-10-06 13:57:05 +00:00
enabled requests are made with
2022-08-12 12:06:08 +00:00
` http://hostname.domain/bucket ` instead .
2021-10-06 13:57:05 +00:00
'' ;
} ;
2023-03-24 00:07:29 +00:00
sseCKeyFile = mkOption {
type = types . nullOr types . path ;
default = null ;
example = " / v a r / n e x t c l o u d - o b j e c t s t o r e - s 3 - s s e - c - k e y " ;
description = lib . mdDoc ''
If provided this is the full path to a file that contains the key
to enable [ server-side encryption with customer-provided keys ] [ 1 ]
( SSE-C ) .
The file must contain a random 3 2 - byte key encoded as a base64
string , e . g . generated with the command
` ` `
openssl rand 32 | base64
` ` `
Must be readable by user ` nextcloud ` .
[ 1 ] : https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html
'' ;
} ;
2021-10-06 13:57:05 +00:00
} ;
} ;
2020-04-24 23:36:52 +00:00
} ;
2022-09-09 14:08:57 +00:00
enableImagemagick = mkEnableOption ( lib . mdDoc ''
2021-10-11 16:52:03 +00:00
the ImageMagick module for PHP .
2021-03-12 07:09:13 +00:00
This is used by the theming app and for generating previews of certain images ( e . g . SVG and HEIF ) .
You may want to disable it for increased security . In that case , previews will still be available
for some images ( e . g . JPEG and PNG ) .
2022-09-09 14:08:57 +00:00
See < https://github.com/nextcloud/server/issues/13099 > .
'' ) / / {
2021-04-25 03:57:28 +00:00
default = true ;
2021-03-12 07:09:13 +00:00
} ;
2023-05-24 13:37:59 +00:00
configureRedis = lib . mkOption {
type = lib . types . bool ;
default = config . services . nextcloud . notify_push . enable ;
defaultText = literalExpression " c o n f i g . s e r v i c e s . n e x t c l o u d . n o t i f y _ p u s h . e n a b l e " ;
description = lib . mdDoc ''
Whether to configure nextcloud to use the recommended redis settings for small instances .
: : : { . note }
The ` notify_push ` app requires redis to be configured . If this option is turned off , this must be configured manually .
: : :
'' ;
} ;
2020-04-24 23:36:52 +00:00
caching = {
apcu = mkOption {
type = types . bool ;
default = true ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Whether to load the APCu module into PHP .
'' ;
} ;
redis = mkOption {
type = types . bool ;
default = false ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Whether to load the Redis module into PHP .
You still need to enable Redis in your config . php .
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
'' ;
} ;
memcached = mkOption {
type = types . bool ;
default = false ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Whether to load the Memcached module into PHP .
You still need to enable Memcached in your config . php .
See https://docs.nextcloud.com/server/14/admin_manual/configuration_server/caching_configuration.html
'' ;
} ;
} ;
autoUpdateApps = {
enable = mkOption {
type = types . bool ;
default = false ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
2020-04-24 23:36:52 +00:00
Run regular auto update of all apps installed from the nextcloud app store .
'' ;
} ;
startAt = mkOption {
type = with types ; either str ( listOf str ) ;
default = " 0 5 : 0 0 : 0 0 " ;
example = " S u n 1 4 : 0 0 : 0 0 " ;
2022-09-09 14:08:57 +00:00
description = lib . mdDoc ''
When to run the update . See ` systemd . services . <name> . startAt ` .
2020-04-24 23:36:52 +00:00
'' ;
} ;
} ;
2020-06-15 15:56:04 +00:00
occ = mkOption {
type = types . package ;
default = occ ;
2022-09-09 14:08:57 +00:00
defaultText = literalMD " g e n e r a t e d s c r i p t " ;
2020-06-15 15:56:04 +00:00
internal = true ;
2022-09-09 14:08:57 +00:00
description = lib . mdDoc ''
2020-06-15 15:56:04 +00:00
The nextcloud-occ program preconfigured to target this Nextcloud instance .
'' ;
} ;
2022-09-09 14:08:57 +00:00
globalProfiles = mkEnableOption ( lib . mdDoc " g l o b a l p r o f i l e s " ) // {
description = lib . mdDoc ''
Makes user-profiles globally available under ` nextcloud.tld/u/user.name ` .
2022-04-27 09:35:20 +00:00
Even though it's enabled by default in Nextcloud , it must be explicitly enabled
here because it has the side-effect that personal information is even accessible to
unauthenticated users by default .
2022-08-21 13:32:41 +00:00
By default , the following properties are set to “ Show to everyone ”
2022-04-27 09:35:20 +00:00
if this flag is enabled :
2022-09-09 14:08:57 +00:00
- About
- Full name
- Headline
- Organisation
- Profile picture
- Role
- Twitter
- Website
2022-04-27 09:35:20 +00:00
Only has an effect in Nextcloud 23 and later .
'' ;
} ;
2022-01-22 01:22:15 +00:00
2022-08-12 12:06:08 +00:00
extraOptions = mkOption {
type = jsonFormat . type ;
default = { } ;
description = lib . mdDoc ''
Extra options which should be appended to nextcloud's config . php file .
'' ;
example = literalExpression '' {
redis = {
host = " / r u n / r e d i s / r e d i s . s o c k " ;
port = 0 ;
dbindex = 0 ;
password = " s e c r e t " ;
timeout = 1 .5 ;
} ;
} '' ;
} ;
secretFile = mkOption {
type = types . nullOr types . str ;
default = null ;
2022-08-21 13:32:41 +00:00
description = lib . mdDoc ''
2022-08-12 12:06:08 +00:00
Secret options which will be appended to nextcloud's config . php file ( written as JSON , in the same
2022-08-21 13:32:41 +00:00
form as the [ ] ( #opt-services.nextcloud.extraOptions) option), for example
` { " r e d i s " : { " p a s s w o r d " : " s e c r e t " } } ` .
2022-08-12 12:06:08 +00:00
'' ;
} ;
2022-05-18 14:49:53 +00:00
nginx = {
recommendedHttpHeaders = mkOption {
type = types . bool ;
default = true ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc " E n a b l e a d d i t i o n a l r e c o m m e n d e d H T T P r e s p o n s e h e a d e r s " ;
2022-05-18 14:49:53 +00:00
} ;
hstsMaxAge = mkOption {
type = types . ints . positive ;
default = 15552000 ;
2022-08-12 12:06:08 +00:00
description = lib . mdDoc ''
Value for the ` max-age ` directive of the HTTP
` Strict-Transport-Security ` header .
2022-05-18 14:49:53 +00:00
See section 6 .1 .1 of IETF RFC 6797 for detailed information on this
directive and header .
'' ;
} ;
2022-01-22 01:22:15 +00:00
} ;
2020-04-24 23:36:52 +00:00
} ;
config = mkIf cfg . enable ( mkMerge [
2021-10-28 06:52:43 +00:00
{ warnings = let
2023-07-15 17:15:38 +00:00
latest = 27 ;
2020-10-07 09:15:18 +00:00
upgradeWarning = major : nixos :
''
A legacy Nextcloud install ( from before NixOS $ { nixos } ) may be installed .
2020-04-24 23:36:52 +00:00
2020-10-07 09:15:18 +00:00
After nextcloud $ { toString major } is installed successfully , you can safely upgrade
to $ { toString ( major + 1 ) } . The latest version available is nextcloud $ { toString latest } .
2020-04-24 23:36:52 +00:00
2020-10-07 09:15:18 +00:00
Please note that Nextcloud doesn't support upgrades across multiple major versions
( i . e . an upgrade from 16 is possible to 17 , but not 16 to 18 ) .
2020-04-24 23:36:52 +00:00
2020-10-07 09:15:18 +00:00
The package can be upgraded by explicitly declaring the service-option
` services . nextcloud . package ` .
'' ;
2021-10-04 12:37:57 +00:00
2020-10-07 09:15:18 +00:00
in ( optional ( cfg . poolConfig != null ) ''
Using config . services . nextcloud . poolConfig is deprecated and will become unsupported in a future release .
Please migrate your configuration to config . services . nextcloud . poolSettings .
2020-06-15 15:56:04 +00:00
'' )
2022-10-30 15:09:59 +00:00
++ ( optional ( versionOlder cfg . package . version " 2 5 " ) ( upgradeWarning 24 " 2 2 . 1 1 " ) )
2023-03-24 00:07:29 +00:00
++ ( optional ( versionOlder cfg . package . version " 2 6 " ) ( upgradeWarning 25 " 2 3 . 0 5 " ) )
2023-07-15 17:15:38 +00:00
++ ( optional ( versionOlder cfg . package . version " 2 7 " ) ( upgradeWarning 26 " 2 3 . 1 1 " ) )
2022-11-21 17:40:18 +00:00
++ ( optional cfg . enableBrokenCiphersForSSE ''
You're using PHP's openssl extension built against OpenSSL 1 .1 for Nextcloud .
This is only necessary if you're using Nextcloud's server-side encryption .
Please keep in mind that it's using the broken RC4 cipher .
If you don't use that feature , you can switch to OpenSSL 3 and get
rid of this warning by declaring
services . nextcloud . enableBrokenCiphersForSSE = false ;
2022-12-28 21:21:41 +00:00
If you need to use server-side encryption you can ignore this warning .
2022-11-21 17:40:18 +00:00
Otherwise you'd have to disable server-side encryption first in order
to be able to safely disable this option and get rid of this warning .
See < https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html #disabling-encryption> on how to achieve this.
For more context , here is the implementing pull request : https://github.com/NixOS/nixpkgs/pull/198470
2023-04-29 16:46:19 +00:00
'' )
++ ( optional ( cfg . enableBrokenCiphersForSSE && versionAtLeast cfg . package . version " 2 6 " ) ''
Nextcloud26 supports RC4 without requiring legacy OpenSSL , so
` services . nextcloud . enableBrokenCiphersForSSE ` can be set to ` false ` .
2023-03-24 00:07:29 +00:00
'' ) ;
2020-04-24 23:36:52 +00:00
services . nextcloud . package = with pkgs ;
mkDefault (
if pkgs ? nextcloud
then throw ''
The ` pkgs . nextcloud ` - attribute has been removed . If it's supposed to be the default
nextcloud defined in an overlay , please set ` services . nextcloud . package ` to
` pkgs . nextcloud ` .
''
2022-10-30 15:09:59 +00:00
else if versionOlder stateVersion " 2 2 . 1 1 " then nextcloud24
2023-03-24 00:07:29 +00:00
else if versionOlder stateVersion " 2 3 . 0 5 " then nextcloud25
2023-07-15 17:15:38 +00:00
else if versionOlder stateVersion " 2 3 . 1 1 " then nextcloud26
else nextcloud27
2020-04-24 23:36:52 +00:00
) ;
2021-10-04 12:37:57 +00:00
services . nextcloud . phpPackage =
2023-03-24 00:07:29 +00:00
if versionOlder cfg . package . version " 2 6 " then pkgs . php81
else pkgs . php82 ;
2020-04-24 23:36:52 +00:00
}
2022-04-27 09:35:20 +00:00
{ assertions = [
2023-05-24 13:37:59 +00:00
{ assertion = cfg . database . createLocally -> cfg . config . dbpassFile == null ;
message = ''
Using ` services . nextcloud . database . createLocally ` with database
password authentication is no longer supported .
If you use an external database ( or want to use password auth for any
other reason ) , set ` services . nextcloud . database . createLocally ` to
` false ` . The database won't be managed for you ( use ` services . mysql `
if you want to set it up ) .
If you want this module to manage your nextcloud database for you ,
unset ` services . nextcloud . config . dbpassFile ` and
` services . nextcloud . config . dbhost ` to use socket authentication
instead of password .
'' ;
2022-04-27 09:35:20 +00:00
}
] ; }
2020-04-24 23:36:52 +00:00
{ systemd . timers . nextcloud-cron = {
wantedBy = [ " t i m e r s . t a r g e t " ] ;
2022-07-14 12:49:19 +00:00
after = [ " n e x t c l o u d - s e t u p . s e r v i c e " ] ;
2020-04-24 23:36:52 +00:00
timerConfig . OnBootSec = " 5 m " ;
2021-12-06 16:07:01 +00:00
timerConfig . OnUnitActiveSec = " 5 m " ;
2020-04-24 23:36:52 +00:00
timerConfig . Unit = " n e x t c l o u d - c r o n . s e r v i c e " ;
} ;
2022-01-27 00:19:43 +00:00
systemd . tmpfiles . rules = [ " d ${ cfg . home } 0 7 5 0 n e x t c l o u d n e x t c l o u d " ] ;
2020-04-24 23:36:52 +00:00
systemd . services = {
2020-06-15 15:56:04 +00:00
# When upgrading the Nextcloud package, Nextcloud can report errors such as
# "The files of the app [all apps in /var/lib/nextcloud/apps] were not replaced correctly"
# Restarting phpfpm on Nextcloud package update fixes these issues (but this is a workaround).
phpfpm-nextcloud . restartTriggers = [ cfg . package ] ;
2020-04-24 23:36:52 +00:00
nextcloud-setup = let
c = cfg . config ;
2022-12-28 21:21:41 +00:00
writePhpArray = a : " [ ${ concatMapStringsSep " , " ( val : '' " ${ toString val } " '' ) a } ] " ;
2021-10-06 13:57:05 +00:00
requiresReadSecretFunction = c . dbpassFile != null || c . objectstore . s3 . enable ;
objectstoreConfig = let s3 = c . objectstore . s3 ; in optionalString s3 . enable ''
' objectstore' = > [
' class' = > ' \ \ OC \ \ Files \ \ ObjectStore \ \ S3' ,
' arguments' = > [
' bucket' = > ' $ { s3 . bucket } ' ,
' autocreate' = > $ { boolToString s3 . autocreate } ,
' key' = > ' $ { s3 . key } ' ,
' secret' = > nix_read_secret ( ' $ { s3 . secretFile } ' ) ,
$ { optionalString ( s3 . hostname != null ) " ' h o s t n a m e ' = > ' ${ s3 . hostname } ' , " }
$ { optionalString ( s3 . port != null ) " ' p o r t ' = > ${ toString s3 . port } , " }
' use_ssl' = > $ { boolToString s3 . useSsl } ,
$ { optionalString ( s3 . region != null ) " ' r e g i o n ' = > ' ${ s3 . region } ' , " }
' use_path_style' = > $ { boolToString s3 . usePathStyle } ,
2023-03-24 00:07:29 +00:00
$ { optionalString ( s3 . sseCKeyFile != null ) " ' s s e _ c _ k e y ' = > n i x _ r e a d _ s e c r e t ( ' ${ s3 . sseCKeyFile } ' ) , " }
2021-10-06 13:57:05 +00:00
] ,
]
'' ;
2021-10-14 00:43:12 +00:00
showAppStoreSetting = cfg . appstoreEnable != null || cfg . extraApps != { } ;
renderedAppStoreSetting =
let
x = cfg . appstoreEnable ;
in
if x == null then " f a l s e "
else boolToString x ;
2022-04-27 09:35:20 +00:00
nextcloudGreaterOrEqualThan = req : versionAtLeast cfg . package . version req ;
2020-04-24 23:36:52 +00:00
overrideConfig = pkgs . writeText " n e x t c l o u d - c o n f i g . p h p " ''
< ? php
2021-10-06 13:57:05 +00:00
$ { optionalString requiresReadSecretFunction ''
function nix_read_secret ( $ file ) {
2020-04-24 23:36:52 +00:00
if ( ! file_exists ( $ file ) ) {
throw new \ RuntimeException ( sprintf (
2021-10-06 13:57:05 +00:00
" C a n n o t s t a r t N e x t c l o u d , s e c r e t f i l e % s s e t b y N i x O S d o e s n ' t s e e m t o "
2020-12-25 13:55:36 +00:00
. " e x i s t ! P l e a s e m a k e s u r e t h a t t h e f i l e e x i s t s a n d h a s a p p r o p r i a t e "
. " p e r m i s s i o n s f o r u s e r & g r o u p ' n e x t c l o u d ' ! " ,
2020-04-24 23:36:52 +00:00
$ file
) ) ;
}
return trim ( file_get_contents ( $ file ) ) ;
2022-08-12 12:06:08 +00:00
} '' }
function nix_decode_json_file ( $ file , $ error ) {
if ( ! file_exists ( $ file ) ) {
throw new \ RuntimeException ( sprintf ( $ error , $ file ) ) ;
2020-04-24 23:36:52 +00:00
}
2022-08-12 12:06:08 +00:00
$ decoded = json_decode ( file_get_contents ( $ file ) , true ) ;
if ( json_last_error ( ) != = JSON_ERROR_NONE ) {
throw new \ RuntimeException ( sprintf ( " C a n n o t d e c o d e % s , b e c a u s e : % s " , $ file , json_last_error_msg ( ) ) ) ;
}
return $ decoded ;
}
2020-04-24 23:36:52 +00:00
$ CONFIG = [
' apps_paths' = > [
2021-10-14 00:43:12 +00:00
$ { optionalString ( cfg . extraApps != { } ) " [ ' p a t h ' = > ' ${ cfg . home } / n i x - a p p s ' , ' u r l ' = > ' / n i x - a p p s ' , ' w r i t a b l e ' = > f a l s e ] , " }
2020-04-24 23:36:52 +00:00
[ ' path' = > ' $ { cfg . home } /apps ' , ' url' = > ' /apps ' , ' writable' = > false ] ,
[ ' path' = > ' $ { cfg . home } /store-apps ' , ' url' = > ' /store-apps ' , ' writable' = > true ] ,
] ,
2021-10-14 00:43:12 +00:00
$ { optionalString ( showAppStoreSetting ) " ' a p p s t o r e e n a b l e d ' = > ${ renderedAppStoreSetting } , " }
' datadirectory' = > ' $ { datadir } /data ' ,
2020-04-24 23:36:52 +00:00
' skeletondirectory' = > ' $ { cfg . skeletonDirectory } ' ,
$ { optionalString cfg . caching . apcu " ' m e m c a c h e . l o c a l ' = > ' \\ O C \\ M e m c a c h e \\ A P C u ' , " }
2022-11-02 22:02:43 +00:00
' log_type' = > ' $ { cfg . logType } ' ,
2022-05-18 14:49:53 +00:00
' loglevel' = > ' $ { builtins . toString cfg . logLevel } ' ,
2020-04-24 23:36:52 +00:00
$ { optionalString ( c . overwriteProtocol != null ) " ' o v e r w r i t e p r o t o c o l ' = > ' ${ c . overwriteProtocol } ' , " }
$ { optionalString ( c . dbname != null ) " ' d b n a m e ' = > ' ${ c . dbname } ' , " }
$ { optionalString ( c . dbhost != null ) " ' d b h o s t ' = > ' ${ c . dbhost } ' , " }
$ { optionalString ( c . dbport != null ) " ' d b p o r t ' = > ' ${ toString c . dbport } ' , " }
$ { optionalString ( c . dbuser != null ) " ' d b u s e r ' = > ' ${ c . dbuser } ' , " }
$ { optionalString ( c . dbtableprefix != null ) " ' d b t a b l e p r e f i x ' = > ' ${ toString c . dbtableprefix } ' , " }
2022-08-12 12:06:08 +00:00
$ { optionalString ( c . dbpassFile != null ) ''
' dbpassword' = > nix_read_secret (
" ${ c . dbpassFile } "
) ,
''
}
2020-04-24 23:36:52 +00:00
' dbtype' = > ' $ { c . dbtype } ' ,
2022-12-28 21:21:41 +00:00
' trusted_domains' = > $ { writePhpArray ( [ cfg . hostName ] ++ c . extraTrustedDomains ) } ,
' trusted_proxies' = > $ { writePhpArray ( c . trustedProxies ) } ,
2021-03-09 03:18:52 +00:00
$ { optionalString ( c . defaultPhoneRegion != null ) " ' d e f a u l t _ p h o n e _ r e g i o n ' = > ' ${ c . defaultPhoneRegion } ' , " }
2022-06-16 17:23:12 +00:00
$ { optionalString ( nextcloudGreaterOrEqualThan " 2 3 " ) " ' p r o f i l e . e n a b l e d ' = > ${ boolToString cfg . globalProfiles } , " }
2021-10-06 13:57:05 +00:00
$ { objectstoreConfig }
2020-04-24 23:36:52 +00:00
] ;
2022-08-12 12:06:08 +00:00
$ CONFIG = array_replace_recursive ( $ CONFIG , nix_decode_json_file (
" ${ jsonFormat . generate " n e x t c l o u d - e x t r a O p t i o n s . j s o n " cfg . extraOptions } " ,
" i m p o s s i b l e : t h i s s h o u l d n e v e r h a p p e n ( d e c o d i n g g e n e r a t e d e x t r a O p t i o n s f i l e % s f a i l e d ) "
) ) ;
$ { optionalString ( cfg . secretFile != null ) ''
$ CONFIG = array_replace_recursive ( $ CONFIG , nix_decode_json_file (
" ${ cfg . secretFile } " ,
" C a n n o t s t a r t N e x t c l o u d , s e c r e t s f i l e % s s e t b y N i x O S d o e s n ' t e x i s t ! "
) ) ;
'' }
2020-04-24 23:36:52 +00:00
'' ;
occInstallCmd = let
2021-10-11 16:52:03 +00:00
mkExport = { arg , value }: " e x p o r t ${ arg } = ${ value } " ;
dbpass = {
arg = " D B P A S S " ;
value = if c . dbpassFile != null
then '' " $( < " ${ toString c . dbpassFile } " ) " ''
else '' " " '' ;
} ;
adminpass = {
arg = " A D M I N P A S S " ;
value = '' " $( < " ${ toString c . adminpassFile } " ) " '' ;
} ;
2020-04-24 23:36:52 +00:00
installFlags = concatStringsSep " \\ \n "
( mapAttrsToList ( k : v : " ${ k } ${ toString v } " ) {
" - - d a t a b a s e " = '' " ${ c . dbtype } " '' ;
# The following attributes are optional depending on the type of
# database. Those that evaluate to null on the left hand side
# will be omitted.
$ { if c . dbname != null then " - - d a t a b a s e - n a m e " else null } = '' " ${ c . dbname } " '' ;
$ { if c . dbhost != null then " - - d a t a b a s e - h o s t " else null } = '' " ${ c . dbhost } " '' ;
$ { if c . dbport != null then " - - d a t a b a s e - p o r t " else null } = '' " ${ toString c . dbport } " '' ;
$ { if c . dbuser != null then " - - d a t a b a s e - u s e r " else null } = '' " ${ c . dbuser } " '' ;
2022-11-21 17:40:18 +00:00
" - - d a t a b a s e - p a s s " = " \" \$ ${ dbpass . arg } \" " ;
2020-04-24 23:36:52 +00:00
" - - a d m i n - u s e r " = '' " ${ c . adminuser } " '' ;
2022-11-21 17:40:18 +00:00
" - - a d m i n - p a s s " = " \" \$ ${ adminpass . arg } \" " ;
2021-10-14 00:43:12 +00:00
" - - d a t a - d i r " = '' " ${ datadir } / d a t a " '' ;
2020-04-24 23:36:52 +00:00
} ) ;
in ''
2021-10-11 16:52:03 +00:00
$ { mkExport dbpass }
$ { mkExport adminpass }
2020-04-24 23:36:52 +00:00
$ { occ } /bin/nextcloud-occ maintenance:install \
$ { installFlags }
'' ;
occSetTrustedDomainsCmd = concatStringsSep " \n " ( imap0
( i : v : ''
$ { occ } /bin/nextcloud-occ config:system:set trusted_domains \
$ { toString i } - - value = " ${ toString v } "
'' ) ( [ c f g . h o s t N a m e ] + + c f g . c o n f i g . e x t r a T r u s t e d D o m a i n s ) ) ;
in {
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
before = [ " p h p f p m - n e x t c l o u d . s e r v i c e " ] ;
2023-05-24 13:37:59 +00:00
after = optional mysqlLocal " m y s q l . s e r v i c e " ++ optional pgsqlLocal " p o s t g r e s q l . s e r v i c e " ;
requires = optional mysqlLocal " m y s q l . s e r v i c e " ++ optional pgsqlLocal " p o s t g r e s q l . s e r v i c e " ;
2020-04-24 23:36:52 +00:00
path = [ occ ] ;
script = ''
2021-02-13 14:23:35 +00:00
$ { optionalString ( c . dbpassFile != null ) ''
if [ ! - r " ${ c . dbpassFile } " ] ; then
echo " d b p a s s F i l e ${ c . dbpassFile } i s n o t r e a d a b l e b y n e x t c l o u d : n e x t c l o u d ! A b o r t i n g . . . "
exit 1
fi
if [ - z " $ ( < ${ c . dbpassFile } ) " ] ; then
echo " d b p a s s F i l e ${ c . dbpassFile } i s e m p t y ! "
exit 1
fi
'' }
2021-10-11 16:52:03 +00:00
if [ ! - r " ${ c . adminpassFile } " ] ; then
echo " a d m i n p a s s F i l e ${ c . adminpassFile } i s n o t r e a d a b l e b y n e x t c l o u d : n e x t c l o u d ! A b o r t i n g . . . "
exit 1
fi
if [ - z " $ ( < ${ c . adminpassFile } ) " ] ; then
echo " a d m i n p a s s F i l e ${ c . adminpassFile } i s e m p t y ! "
exit 1
fi
2021-02-13 14:23:35 +00:00
2020-04-24 23:36:52 +00:00
ln - sf $ { cfg . package } /apps $ { cfg . home } /
2021-10-14 00:43:12 +00:00
# Install extra apps
ln - sfT \
$ { pkgs . linkFarm " n i x - a p p s "
( mapAttrsToList ( name : path : { inherit name path ; } ) cfg . extraApps ) } \
$ { cfg . home } /nix-apps
2020-08-20 17:08:02 +00:00
# create nextcloud directories.
# if the directories exist already with wrong permissions, we fix that
2021-10-14 00:43:12 +00:00
for dir in $ { datadir } /config $ { datadir } /data $ { cfg . home } /store-apps $ { cfg . home } /nix-apps ; do
2020-08-20 17:08:02 +00:00
if [ ! - e $ dir ] ; then
install - o nextcloud - g nextcloud - d $ dir
elif [ $ ( stat - c " % G " $ dir ) != " n e x t c l o u d " ] ; then
chgrp - R nextcloud $ dir
fi
done
2021-10-14 00:43:12 +00:00
ln - sf $ { overrideConfig } $ { datadir } /config/override.config.php
2020-04-24 23:36:52 +00:00
# Do not install if already installed
2021-10-14 00:43:12 +00:00
if [ [ ! - e $ { datadir } /config/config.php ] ] ; then
2020-04-24 23:36:52 +00:00
$ { occInstallCmd }
fi
$ { occ } /bin/nextcloud-occ upgrade
$ { occ } /bin/nextcloud-occ config:system:delete trusted_domains
2021-10-14 00:43:12 +00:00
$ { optionalString ( cfg . extraAppsEnable && cfg . extraApps != { } ) ''
2022-06-16 17:23:12 +00:00
# Try to enable apps
2021-10-14 00:43:12 +00:00
$ { occ } /bin/nextcloud-occ app:enable $ { concatStringsSep " " ( attrNames cfg . extraApps ) }
'' }
2020-04-24 23:36:52 +00:00
$ { occSetTrustedDomainsCmd }
'' ;
serviceConfig . Type = " o n e s h o t " ;
2020-08-20 17:08:02 +00:00
serviceConfig . User = " n e x t c l o u d " ;
2023-03-24 00:07:29 +00:00
# On Nextcloud ≥ 26, it is not necessary to patch the database files to prevent
# an automatic creation of the database user.
environment . NC_setup_create_db_user = lib . mkIf ( nextcloudGreaterOrEqualThan " 2 6 " ) " f a l s e " ;
2020-04-24 23:36:52 +00:00
} ;
nextcloud-cron = {
2022-07-14 12:49:19 +00:00
after = [ " n e x t c l o u d - s e t u p . s e r v i c e " ] ;
2021-10-14 00:43:12 +00:00
environment . NEXTCLOUD_CONFIG_DIR = " ${ datadir } / c o n f i g " ;
2020-04-24 23:36:52 +00:00
serviceConfig . Type = " o n e s h o t " ;
serviceConfig . User = " n e x t c l o u d " ;
serviceConfig . ExecStart = " ${ phpPackage } / b i n / p h p - f ${ cfg . package } / c r o n . p h p " ;
} ;
nextcloud-update-plugins = mkIf cfg . autoUpdateApps . enable {
2022-07-14 12:49:19 +00:00
after = [ " n e x t c l o u d - s e t u p . s e r v i c e " ] ;
2020-04-24 23:36:52 +00:00
serviceConfig . Type = " o n e s h o t " ;
serviceConfig . ExecStart = " ${ occ } / b i n / n e x t c l o u d - o c c a p p : u p d a t e - - a l l " ;
serviceConfig . User = " n e x t c l o u d " ;
startAt = cfg . autoUpdateApps . startAt ;
} ;
} ;
services . phpfpm = {
pools . nextcloud = {
user = " n e x t c l o u d " ;
2020-08-20 17:08:02 +00:00
group = " n e x t c l o u d " ;
2020-04-24 23:36:52 +00:00
phpPackage = phpPackage ;
phpEnv = {
2021-10-14 00:43:12 +00:00
NEXTCLOUD_CONFIG_DIR = " ${ datadir } / c o n f i g " ;
2020-04-24 23:36:52 +00:00
PATH = " / r u n / w r a p p e r s / b i n : / n i x / v a r / n i x / p r o f i l e s / d e f a u l t / b i n : / r u n / c u r r e n t - s y s t e m / s w / b i n : / u s r / b i n : / b i n " ;
} ;
settings = mapAttrs ( name : mkDefault ) {
2020-08-20 17:08:02 +00:00
" l i s t e n . o w n e r " = config . services . nginx . user ;
" l i s t e n . g r o u p " = config . services . nginx . group ;
2020-04-24 23:36:52 +00:00
} // cfg . poolSettings ;
extraConfig = cfg . poolConfig ;
} ;
} ;
2020-08-20 17:08:02 +00:00
users . users . nextcloud = {
2020-04-24 23:36:52 +00:00
home = " ${ cfg . home } " ;
2020-08-20 17:08:02 +00:00
group = " n e x t c l o u d " ;
2021-04-15 00:37:46 +00:00
isSystemUser = true ;
2020-04-24 23:36:52 +00:00
} ;
2020-08-20 17:08:02 +00:00
users . groups . nextcloud . members = [ " n e x t c l o u d " config . services . nginx . user ] ;
2020-04-24 23:36:52 +00:00
environment . systemPackages = [ occ ] ;
2023-05-24 13:37:59 +00:00
services . mysql = lib . mkIf mysqlLocal {
2022-04-27 09:35:20 +00:00
enable = true ;
package = lib . mkDefault pkgs . mariadb ;
ensureDatabases = [ cfg . config . dbname ] ;
ensureUsers = [ {
name = cfg . config . dbuser ;
ensurePermissions = { " ${ cfg . config . dbname } . * " = " A L L P R I V I L E G E S " ; } ;
} ] ;
2023-05-24 13:37:59 +00:00
} ;
services . postgresql = mkIf pgsqlLocal {
enable = true ;
ensureDatabases = [ cfg . config . dbname ] ;
ensureUsers = [ {
name = cfg . config . dbuser ;
ensurePermissions = { " D A T A B A S E ${ cfg . config . dbname } " = " A L L P R I V I L E G E S " ; } ;
} ] ;
} ;
services . redis . servers . nextcloud = lib . mkIf cfg . configureRedis {
enable = true ;
user = " n e x t c l o u d " ;
} ;
services . nextcloud = lib . mkIf cfg . configureRedis {
caching . redis = true ;
extraOptions = {
2023-07-15 17:15:38 +00:00
" m e m c a c h e . d i s t r i b u t e d " = '' \ O C \ M e m c a c h e \ R e d i s '' ;
" m e m c a c h e . l o c k i n g " = '' \ O C \ M e m c a c h e \ R e d i s '' ;
2023-05-24 13:37:59 +00:00
redis = {
host = config . services . redis . servers . nextcloud . unixSocket ;
port = 0 ;
} ;
} ;
2022-04-27 09:35:20 +00:00
} ;
2020-08-20 17:08:02 +00:00
services . nginx . enable = mkDefault true ;
2020-10-07 09:15:18 +00:00
2021-07-14 22:03:04 +00:00
services . nginx . virtualHosts . ${ cfg . hostName } = {
2020-08-20 17:08:02 +00:00
root = cfg . package ;
locations = {
" = / r o b o t s . t x t " = {
priority = 100 ;
2020-04-24 23:36:52 +00:00
extraConfig = ''
2020-08-20 17:08:02 +00:00
allow all ;
access_log off ;
2020-04-24 23:36:52 +00:00
'' ;
} ;
2021-03-09 03:18:52 +00:00
" = / " = {
priority = 100 ;
extraConfig = ''
if ( $ http_user_agent ~ ^ DavClnt ) {
return 302 /remote.php/webdav / $ is_args $ args ;
}
'' ;
} ;
2020-08-20 17:08:02 +00:00
" / " = {
priority = 900 ;
2020-11-03 02:18:15 +00:00
extraConfig = " r e w r i t e ^ / i n d e x . p h p ; " ;
2020-08-20 17:08:02 +00:00
} ;
" ~ ^ / s t o r e - a p p s " = {
priority = 201 ;
extraConfig = " r o o t ${ cfg . home } ; " ;
} ;
2021-10-14 00:43:12 +00:00
" ~ ^ / n i x - a p p s " = {
priority = 201 ;
extraConfig = " r o o t ${ cfg . home } ; " ;
} ;
2020-08-20 17:08:02 +00:00
" ^ ~ / . w e l l - k n o w n " = {
priority = 210 ;
extraConfig = ''
2021-02-17 17:02:09 +00:00
absolute_redirect off ;
2020-08-20 17:08:02 +00:00
location = /.well-known/carddav {
2021-02-16 17:04:54 +00:00
return 301 /remote.php/dav ;
2020-08-20 17:08:02 +00:00
}
location = /.well-known/caldav {
2021-02-16 17:04:54 +00:00
return 301 /remote.php/dav ;
2020-08-20 17:08:02 +00:00
}
2021-03-09 03:18:52 +00:00
location ~ ^ / \ . well-known / ( ? ! acme-challenge | pki-validation ) {
return 301 /index.php $ request_uri ;
}
2020-08-20 17:08:02 +00:00
try_files $ uri $ uri / = 404 ;
'' ;
} ;
" ~ ^ / ( ? : b u i l d | t e s t s | c o n f i g | l i b | 3 r d p a r t y | t e m p l a t e s | d a t a ) ( ? : $ | / ) " . extraConfig = ''
return 404 ;
'' ;
2021-02-16 17:04:54 +00:00
" ~ ^ / ( ? : \\ . ( ? ! w e l l - k n o w n ) | a u t o t e s t | o c c | i s s u e | i n d i e | d b _ | c o n s o l e ) " . extraConfig = ''
2020-08-20 17:08:02 +00:00
return 404 ;
'' ;
2020-11-03 02:18:15 +00:00
" ~ ^ \\ / ( ? : i n d e x | r e m o t e | p u b l i c | c r o n | c o r e \\ / a j a x \\ / u p d a t e | s t a t u s | o c s \\ / v [ 1 2 ] | u p d a t e r \\ / . + | o c [ m s ] - p r o v i d e r \\ / . + | . + \\ / r i c h d o c u m e n t s c o d e \\ / p r o x y ) \\ . p h p ( ? : $ | \\ / ) " = {
2020-08-20 17:08:02 +00:00
priority = 500 ;
extraConfig = ''
include $ { config . services . nginx . package } /conf/fastcgi.conf ;
fastcgi_split_path_info ^ ( . + ? \ . php ) ( \ \ /. * ) $ ;
set $ path_info $ fastcgi_path_info ;
try_files $ fastcgi_script_name = 404 ;
fastcgi_param PATH_INFO $ path_info ;
fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name ;
fastcgi_param HTTPS $ { if cfg . https then " o n " else " o f f " } ;
fastcgi_param modHeadersAvailable true ;
fastcgi_param front_controller_active true ;
fastcgi_pass unix:$ { fpm . socket } ;
fastcgi_intercept_errors on ;
fastcgi_request_buffering off ;
2022-09-09 14:08:57 +00:00
fastcgi_read_timeout $ { builtins . toString cfg . fastcgiTimeout } s ;
2020-08-20 17:08:02 +00:00
'' ;
} ;
2020-10-11 12:50:04 +00:00
" ~ \\ . ( ? : c s s | j s | w o f f 2 ? | s v g | g i f | m a p ) $ " . extraConfig = ''
2020-08-20 17:08:02 +00:00
try_files $ uri /index.php $ request_uri ;
expires 6 M ;
access_log off ;
'' ;
" ~ ^ \\ / ( ? : u p d a t e r | o c s - p r o v i d e r | o c m - p r o v i d e r ) ( ? : $ | \\ / ) " . extraConfig = ''
try_files $ uri / = 404 ;
index index . php ;
'' ;
2020-10-11 12:50:04 +00:00
" ~ \\ . ( ? : p n g | h t m l | t t f | i c o | j p g | j p e g | b c m a p | m p 4 | w e b m ) $ " . extraConfig = ''
try_files $ uri /index.php $ request_uri ;
access_log off ;
'' ;
2020-04-24 23:36:52 +00:00
} ;
2020-08-20 17:08:02 +00:00
extraConfig = ''
index index . php index . html /index.php $ request_uri ;
2022-01-22 01:22:15 +00:00
$ { optionalString ( cfg . nginx . recommendedHttpHeaders ) ''
add_header X-Content-Type-Options nosniff ;
add_header X-XSS-Protection " 1 ; m o d e = b l o c k " ;
2023-03-27 19:17:25 +00:00
add_header X-Robots-Tag " n o i n d e x , n o f o l l o w " ;
2022-01-22 01:22:15 +00:00
add_header X-Download-Options noopen ;
add_header X-Permitted-Cross-Domain-Policies none ;
add_header X-Frame-Options sameorigin ;
add_header Referrer-Policy no-referrer ;
2022-05-18 14:49:53 +00:00
'' }
$ { optionalString ( cfg . https ) ''
add_header Strict-Transport-Security " m a x - a g e = ${ toString cfg . nginx . hstsMaxAge } ; i n c l u d e S u b D o m a i n s " always ;
2022-01-22 01:22:15 +00:00
'' }
2020-08-20 17:08:02 +00:00
client_max_body_size $ { cfg . maxUploadSize } ;
fastcgi_buffers 64 4 K ;
fastcgi_hide_header X-Powered-By ;
gzip on ;
gzip_vary on ;
gzip_comp_level 4 ;
gzip_min_length 256 ;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth ;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy ;
$ { optionalString cfg . webfinger ''
rewrite ^ /.well-known/host-meta /public.php ? service = host-meta last ;
rewrite ^ /.well-known/host-meta.json /public.php ? service = host-meta-json last ;
'' }
'' ;
2020-04-24 23:36:52 +00:00
} ;
2020-08-20 17:08:02 +00:00
}
2020-04-24 23:36:52 +00:00
] ) ;
2023-02-02 18:25:31 +00:00
meta . doc = ./nextcloud.md ;
2020-04-24 23:36:52 +00:00
}