nginx map directives

Discussion in 'Installation/Configuration' started by notzippy, Sep 12, 2015.

  1. notzippy

    notzippy New Member

    I tried adding map directives to a particular site (it was a wordpress site), so it went like
    map $request_uri $blogid {
        /foo2012    2;
        /foo    3;
        /chfoo    4;
        /foo2013    5;
        /foo2014    8;
        /foo2015    9;
        location ~ ^(/[^/]+/)?files/(?<rt_file>.+) {
            try_files /wp-content/blogs.dir/$blogid/files/$rt_file /wp-includes/ms-files.php?file=$rt_file ;
            access_log off;    log_not_found off; expires max;
    but when I looked at the sites vhosts file (/etc/nginx/sites-available/ the directive did not make it there. After manually adding it to the vhosts it worked ok. Are directives limited in some way for nginx ?

    Gwyneth Llewelyn likes this.
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    Where did you add this directives, in the nginx directives field of the website in ispconfig?
  3. notzippy

    notzippy New Member

    yes that was were I added them.

  4. Because map {} directives have sadly to be outside server {}, ispconfig does not add the directives if you place them inside the nginx directive fields (basically, what happened with notzippy's configuration was that it had been written to Tough!
    But under 3.0, I managed to do a simple trick, which allowed me to use SSL at the same time as map {}:
    (...usual WP Multisite instructions...)
    #avoid php readfile()
    location ^~ /blogs.dir {
            alias {DOCROOT}wp-content/blogs.dir ;
            access_log off; log_not_found off;      expires max;
    # Notice the extra end bracket: it will close the server block, so what comes next is outside it:
    map $http_host $blogid {
        default               0;     1;     2;    3;
    # no end bracket, as ISPConfig will put an end bracket by itself
    This actually used to work quite well!
    Unfortunately, with 3.1 and direct support for Let's Encrypt (even if I don't use it!), ISPConfig will automatically add an extra location {} inside the server block to comply with Let's Encrypt, namely:
            location ~ /\.well-known/acme-challenge/ {
               root /usr/local/ispconfig/interface/acme/;
               index index.html index.htm;
               try_files $uri =404;
    It's a pity that this cannot be disabled... or why it cannot somehow be pushed before everything else, because otherwise, WP Multisite support under nginx will be suboptimal, since it will force all requests to go through PHP, even if they don't need to, making WP Multisite much less performant than single-site WP — truly a pity.
    In any case, I wonder why this block gets added even if the checkbox for Let's Encrypt is unchecked. Maybe it's a bug? Or just a feature? I have no idea.
    Of course you can hack the templates on your own, but that means they will be overwritten sooner or later by a newer version... I've tried to take a look at /usr/local/ispconfig/interface/web/sites/web_vhost_domain_edit.php and try to understand what is happening. It seems that to properly configure Let's Encrypt, the configuration must be set up without SSL and Let's Encrypt, the server reloaded, and afterwards the configuration gets changed again and the above snippet for the 'well-known acme challenge' is appended (and the new configuration with that extra block is then written out and the server reloaded again). Why exactly this has to be done this way is a bit beyond my understanding; nevertheless, I cannot find any plausible reason for SSL automatically triggering Let's Encrypt (the reverse, of course, is true). What I could understand from the code, it only adds this extra block if both SSL and Let's Encrypt are checked. But somehow there must be a bug somewhere, I just can't find it...
    So this means that, for now, we will have to accept a bit worse performance on WP Multisite until someone figures out what is wrong.
  5. Hrrmpf. Nothing is more frustrating than googling for a solution and finding one own's answer from over four years before — at the time, without solution. I wonder if the current version of ISPConfig has an 'official' fix for the above issue? This is just because the lack of a map{} directive is driving me nuts (I have the same issue as @notzippy — adding support for a WordPress multisite installation, which really needs map{} to work...)
    On the other hand, at least under ISPConfig 3.2.2, my ancient trick still works... to an extent. As per the nginx definition, the map{} directive is supposed to come before a server{} directive, and of course we cannot do that in ISPConfig — at least, as far as I know. In some cases, however, even a map{} directive after the server block does something (and at least it doesn't throw any errors) — but not much, I'm afraid.
    My (uninformed) guess is that in this particular context (WordPress multisite installation), nginx is not really following the rule for delivering a static file, but merely falling back to launching ms-files.php and hoping that it gets the file right (it does). Eventually, other rules, other plugins, or even some reverse proxies running on top of the WP installation, may cache the file statically at some point, but it's really a pity we can't do better than this...
    Granted, debugging nginx is not trivial, and I may be wrong!

    (Note to self: I was wrong about how Let's Encrypt works... it actually reconfigures nginx from scratch for the particular website asking for a credential, and then reverts the configuration to what it was before. It's an ugly hack, but apparently certbot manages to do that without breaking things — even when the operation fails, it almost always recovers the 'old' configuration gracefully)
  6. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    I think you may need to use a conf-custom folder instead but I am really not sure whether you should delete the LE acme folder though I think it may be deleted with ##delete## or something like that.
    Gwyneth Llewelyn likes this.
  7. @ahrasis, thanks for the tip! Aye, I might need to do that (is there a way to have different "templates" active at the same time? I'm not talking about the so-called snippets, but rather complete templates).
    Also, on one hand, the mess I had on my side was because I was confusing WordPress multisite configurations: the OP posted a solution for WPMU using subdirectories, while I posted the one which is appropriate for subdomains. In fact, looking back at all my configurations, I seem to have made that mistake several times, and thus the strange unexpected behaviour I had on several WPMU installations... no wonder they misbehaved!
    On the other hand, I'm now thinking that I ought to switch to instead, as per the most recent recommendations, which I wasn't even aware of until I read your own answer to a thread! I'm not necessarily a super-fan of certbot myself, and I welcome any change that makes this insane process a little easier. In fact, I was trying to replace it with lego for no particular reason beyond being a Go fangirl, and because lego seems to be able to automatically connect to DNS providers such as Cloudflare (which I use extensively for all my websites except one!) in order to satisfy Let's Encrypt when, for some reason, web-based certification fails (as it happens under certbot so often...), and the alternative is changing a DNS TXT record...
    Anyway, I'm off-topic here, so I'll stop :)

Share This Page