First-time packager - nginx.conf *only* works after editing and un-editing once

Hi all,

I’m packaging “My Idlers”, a MIT-licensed app to keep track of your VPS and other (hosted) services.

The app is built on Laravel/Composer.

Upstream distributes the app with Artisan, I need some help with nginx.

I have trouble getting consistent usable results with my nginx.conf; notably: after installing, I need to comment out a line, restart nginx, uncomment the line, restart once more, to make the app usable.

nginx.conf, as installed at /etc/nginx/conf.d/my_idlers.domain.tld.d/my_idlers.conf
# try redirecting stuff to index.php
rewrite ^(.*)$ /index.php$1 last;
root /var/www/my_idlers/public/;

location / {
  alias /var/www/my_idlers/public/;

  index index.php;
  client_max_body_size 256M;

  #Laravel: append $query_string
  try_files $uri $uri/ /index.php?$query_string;

  location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #fastcgi_pass unix:/var/run/php/php8.3-fpm-my_idlers.sock;
    fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
   
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass_header Authorization;
  }

  # Include SSOWAT user panel.
  include conf.d/yunohost_panel.conf.inc;
}
# not tested; it may have trouble redirecting
location /api/ {
  try_files $uri $uri/ /api/index.php?$query_string;
}

The first line (rewrite) in the nginx.conf above is a workaround to get index.php found at all, but it breaks access to non-php files (CSS, for example)

After I comment out the rewrite, restart nginx, put back the rewrite and restart nginx once more, the app and access to static files work.

Of course, there is a mistake in the config, but I have tried many permutations without reliable result.

Things I think I know, but seem to be unable to do without:

  • rewrite ^(.*)$ /index.php$1 last; drops every request as a parameter into index.php. Usually try_files has the same result, but not here
  • try_files - the directive is supposed to find the requested resource either as a file, as a directory or, if not found, use it as a parameter to index.php. Without the above rewrite rule, it has at least the first, sometimes both of these effects:
    • $path and index.php get concatenated without a / in between, resulting in 404 for /var/www/my_idlers/publicindex.php
    • In some permutations of testing there must have been a relative path I was unable to find, as the 404 mentioned /usr/share/nginx/htmlindex.php ; aigain, notice the missing /.
  • I suppose having both a root directive and a alias directive is superfluous. Should adding the alias for each (nested) location have the same result? I imagine at least location /api/ would need the alias, but the (nested) php location was helped by the root directive.

I should mention that there may be interference from upper level of (generic YNH) nginx conf files. I was able to get the app running via nginx on a non-Yunohost server. The config used then was the starting point for my YNH package.

I’ll be looking forward to any input. In the mean time I’ll be testing some more.

Eeeeh i didn’t read the whole thing but i’m a bit uncomfortable with the first two lines being in global scope

I would ditch the root one that seems unecessary (cf the “alias” 3 lines below that already achieves the thing)

and move the “rewrite” one to inside the location block ?

1 Like

Ha, thanks :slight_smile:

That works, wohoo!

Un-be-lievable, it does not work after all. I must have messed up testing afterwards.

Upon cleaning the repo and testing everything on a new server… The behaviour returs:

  • Upon install, the app works but without CSS (as symptom of unability to serve static files)
  • Comment out the rewrite rule, restart nginx. Now CSS / static files work but PHP files do not.The app breaks.
  • Uncomment the rewrite rule, restart nginx. Now PHP works again, and static files keep working

The rewrite in question is the 4th line in the config below,

  rewrite ^(.*)$ /index.php$1 last;
my_idlers.conf as installed
location / {
  alias /var/www/my_idlers/public/;
  # try redirecting stuff to index.php
  rewrite ^(.*)$ /index.php$1 last;

  index index.php;
  client_max_body_size 256M;

  #Laravel: append $query_string
  try_files $uri $uri/ /index.php?$query_string;

  location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #fastcgi_pass unix:/var/run/php/php8.3-fpm-my_idlers.sock;
    fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
   
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass_header Authorization;
  }

  # Include SSOWAT user panel.
  include conf.d/yunohost_panel.conf.inc;
}
# not tested; it may have trouble redirecting
location /api/ {
  alias /var/www/my_idlers/public/;
  try_files $uri $uri/ /api/index.php?$query_string;
}

Weeeell… One way or another, in utter dispair, I turned to Laravel docs. Lo and behold, there is a nginx conf that, slightly edited to get rid of the server directive, just works.

After all the trouble I went through, the finally working conf file seems deceptively simple:

location / {
    root __INSTALL_DIR__/public;
    try_files $uri $uri/ /index.php?$query_string;
    index index.html index.htm index.php;
}


location ~ \.php$ {
    root __INSTALL_DIR__/public;
    index index.html index.htm index.php;
    fastcgi_pass unix:/var/run/php/php__PHP_VERSION__-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
}

location ~ /\.(?!well-known).* {
    deny all;
}

If one of you got a solution to make it even simpler, please let me know! For now I’m happy the app is working :slight_smile: