#tryFiles

2026-02-13
Harto de que el OOM Killer haga bien su trabajo. He decidido aprovechar un poco un larkbox siempre en linea para reducir la carga de mi pobre VPS de solo 1gb de RAM

Introducción

Podríamos decir que este articulo es una extensión del anterior que he escrito. Una suma de experiencia acumulada gracias a ideas que han venido pasando por mi mente y que probablemente sirva como idea para algo posterior. En este caso, tras aprender a configurar WireGuard, noté que daba mas ventajas que usar un tunel inverso, así que empece a trastear al darme cuenta que Nginx no sirve solo de proxy inverso para servicios locales, sino también, para otros al alcance de su red.

El problema

No sabría decir si es un problema. Yo solo quería tener nextcloud y todos sus beneficios, pero mis recursos limitados me dejaban con un pobre VPS con un procesador de 1 nucleo, 1GB de ram y 25GB de disco duro, recursos que se acabaron rápidamente a pesar de ser el unico usuario. Al darme cuenta que tengo un LarkBox X 2023-Mini de Chuwi funcionando 24/7 para unos experimentos, me di cuenta que tal vez, lo mejor, seria usarlo de forma local. Pero entonces tendria que perder funciones que me sirven, como el gestor de marcadores flocus o mi bot de icsannouncer o el cliente de correo electrónico (no, no uso el roundcube que dijeron iban a unir a nextcloud) y claro, la funcion de compartir archivos públicamente. La cosa va de que con 1GB no se puede hacer mucho. Solo el servicio de MariaDB consume la mitad de la memoria que hay y se necesita tener activo, como mínimo, los servicios de Nginx, MariaDB, PHP-fpm, fail2ban, SSH y bueno, syncthing que lo tengo por si las dudas. Es también un problema el hecho de que los bots de ia, crawlers y otros esten jode que jode, minando los escasos megas que tiene mi VPS, asi que a cada rato se muere, principalmente, MariaDB, poniendo en riesgo la integridad de la base de datos.

La Solución

En principio pensé que podría aprovechar el túnel inverso que creé y usaba para acceder al terminal del Larkbox. Pero era lento. Y habia que crear un tunel por cada servicio y para coronar, se desconectaba en cada salto de red, por lo que tendría que volver a casa a revivirlo. Esto ultimo lo resolví usando autossh pero igual es un fastidio. Tras conocer WireGuard (lo conocía de hace mucho pero nunca le di importancia) me di cuenta de que no necesitaba usarlo como VPN en el sentido de acceder a paginas restringidas mediante mi server, sino como VPN en el sentido de Red Privada Virtual. Es decir, para acceder mediante internet a mi red domestica y por supuesto, acceder a sus servicios. Queda pendiente escribir sobre el experimento de utilizar Moonlight mediante WireGuard, Pero al notar que se podía levantar el servicio y no necesitar prestarle mayor atención, pensé que podría aprovecharlo para aprovechar NextCloud mediante la VPN. Esto me daba solución a casi todos los problemas que tenia, excepto, la compartición de archivos públicos. Queda pendiente escribir sobre muchas cosas que me di cuenta con este experimento. En realidad se puede hacer mas de lo que haremos en este articulo y me sorprendí. Podría reducir gastos de esta manera y por un instante pensé que incluso podría ahorrarme la factura de la luz mediante paneles solares, pero vamos por partes.

🌟El tutorial🌟

Advertencia. Este tutorial asume que ya tienes instalado y respaldado Nextcloud, WireGuard, Nginx, PHP-FPM y todos los módulos necesarios para que funcione NextCloud .
Debido a que esto es básicamente una migración de un servidor a otro, estoy asumiendo que conoces la mayoría de los pasos descritos en la cita. Ademas ya hay un montón de tutoriales para cada cosa y no quiero ser redundante. WireGuard en cambio, creo que escribiré un tutorial debido a ciertos problemas que me encontré y haré unas cuantas aclaraciones sobre Nginx. Hechas estas aclaraciones, al momento de leer este articulo ya deberías:
  • Creado un archivo zip de tu servidor de origen de las carpetas NextCloud y nextcloud_data
  • Traído estas carpetas a tu nuevo servidor
  • Descomprimido los archivos en sus respectivos directorios
  • Asegurado que los archivos tengan los permisos y propiedades necesarios
  • Creado el tunel entre tu VPS y tu equipo domestico (si, puede ser tu celular si tienes paciencia suficiente)
  • Tener VPS :v
  • Tener dominio :v
  • Tener certificados SSL XD (afortunadamente solo necesitas uno y si como yo, estas migrando desde un servidor ya creado, puedes reaprovechar ese)
Déjame contarte unos cuantos detallitos antes de continuar. Resulta que Nginx funciona distinto según si lo instalas desde los repos de tu distro o desde la pagina del proyecto. Especialmente en Debian/Ubuntu que utilizan un modelo de configuraciones basado en sites-avaliable y sites-enabled. En el Nginx del propio sitio utilizan un modelo único de archivos *.conf dentro de la carpeta conf.d. Te recomiendo este ultimo porque da ciertas ventajas, como disponer de HTTP2 y HTTP3 y mayor seguridad, aparte de estar mas actualizado Lo mismo aplica a MariaDB. Te recomiendo los paquetes oficiales, aunque probablemente te encuentres con un error en Nextcloud que puedes ignorar.
Versión de base de datos Se detectó la versión «12.2.1-MariaDB-ubu2404» de MariaDB. Se sugiere utilizar una versión de MariaDB entre >=10.6 y <=11.8 para un mejor rendimiento, estabilidad y funcionalidad con esta versión de Nextcloud.
¿Dando tanto por sentado esto todavía califica como tutorial? WireGuard permite crear una Red Privada Virtual, en la que cada dispositivo que se una, puede ver a los demás en lo que se conoce como una red Mesh. Por supuesto, esto es en forma virtual, porque fuera de tu red VPN sigues usando el modelo Cliente/Servidor (Estrella), puesto que si el servidor se desconecta, nadie mas puede usar la VPN Arquitecturas de red punto a punto, estrella y mesh Debido a esta arquitectura de red, es posible que cualquier miembro de la red ofrezca servicios y los demás consuman de ellos. Esto incluye al servidor, que puede actuar de cliente para consumir lo que sirva otro miembro de la red VPN. Gracias a esto, podemos permitir al servidor, mediante Nginx, los servicios que ofrezca uno de los clientes. Puede ser cualquiera. Hay que tener en cuenta que este modelo de servidor no es el apropiado para producción, como tampoco lo era el tunel inverso, pero para uso personal, esta muy bien.

Configuración local

Primero, configura Nginx en el equipo local para servir Nextcloud. Te sugiero este modelo de archivo de configuración que me ha servido para este propósito. Por supuesto, puedes servirlo en el puerto 80 como es común para http no seguro, o en cualquier puerto que desees, ajústalo en el archivo de configuración
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
map $arg_v $asset_immutable {
    "" "";
    default "immutable";
}

server {

    server_name tuserverpublico.com;
    server_tokens off;
    access_log /var/log/nginx/nextcloud.tuserverpublico.com.access.log;
    error_log /var/log/nginx/nextcloud.tuserverpublico.com.error.log;
    

    root /var/www/nextcloud;

    client_max_body_size 512M;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    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/wasm 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;

    # Pagespeed is not supported by Nextcloud, so if your server is built
    # with the `ngx_pagespeed` module, uncomment this line to disable it.
    #pagespeed off;

    # The settings allows you to optimize the HTTP2 bandwitdth.
    # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
    # for tunning hints
    client_body_buffer_size 512k;

    # HTTP response headers borrowed from Nextcloud `.htaccess`
    add_header Referrer-Policy                      "no-referrer"   always;
    add_header X-Content-Type-Options               "nosniff"       always;
    add_header X-Download-Options                   "noopen"        always;
    add_header X-Frame-Options                      "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies    "none"          always;
    add_header X-Robots-Tag                         "noindex,nofollow"          always;
    add_header X-XSS-Protection                     "1; mode=block" always;
    add_header Strict-Transport-Security                       "max-age=15768000;includeSubDomains;preload;" always;

    # Remove X-Powered-By, which is an information leak
    fastcgi_hide_header X-Powered-By;

    # Specify how to handle directories -- specifying `/index.php$request_uri`
    # here as the fallback means that Nginx always exhibits the desired behaviour
    # when a client requests a path that corresponds to a directory that exists
    # on the server. In particular, if that directory contains an index.php file,
    # that file is correctly served; if it doesn't, then the request is passed to
    # the front-end controller. This consistent behaviour means that we don't need
    # to specify custom rules for certain paths (e.g. images and other assets,
    # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
    # `try_files $uri $uri/ /index.php$request_uri`
    # always provides the desired behaviour.

    include mime.types;
        types {
            text/javascript mjs;
        }

    # Rules borrowed from `.htaccess` to hide certain paths from clients
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

        index index.php index.html /index.php$request_uri;

        location ~ \.php(?:$|/) {
                #try_files $uri =404;
                #try_files $uri $uri/ /index.php?$args;
                rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;

                fastcgi_split_path_info ^(.+?\.php)(/.*)$;
                try_files $fastcgi_script_name =404;

                set $path_info $fastcgi_path_info;

                #fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
                #include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php8.3-fpm.sock;

                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;

        fastcgi_param modHeadersAvailable true;         # Avoid sending the security headers twice
        fastcgi_param front_controller_active true;     # Enable pretty urls
            #fastcgi_pass php-handler;

        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;

        fastcgi_max_temp_file_size 0;
        #autoindex on;
        }

        location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$ {
                try_files $uri /index.php$request_uri;
                # HTTP response headers borrowed from Nextcloud `.htaccess`
            add_header Cache-Control                     "public, max-age=15778463$asset_immutable";
            add_header Referrer-Policy                   "no-referrer"       always;
            add_header X-Content-Type-Options            "nosniff"           always;
            add_header X-Frame-Options                   "SAMEORIGIN"        always;
            add_header X-Permitted-Cross-Domain-Policies "none"              always;
            add_header X-Robots-Tag                      "noindex, nofollow" always;
            add_header X-XSS-Protection                  "1; mode=block"     always;
            access_log off;     # Optional: Don't log access to assets
            }

            location ~ \.(otf|woff2?)$ {
            try_files $uri /index.php$request_uri;
            expires 7d;         # Cache-Control policy borrowed from `.htaccess`
            access_log off;     # Optional: Don't log access to assets
        }

            # Rule borrowed from `.htaccess`
            location /remote {
                return 301 /remote.php$request_uri;
            }

            location / {
                try_files $uri $uri/ /index.php$request_uri;
                #autoindex on;
            }

            location = / {
            if ( $http_user_agent ~ ^DavClnt ) {
                return 302 /remote.php/webdav/$is_args$args;
            }
        }

        #location ~ /\.ht {
        #       deny all;
        #}

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
            }

    location ^~ /.well-known {
            # The rules in this block are an adaptation of the rules
            # in `.htaccess` that concern `/.well-known`.

        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }

        location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

        # Let Nextcloud's API for `/.well-known` URIs handle all other
        # requests by passing them to the front-end controller.
        return 301 /index.php$request_uri;

        location /.well-known/nodeinfo {
                default_type application/json;
                return 404 '{"message": "nodeinfo not supported"}';
                add_header x-nextcloud-well-known 1 always;
        }

        location /.well-known/webfinger {
                default_type application/json;
                return 404 '{"message": "webfinger not supported"}';
                add_header x-nextcloud-well-known 1 always;
        }
    }

    listen 80;






}
Recuerda reemplazar tuserverpublico.com por el nombre de dominio de tu VPS que recibira el trafico externo y usar el socket de tu instancia de PHP-fpm. En mi caso utilicé fastcgi_pass unix:/run/php/php8.3-fpm.sock; porque es lo que uso. Necesitas ahora agregar al array de configuracion de tu instancia de nextcloud, las siguientes lineas
<?php$CONFIG = array (
  ...
  'trusted_proxies' => ['ip_wireguard_del_servidor '],
  'overwrite.cli.url' => 'https://tuservidorpublico.com',
  'overwritehost' => 'tuservidorpublico.com',
  'overwriteprotocol' => 'https',
  'datadirectory' => '/var/www/nextcloud_data',
  'overwriteprotocol' => 'https',
  'overwrite.cli.url' => 'https://tuservidorpublico.com',
  ...
);
la ip_wireguard_del_servidor es la ip que tiene asignada el servidor publico en la red de WireGuard. recuerda confirmar que este activo overwriteprotocol en https y overwritehost en tu direccion de dominio publica. Otra cosa mas. Es probable que quieras llevar la carpeta de nextcloud_data a otro disco o directorio, pero las politicas de seguridad impiden que hagas esto. Te ahorro sufrimiento diciendotelo para que no pierdas tiempo intentando muchas cosas sin exito. Eso si, recuerda que nextcloud_data, no debe ser servida en publico, por lo que no debe estar dentro de la carpeta nextcloud ni tampoco en algun directorio que se encuentre siendo servido por nginx.

Configuracion del Servidor

Ya estamos en las configuraciones finales. En este caso puedes cambiar solo lo necesario para que tu servidor previo haga de proxy inverso para tu instancia local de NextCloud, pero te comparto las configuraciones necesarias tambien.
map $arg_v $asset_immutable {
    "" "";
    default "immutable";
}

server {
    server_name tuservidorpublico.com;
    server_tokens off;
    access_log /var/log/nginx/tuservidorpublico.com.access.log;
    error_log /var/log/nginx/tuservidorpublico.com.error.log;
    
        location / {
                proxy_pass http://ip_wireguard_del_cliente ;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_buffering off;
                        proxy_request_buffering off;
                        client_max_body_size 512M;
                proxy_cache_bypass $http_upgrade;

                
            }

        location ~ ^/(?:\.|autotest|occ|issue|indie|db_structure|console) {
            deny all;
        }

    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/tuservidorpublico.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/tuservidorpublico.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = tuservidorpublico.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name tuservidorpublico.com;
    listen 80;
    return 404; # managed by Certbot
}
Estas configuraciones son mas cortas, pero tengo algunas observaciones que hacer.
  • proxy_pass ip_wireguard_del_cliente ; debes reemplazarla por la direccion ip que tiene el equipo local en la red WireGuard.
  • Tanto en el equipo local como en el servidor, he segmentado los logs por dominio, para que sea mas facil de depurar.ç
  • Las configuraciones SSL estan manejadas por el certbot. Genera las tuyas propias.
  • listen 443 ssl http2; solo funciona en Nginx de los repositorios nativos de Debian/Ubuntu porque esta desactualizado.

Conclusiones

Con estas configuraciones y observaciones, ya deberías tener una instancia publica de NextCloud, utilizando WireGuard para un servidor local. Puedes servir cualquier otra cosa con esta estrategia pero recuerda tomar todas las medidas de precaución pertinentes pues internet es un lugar salvaje. Consumo de RAM desactivando servicios no necesitados después de mover NextCloud a servidor local Al momento de escribir este articulo, todo funciona bien y el consumo de CPU y RAM de mi servidor ha bajado muchisimo, llegando a consumir solo 205M de RAM de los 979M que dispongo. Por supuesto, si estas usando AWS u otro servicio en el que pagas por consumo, ten cuidado. Esto reduce el consumo de recursos de computo, pero no de red. Debido a que ahora hay mas vueltas, es posible que el consumo de red se duplique, porque el esquema es el siguiente:
  1. El usuario pide un recurso al servidor publico (acceder a la portada, pedir un archivo, etc).
  2. El servidor pide este recurso al servidor local.
  3. WireGuard pide los recursos al servidor loca.
  4. El servidor local responde.
  5. WireGuard entrega los recursos al servidor publico.
  6. El servidor entrega los recursos al cliente.
Es un tramo inmenso en comparacion al modelo tradicional:
  1. El usuario pide un recurso al servidor publico.
  2. El servidor publico entrega el recurso al usuario.
Por supuesto, todo esto es para uso personal. No tengo idea de si es viable para algo mas colectivo. Tengo ciertas dudas sobre esto tambien, en el sentido de que tal vez no valga la pena arriesgar un equipo local debido a que el 2026 promete estar escaso de memorias. Pero bueh, sin riesgos no se aprende. https://interlan.ec/blog/2026/02/13/tutorial-nextcloud-wireguard-nginx/ #autoindex #DIY #fastcgiIndex #fastcgiPass #include #location #nextcloud #nginx #pagespeed #selfhosting #servidores #tryFiles #tutorial #wireguard
Consumo de RAM desactivando servicios no necesitados después de mover NextCloud a servidor localArquitecturas de red punto a punto, estrella y meshConsumo de RAM desactivando servicios no necesitados después de mover NextCloud a servidor local

Client Info

Server: https://mastodon.social
Version: 2025.07
Repository: https://github.com/cyevgeniy/lmst