MediaWiki mit Varnish Cache und NGINX Proxy

Aus RT-Wiki - IT-Notizbuch
Zur Navigation springen Zur Suche springen

MediaWiki / Varnish Cache aktivieren

LocalSettings.php

# Enable Varnish Cache Purge
$wgUseCdn = true;
$wgCdnServers = [ '127.0.0.1', '192.168.1.4:6081' ];
$wgCdnServersNoPurge = [ '192.168.1.4' ];

Die IP 192.168.1.4 entspricht in diesem Beispiel der Adresse des Varnish Servers.

Da Varnish standardmäßig auf Port 6081 läuft, muss dieser in der Konfiguration von MediaWiki mit angegeben werden.

Aufgrund eines Bugs muss die IP gleichzeitig bei $wgCdNServersNoPurge angegeben werden sobald man einen Port definiert.[1]

NGINX Proxy einrichten

sudo vi /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# Nur bei HTTPS
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header HTTPS "on";

HTTP *:80 (Ohne Umleitung auf HTTPS) : Nicht empfehlenswert

server {
        listen 80;
        server_name my.domain.de;
        
		location / {
                include /etc/nginx/proxy_params;
                proxy_pass http://127.0.0.1:6081;
        }
}

HTTP *:80 (Mit Umleitung auf HTTPS):

server {
        listen 80;
        server_name my.domain.de;
        return 301 https://$host$request_uri;
}

HTTPS *:443

server {
        listen 443 ssl;
        server_name my.domain.de;

        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";

        location / {
                include /etc/nginx/proxy_params;
                proxy_pass http://127.0.0.1:6081;
        }

        client_max_body_size 0;

		# Certbot auto-configuration
        ssl_certificate /etc/letsencrypt/live/my.domain.de/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/my.domain.de/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

}

Varnish Server einrichten

/etc/varnish/default.vcl

vcl 4.0;
# set default backend if no server cluster specified
backend default {
    .host = "192.168.2.5";
    .port = "80";
}

# access control list for "purge": open to only localhost and other local nodes
acl purge {
    "127.0.0.1";
    "192.168.2.5";
}

# vcl_recv is called whenever a request is received
sub vcl_recv {
        # Serve objects up to 2 minutes past their expiry if the backend
        # is slow to respond.
        # set req.grace = 120s;

        set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;

        set req.backend_hint= default;

        # This uses the ACL action called "purge". Basically if a request to
        # PURGE the cache comes from anywhere other than localhost, ignore it.
        if (req.method == "PURGE") {
            if (!client.ip ~ purge) {
                return (synth(405, "Not allowed."));
            } else {
                return (purge);
            }
        }

        # Pass requests from logged-in users directly.
        # Only detect cookies with "session" and "Token" in file name, otherwise nothing get cached.
        if (req.http.Authorization || req.http.Cookie ~ "session" || req.http.Cookie ~ "Token") {
            return (pass);
        } /* Not cacheable by default */

        # normalize Accept-Encoding to reduce vary
        if (req.http.Accept-Encoding) {
          if (req.http.User-Agent ~ "MSIE 6") {
            unset req.http.Accept-Encoding;
          } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
          } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
          } else {
            unset req.http.Accept-Encoding;
          }
        }

        return (hash);
}

sub vcl_pipe {
        # Note that only the first request to the backend will have
        # X-Forwarded-For set.  If you use X-Forwarded-For and want to
        # have it set for all requests, make sure to have:
        # set req.http.connection = "close";

        # This is otherwise not necessary if you do not do any request rewriting.

        set req.http.connection = "close";
}

# Called if the cache has a copy of the page.
sub vcl_hit {
        if (!obj.ttl > 0s) {
            return (pass);
        }

        # Force lookup if the request is a no-cache request from the client.
        if (req.http.Cache-Control ~ "no-cache") {
            return (miss);
        }
}

# Called after a document has been successfully retrieved from the backend.
sub vcl_backend_response {
        # Don't cache 50x responses
        if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
            set beresp.uncacheable = true;
            return (deliver);
        }

       if (beresp.ttl < 48h) {
          set beresp.ttl = 48h;
        }

        if (!beresp.ttl > 0s) {
          set beresp.uncacheable = true;
          return (deliver);
        }

        if (beresp.http.Set-Cookie) {
          set beresp.uncacheable = true;
          return (deliver);
        }

#       if (beresp.http.Cache-Control ~ "(private|no-cache|no-store)") {
#          set beresp.uncacheable = true;
#          return (deliver);
#        }

        if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") {
          set beresp.uncacheable = true;
          return (deliver);
        }

        return (deliver);
}

Erweiterung 'Visual Editor'

Hinter einem Proxyserver, speziell einem mit SSL, muss für den Visual Editor die Konfiguration in der LocalSettings.php angepasst werden.

# Set internal Server address
$wgInternalServer = "http://192.168.2.6";

# Special config for Visual Editor behind https Proxy
wfLoadExtension( 'Parsoid', "$IP/vendor/wikimedia/parsoid/extension.json" );
$wgVirtualRestConfig['modules']['parsoid'] = array(
    // URL to the Parsoid instance.
    // You should change $wgServer to match the non-local host running Parsoid
    'url' => $wgInternalServer . $wgScriptPath . '/rest.php',
    // Parsoid "domain", see below (optional, rarely needed)
    // 'domain' => 'localhost',
);

Siehe auch

NGINX installieren (AlmaLinux/CentOS)

NGINX installieren (Raspberry Pi)

Reverse Proxy mit NGINX

Quellen

https://www.mediawiki.org/wiki/Manual:$wgCdnServers

Einzelnachweise