-
-
Save schneefux/22b75d2bd3e4e754ba1684f1d1e93271 to your computer and use it in GitHub Desktop.
Nextcloud with Let's encrypt, nginx and uwsgi on NixOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# requires https://github.com/NixOS/nixpkgs/pull/19139 | |
# alternatively, use uwsgi-cgi or phpfpm | |
security.acme.preliminarySelfsigned = true; | |
security.acme.certs = { | |
${config.networking.domain} = { | |
webroot = "/var/www/challenges"; | |
extraDomains = { | |
"cloud.${config.networking.domain}" = null; | |
}; | |
email = "admin@${config.networking.domain}"; | |
postRun = '' | |
systemctl reload nginx.service | |
''; | |
group = "ssl"; | |
allowKeysForGroup = true; | |
}; | |
}; | |
users.groups.ssl = {}; | |
users.users.nginx.extraGroups = [ "ssl" ]; | |
# generate fresh DH params every day | |
systemd.services.gendhparams = { | |
description = "DHParam generator"; | |
after = [ "basic.target" ]; | |
script = '' | |
FILE=`mktemp` | |
${pkgs.openssl.bin}/bin/openssl dhparam -out $FILE 2048 && \ | |
chmod 640 $FILE && \ | |
mv -f $FILE ${config.security.acme.directory}/${config.networking.domain}/dhparams.pem | |
''; | |
serviceConfig.User = "root"; | |
}; | |
systemd.timers.gendhparams = { | |
enable = true; | |
description = "DHParam generator timer"; | |
wantedBy = [ "timers.target" ]; | |
partOf = [ "gendhparams.service" ]; | |
timerConfig = { | |
RandomizedDelaySec = "1h"; | |
OnCalendar = "daily"; | |
Persistent = true; | |
}; | |
}; | |
services.mysql = { | |
enable = true; | |
package = pkgs.mysql; | |
}; | |
# Nextcloud system cron | |
users.users.nginx.useDefaultShell = true; | |
systemd.services.nextcloudcron = { | |
description = "Nextcloud cron"; | |
after = [ "network.target" ]; | |
script = '' | |
${pkgs.php}/bin/php ${pkgs.nextcloud}/cron.php | |
${pkgs.nextcloud-news-updater}/bin/nextcloud-news-updater -t 2 -i 30 --mode singlerun ${pkgs.nextcloud} | |
''; | |
environment = { NEXTCLOUD_CONFIG_DIR = "/var/lib/nextcloud/config"; }; | |
serviceConfig.User = "nginx"; | |
}; | |
systemd.timers.nextcloudcron = { | |
enable = true; | |
description = "Nextcloud cron timer"; | |
wantedBy = [ "timers.target" ]; | |
partOf = [ "Nextcloudcron.service" ]; | |
timerConfig = { | |
RandomizedDelaySec = "5min"; | |
OnCalendar = "*-*-* *:00,30:00"; # every 1/2h | |
Persistent = true; | |
}; | |
}; | |
# web server | |
services.nginx = { | |
enable = true; | |
httpConfig = '' | |
error_log stderr; | |
include ${pkgs.nginx}/conf/mime.types; | |
gzip on; | |
gzip_buffers 16 8k; | |
gzip_comp_level 6; | |
gzip_http_version 1.1; | |
gzip_min_length 256; | |
gzip_proxied any; | |
gzip_vary on; | |
gzip_types | |
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml | |
text/javascript application/javascript application/x-javascript | |
text/x-json application/json application/x-web-app-manifest+json | |
text/css text/plain text/x-component | |
font/opentype application/x-font-ttf application/vnd.ms-fontobject | |
image/x-icon; | |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
ssl_prefer_server_ciphers on; | |
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; | |
ssl_ecdh_curve secp384r1; | |
ssl_session_cache shared:SSL:10m; | |
ssl_session_tickets off; | |
ssl_stapling on; | |
ssl_stapling_verify on; | |
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; | |
add_header Public-Key-Pins 'pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis="; max-age=5184000; includeSubDomains'; # Let's Encrypt HKPK | |
add_header X-Frame-Options DENY; | |
add_header X-Content-Type-Options nosniff; | |
ssl_certificate ${config.security.acme.directory}/${config.networking.domain}/fullchain.pem; | |
ssl_certificate_key ${config.security.acme.directory}/${config.networking.domain}/key.pem; | |
ssl_trusted_certificate ${config.security.acme.directory}/${config.networking.domain}/fullchain.pem; | |
ssl_dhparam ${config.security.acme.directory}/${config.networking.domain}/dhparams.pem; | |
server { | |
listen 80; | |
listen [::]:80; | |
server_name cloud.${config.networking.domain}; | |
location /.well-known/acme-challenge { | |
root /var/www/challenges/; | |
} | |
location / { | |
return 301 https://$server_name$request_uri; | |
} | |
} | |
server { | |
listen 443 ssl http2; | |
listen [::]:443 ssl http2; | |
server_name cloud.${config.networking.domain}; | |
root ${pkgs.nextcloud}; | |
client_max_body_size 10G; | |
gzip off; | |
rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect; | |
rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect; | |
rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect; | |
index index.php; | |
error_page 403 /core/templates/403.php; | |
error_page 404 /core/templates/404.php; | |
add_header X-Content-Type-Options nosniff; | |
add_header X-Frame-Options "SAMEORIGIN"; | |
add_header X-XSS-Protection "1; mode=block"; | |
add_header X-Robots-Tag none; | |
add_header X-Download-Options noopen; | |
add_header X-Permitted-Cross-Domain-Policies none; | |
location = /robots.txt { | |
allow all; | |
log_not_found off; | |
access_log off; | |
} | |
location ~ ^/(?:\.htaccess|config|db_structure\.xml|README){ | |
deny all; | |
} | |
location / { | |
rewrite ^/.well-known/host-meta /public.php?service=host-meta last; | |
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; | |
rewrite ^/.well-known/carddav /remote.php/carddav/ redirect; | |
rewrite ^/.well-known/caldav /remote.php/caldav/ redirect; | |
rewrite ^(/core/doc/[^\/]+/)$ $1/index.html; | |
try_files $uri $uri/ =404; | |
} | |
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) { | |
include ${pkgs.nginx}/conf/uwsgi_params; | |
uwsgi_modifier1 14; | |
uwsgi_hide_header X-Frame-Options; | |
uwsgi_hide_header X-XSS-Protection; | |
uwsgi_hide_header X-Content-Type-Options; | |
uwsgi_hide_header X-Robots-Tag; | |
uwsgi_param MOD_X_ACCEL_REDIRECT_ENABLED on; | |
uwsgi_pass unix:/run/uwsgi/php.sock; | |
} | |
location ~* \.(?:css|js)$ { | |
add_header Cache-Control "public, max-age=7200"; | |
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"; | |
add_header X-Content-Type-Options nosniff; | |
add_header X-Frame-Options "SAMEORIGIN"; | |
add_header X-XSS-Protection "1; mode=block"; | |
add_header X-Robots-Tag none; | |
add_header X-Download-Options noopen; | |
add_header X-Permitted-Cross-Domain-Policies none; | |
access_log off; | |
} | |
location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|swf)$ { | |
access_log off; | |
} | |
location ^~ /data { | |
internal; | |
} | |
location ^~ /apps { | |
alias /var/lib/nextcloud/apps; | |
} | |
} | |
''; | |
}; | |
services.uwsgi = { | |
enable = true; | |
user = "nginx"; | |
group = "nginx"; | |
instance = { | |
type = "emperor"; | |
vassals = { | |
php = { | |
type = "normal"; | |
socket = "/run/uwsgi/php.sock"; | |
master = true; | |
vacuum = true; | |
processes = 16; | |
cheaper = 1; | |
php-sapi-name = "apache"; # opcode caching tweak | |
php-allowed-ext = [ ".php" ".inc" ]; | |
socket-modifier1 = 14; | |
php-index = "index.php"; | |
php-set = "date.timezone=Europe/Berlin"; | |
env = [ | |
"NEXTCLOUD_CONFIG_DIR=/var/lib/nextcloud/config" | |
]; | |
plugins = [ "php" ]; | |
}; | |
}; | |
}; | |
plugins = [ "php" ]; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment