Nextcloud SNAP - Guide to getting .htacces/pretty urls

.htaccess guide - wip - 27-12-2024

After receiving some help i decided it would be nice to do something back.
I followed some of the stuff from sources below and put them together.

I wanted to get .htaccess working and ‘pretty urls’ props to Gwindalmir and szaimen

TESTED AND WORKS FOR ME!
Instead of https://nc.yourhostname.eu/index.php/apps/dashboard/
you get a nice https://nc.yourhostname.eu/apps/dashboard/
Also my website now shows “secure”
see here : (not sure if it’s related?)

Here’s the steps:
Copy the .htaccess file to a location you can write to:
sudo cp /snap/nextcloud/current/htdocs/.htaccess /var/snap/nextcloud/current/nextcloud/config/

Bind mount the .htaccess file back into the snap, this makes our changes readable by the snap:

sudo mount /var/snap/nextcloud/current/nextcloud/config/.htaccess /snap/nextcloud/current/htdocs/.htaccess -o bind

Now, edit the .htaccess file accordingly, copy this bit into your .htaccess file:

#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####

ErrorDocument 403 /
ErrorDocument 404 /
<IfModule mod_rewrite.c>
  Options -MultiViews
  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
  RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4)$
  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$
  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$
  RewriteCond %{REQUEST_FILENAME} !/remote.php
  RewriteCond %{REQUEST_FILENAME} !/public.php
  RewriteCond %{REQUEST_FILENAME} !/cron.php
  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php
  RewriteCond %{REQUEST_FILENAME} !/status.php
  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php
  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php
  RewriteCond %{REQUEST_FILENAME} !/robots.txt
  RewriteCond %{REQUEST_FILENAME} !/updater/
  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/
  RewriteCond %{REQUEST_FILENAME} !/ocm-provider/
  RewriteCond %{REQUEST_URI} !^/\.well-known/(acme-challenge|pki-validation)/.*
  RewriteRule . index.php [PT,E=PATH_INFO:$1]
  RewriteBase /
  <IfModule mod_env.c>
    SetEnv front_controller_active true
    <IfModule mod_dir.c>
      DirectorySlash off
    </IfModule>
  </IfModule>
</IfModule>

The complete .htaccess file should look something like this:

<IfModule mod_headers.c>
  <IfModule mod_setenvif.c>
    <IfModule mod_fcgid.c>
       SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
       RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
    </IfModule>
    <IfModule mod_proxy_fcgi.c>
       SetEnvIfNoCase Authorization "(.+)" HTTP_AUTHORIZATION=$1
    </IfModule>
    <IfModule mod_lsapi.c>
      SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
      RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
    </IfModule>
  </IfModule>

  <IfModule mod_env.c>
    # Add security and privacy related headers

    # Avoid doubled headers by unsetting headers in "onsuccess" table,
    # then add headers to "always" table: https://github.com/nextcloud/server/pull/19002
    Header onsuccess unset Referrer-Policy
    Header always set Referrer-Policy "no-referrer"

    Header onsuccess unset X-Content-Type-Options
    Header always set X-Content-Type-Options "nosniff"

    Header onsuccess unset X-Frame-Options
    Header always set X-Frame-Options "SAMEORIGIN"

    Header onsuccess unset X-Permitted-Cross-Domain-Policies
    Header always set X-Permitted-Cross-Domain-Policies "none"

    Header onsuccess unset X-Robots-Tag
    Header always set X-Robots-Tag "noindex, nofollow"

    Header onsuccess unset X-XSS-Protection
    Header always set X-XSS-Protection "1; mode=block"

    SetEnv modHeadersAvailable true
  </IfModule>

  # Add cache control for static resources
  <FilesMatch "\.(css|js|mjs|svg|gif|png|jpg|webp|ico|wasm|tflite)$">
    <If "%{QUERY_STRING} =~ /(^|&)v=/">
      Header set Cache-Control "max-age=15778463, immutable"
    </If>
    <Else>
      Header set Cache-Control "max-age=15778463"
    </Else>
  </FilesMatch>

  # Let browsers cache OTF and WOFF files for a week
  <FilesMatch "\.(otf|woff2?)$">
    Header set Cache-Control "max-age=604800"
  </FilesMatch>
</IfModule>

<IfModule mod_php.c>
  php_value mbstring.func_overload 0
  php_value default_charset 'UTF-8'
  php_value output_buffering 0
  <IfModule mod_env.c>
    SetEnv htaccessWorking true
  </IfModule>
</IfModule>

<IfModule mod_mime.c>
  AddType image/svg+xml svg svgz
  AddType application/wasm wasm
  AddEncoding gzip svgz
  # Serve ESM javascript files (.mjs) with correct mime type
  AddType text/javascript js mjs
</IfModule>

<IfModule mod_dir.c>
  DirectoryIndex index.php index.html
</IfModule>

<IfModule pagespeed_module>
  ModPagespeed Off
</IfModule>

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{HTTP_USER_AGENT} DavClnt
  RewriteRule ^$ /remote.php/webdav/ [L,R=302]
  RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
  RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
  RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
  RewriteRule ^remote/(.*) remote.php [QSA,L]
  RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
  RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
  RewriteRule ^ocm-provider/?$ index.php [QSA,L]
  RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
</IfModule>

# Clients like xDavv5 on Android, or Cyberduck, use chunked requests.
# When FastCGI or FPM is used with apache, requests arrive to Nextcloud without any content.
# This leads to the creation of empty files.
# The following directive will force the problematic requests to be buffered before being forwarded to Nextcloud.
# This way, the "Transfer-Encoding" header is removed, the "Content-Length" header is set, and the request content is proxied to Nextcloud.
# Here are more information about the issue:
#  - https://docs.cyberduck.io/mountainduck/issues/fastcgi/
#  - https://docs.nextcloud.com/server/latest/admin_manual/issues/general_troubleshooting.html#troubleshooting-webdav
<IfModule mod_setenvif.c>
  SetEnvIf Transfer-Encoding "chunked" proxy-sendcl=1
</IfModule>

# Apache disabled the sending of the server-side content-length header
# in their 2.4.59 patch updated which breaks some use-cases in Nextcloud.
# Setting ap_trust_cgilike_cl allows to bring back the usual behaviour.
# See https://bz.apache.org/bugzilla/show_bug.cgi?id=68973
<IfModule mod_env.c>
  SetEnv ap_trust_cgilike_cl
</IfModule>

AddDefaultCharset utf-8
Options -Indexes

#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####

ErrorDocument 403 /
ErrorDocument 404 /
<IfModule mod_rewrite.c>
  Options -MultiViews
  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
  RewriteCond %{REQUEST_FILENAME} !\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4)$
  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$
  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$
  RewriteCond %{REQUEST_FILENAME} !/remote.php
  RewriteCond %{REQUEST_FILENAME} !/public.php
  RewriteCond %{REQUEST_FILENAME} !/cron.php
  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php
  RewriteCond %{REQUEST_FILENAME} !/status.php
  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php
  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php
  RewriteCond %{REQUEST_FILENAME} !/robots.txt
  RewriteCond %{REQUEST_FILENAME} !/updater/
  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/
  RewriteCond %{REQUEST_FILENAME} !/ocm-provider/
  RewriteCond %{REQUEST_URI} !^/\.well-known/(acme-challenge|pki-validation)/.*
  RewriteRule . index.php [PT,E=PATH_INFO:$1]
  RewriteBase /
  <IfModule mod_env.c>
    SetEnv front_controller_active true
    <IfModule mod_dir.c>
      DirectorySlash off
    </IfModule>
  </IfModule>
</IfModule>

Restart apache inside the snap so the changes take effect:
sudo snap restart nextcloud.apache

To enable the mount point automatically, add the following to your /etc/fstab file:
/var/snap/nextcloud/current/nextcloud/config/.htaccess /snap/nextcloud/current/htdocs/.htaccess none auto,bind,x-systemd.before=snap.nextcloud.apache.service,x-systemd.requires-mounts-for=/snap/nextcloud/current/,x-systemd.required-by=snap.nextcloud.apache.service 0 0

Then either reboot, or execute:
sudo systemctl daemon-reload; sudo systemctl restart local-fs.target

Note, this does rely on symlinks (/snap/nextcloud/current). Systemd mounting doesn’t work with symlinks, but that’s fine here, since the link itself wouldn’t change unless there was an update. The symlink is parsed only during evaluation (daemon-reload or reboot).
The result is a generated unit named snap-nextcloud-xxxxx-htdocs-.htaccess.mount (for revision xxxxx of nextcloud). Assuming an update to the snap recreates the service unit files, then that mount unit should update accordingly.

Gotchas:

  • sudo nextcloud.occ maintenance:update:htaccess still doesn’t work. I don’t know why.
  • Updates - I don’t know what will happen when the snap updates. Presumably your custom .htaccess file will still replace the original. However, you need to check to make sure the contents haven’t changed separately from what you added.
  • Did get one error that’s new myself : Unable to run check for JavaScript support. Please remedy or confirm manually if your webserver serves `.mjs` files using the JavaScript MIME type. To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule.
  • Also : Could not check for otf loading support. Please check manually if your webserver serves `.otf` files. To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule. For more details see the documentation ↗.

Any tips are welcome, don’t know if you can add co-writers on this forum or something?

Hi, see Remove index.php from urls · Issue #412 · nextcloud-snap/nextcloud-snap · GitHub

1 Like

Yeah, cool to see you here!

Couldn’t find it on this forum at all, or mostly the questions never the solutions (or i just don’t know how to search on these forums… )

I still wonder how i can change the input fields/layout here to use my 34" screen… Got more gray space than actual forum content…

1 Like

Nextcloud-snap Wiki

What is Snap confinement?

Snap confinement is a snap security feature on Ubuntu. This is the reason Nextcloud snap is not supported on non-Ubuntu distributions. So unless you allow the Nextcloud snap to access removable media in /mnt or /media you will not be able to access any other directory outside of the confinement on Ubuntu.

I think i already found that sudo snap connect nextcloud:removable-mediaa while back during my search, the sudo nextcloud.occ maintenance:update:htaccess command didn’t work before i moved my data folder to /mnt/nextcloud, i decided to move the data folder when i couldn’t get .htacces to work.

I’m afraid to run it now and break things.

I do think the .htacces broke the nextcloud office stuff. It can’t edit anything it just downloads every file now, as in png/jpg/mp4/mkv etc. Nothing is played in the browser everything just downloads.

root@nc:~# sudo nextcloud.occ maintenance:update:htaccess

In Setup.php line 514:

/snap/nextcloud/45728/htdocs does not have enough space for writing the htaccess file! Not writing it back!

maintenance:update:htaccess

I’m starting to think using snap wasn’t such a great idea. Yeah gonna start over, i have the feeling i’m fighting snap more than actually getting nextcloud to work. Hope i remember everything i learned so far, because i’m thinking of doing a complete fresh installation of Ubuntu also to lessen the chance that all the stuff i tried bites me lateron. Also i need to take in account that i have : Unifi controller/adguard/wireguard running also. Docker is also running in snap but i haven’t used that yet for anything really so that can go also.

Already found the guide on the forum here and a video on YT (but it’s older) but i’ll give it a try. No harm done i can only learn from this.

This topic was automatically closed 8 days after the last reply. New replies are no longer allowed.