Join the community today
Register Now

Wordpress Wordpress Multisite + Redis + wp-rocket + Cloudflare on Subdomains

Discussion in 'Blogs & CMS usage' started by EckyBrazzz, Aug 22, 2019.

  1. EckyBrazzz

    EckyBrazzz Active Member

    884
    186
    43
    Mar 28, 2018
    >>>>Click here<<<< i'm nearby......
    Ratings:
    +342
    Local Time:
    5:26 AM
    Latest
    Latest
    Hi there all,

    This should become a tutorial for setting up a WordPress Multi site. This is not a thing that comes by default in Centmin mod and it needs a little setup and adjustments in the settings.

    There is an old post on the forum, pinned about that install, but it's a little outdated (2016)

    You need to install Redis on a good way, install just one main domain.ssl.conf and follow some exact steps to complete the setup. The main domain can't have www, and for now, adding subdomains works out of the box after adding an A record at your DNS (Cloudflare as we use it here)

    For now, it seems to work, but before I gone write down exactly the steps how to archive it I need some time to test it and fine tune it. Have some little issues.

    I came to the conclusion that a Multi site environment for me has to many benefits as I have many sites in different languages, but here is a little preview.

    Project_CMM_7290.png

    On a network setup you can select what you want to have by default inside your network, one super user and on each domain an administrator and the normal other users. With the plugin Controlled Admin Access you can create a kind of administrator with limited rights . There is so much to configure, and the options that it has I did not see before.
    Project_CMM_7291.png

    Project_CMM_7292.png
    Currently, my setup is with the Nginx Helper plug that creates a map, normally the nginx helper plug does not show as many options, but with multi-site it does some extra.
    Project_CMM_7293.png

    The same for WebPExpress plugin, that is for the entire network to generate your WebP format images on the fly. The Wp-Rocket can't be set up in a Network, gives a fatal error, but you can use it on each subdomain.

    Code (Text):
    1293:M 21 Aug 2019 07:45:19.803 * Calling fsync() on the AOF file.
    1293:M 21 Aug 2019 07:45:19.805 * Removing the pid file.
    1293:M 21 Aug 2019 07:45:19.805 # Redis is now ready to exit, bye bye...
    1303:C 21 Aug 2019 07:45:49.627 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    1303:C 21 Aug 2019 07:45:49.629 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=1303, just started
    1303:C 21 Aug 2019 07:45:49.630 # Configuration loaded
    1303:C 21 Aug 2019 07:45:49.630 * supervised by systemd, will signal readiness
                    _._                                                
               _.-``__ ''-._                                            
          _.-``    `.  `_.  ''-._           Redis 5.0.5 (00000000/0) 64 bit
      .-`` .-```.  ```\/    _.,_ ''-._                                  
     (    '      ,       .-`  | `,    )     Running in standalone mode
     |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
     |    `-._   `._    /     _.-'    |     PID: 1303
      `-._    `-._  `-./  _.-'    _.-'                                  
     |`-._`-._    `-.__.-'    _.-'_.-'|                                
     |    `-._`-._        _.-'_.-'    |           http://redis.io      
      `-._    `-._`-.__.-'_.-'    _.-'                                  
     |`-._`-._    `-.__.-'    _.-'_.-'|                                
     |    `-._`-._        _.-'_.-'    |                                
      `-._    `-._`-.__.-'_.-'    _.-'                                  
          `-._    `-.__.-'    _.-'                                      
              `-._        _.-'                                          
                  `-.__.-'                                              
    
    1303:M 21 Aug 2019 07:45:49.636 # Server initialized
    1303:M 21 Aug 2019 07:45:49.636 * Ready to accept connections
    


    PLEASE DON'T POST COMMENTS BELOW IF IT IS NOT RELATED TO THIS ISSUE OR IF YOU ALREADY HAVE QUESTIONS ON HOW TO SET IT UP AS I DON'T SUPPORT IT "YET".

    I WILL SUPPORT IT AFTERWARDS!
     
  2. EckyBrazzz

    EckyBrazzz Active Member

    884
    186
    43
    Mar 28, 2018
    >>>>Click here<<<< i'm nearby......
    Ratings:
    +342
    Local Time:
    5:26 AM
    Latest
    Latest
    Little preview info.

    To create this we need Cloudflare for the SSL.
    The first domain can't include www (in fact www is a subdomain)

    Create a normal installation with option 22-2 (Redis) and with SSL

    Plugin nginx Helper is installed by default with Redis, we need this as it has extra options when using Multi sites.

    Be careful with WebP Express. The way they get stored in the media gelaria is different. This also is for normal media.

    Enable Multi site by editing wp-config.php
    Code (Text):
    define('MULTISITE', true);
    define('SUBDOMAIN_INSTALL', true);
    define('DOMAIN_CURRENT_SITE', 'domain.com');
    define('PATH_CURRENT_SITE', '/');
    define('SITE_ID_CURRENT_SITE', 1);
    define('BLOG_ID_CURRENT_SITE', 1);
    /* That's all, stop editing! Happy publishing. */
    

    Edit created domain.ssl.conf
    Code (Text):
    #x# HTTPS-DEFAULT
    # server {
    #
    #   server_name xoommit.com www.xoommit.com;
    #   return 302 https://xoommit.com$request_uri;
    #   include /usr/local/nginx/conf/staticfiles.conf;
    # }
    map $uri $blogname{
    ~^(?<blogpath>/[^/]+/)sites/(.*)    $blogpath ;
    }
    map $blogname $blogid{
        default -999;
            include /home/nginx/domains/domain.com/public/wp-content/uploads/nginx-helper/map.conf;
    }
    server {
      listen 443 ssl http2 reuseport;
      server_name domain.com sub1.domain.com sub2.domain.com sub3.domain.com <SNIPPED>;
    

    Part for Redis
    Code (Text):
    # Block nginx-help log from public viewing
    location ~* /wp-content/uploads/nginx-helper/ { deny all; }
    
        set $skip_cache 0;
    
       # exclude mobile devices from redis caching
       if ($redis_device = mobile) {
         set $skip_cache 1;
       }
    
        # POST requests and urls with a query string should always go to PHP
        if ($request_method = POST) {
            set $skip_cache 1;
        }
        if ($query_string != "") {
            set $skip_cache 1;
        }
    # Don't cache uris containing the following segments
    if ($request_uri ~* "\?add-to-cart=|/cart/|/my-account/|/checkout/|/shop/checkout/|/store/checkout/|/customer-dashboard/|/addons/|/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|-->more if needed
      set $skip_cache 1;
    }
    
    # Don't use the cache for logged in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|edd_items_in_cart|woocommerce_items_in_cart") {
      set $skip_cache 1;
    }
    
        # Rewrite multisite '.../wp-.' and '.../.php'.
        if (!-e $request_filename) {
            rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
            rewrite ^/[_0-9a-zA-Z-]+.(/wp-admin/.\.php)$ $1 last;
            rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
        }
    


    Define what should be in your network (enabled or not)
    Every time you want to add a new subdomain you have to
    • edit server name --> add sub4.domain.com as example
    • create a A record that point to your IP
    • most common use is for internationl pages other languages, so create child themes and enable them for the network. You have to create a php function to rename the category,
    • Add new subdomain in the WP Admin panel.
    • DONE, configure it now
    Importing old existing domains.
    • Use import /export function of WordPress. Step by step don't try to do them all together
    • default limit is 1MB, try to set higher value if needed
    • test each step of the import, something might be broken due plugins
    • Images are a no go.
    Wp-Rocket --> Great works
    Code (Text):
    curl -I https://sub1.domain.com
    HTTP/1.1 200 OK
    Date: Tue, 27 Aug 2019 14:11:29 GMT
    Content-Type: text/html; charset=utf-8
    Connection: keep-alive
    Set-Cookie: __cfduid=da23d5cfba42f53aa46bc2927c94a15481566915089; expires=Wed, 26-Aug-20 14:11:29 GMT; path=/; domain=.domain.com; HttpOnly; Secure
    Last-Modified: Tue, 27 Aug 2019 06:26:16 GMT
    Vary: Accept-Encoding
    X-Powered-By: centminmod
    Vary: Accept-Encoding, Cookie
    Cache-Control: no-cache, no-store, must-revalidate
    X-Rocket-Nginx-Serving-Static: Yes
    X-Rocket-Nginx-Reason: /wp-content/cache/wp-rocket/sub1.domain.com///index-https.html_gzip
    X-Rocket-Nginx-File: /home/nginx/domains/domain.com/public/wp-content/cache/wp-rocket/sub1.domain.com///index-https.html_gzip
    Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
    X-Frame-Options: SAMEORIGIN
    X-XSS-Protection: 1; mode=block
    X-Content-Type-Options: nosniff
    X-UA-Compatible: ie=edge
    X-Frame-Options: SAMEORIGIN
    X-XSS-Protection: 1; mode=block
    X-UA-Compatible: ie=edge
    Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
    Server: cloudflare
    CF-RAY: 50cea28a9f62bf46-XXX
    

    Don't start this now, as far for now it works, but needs improvements. Created subdomains get A+ at openssllabs.com thanks to Cloudflare. I did not post all configurations, Redis for example needs to be setup correctly.

    PLEASE DON'T POST COMMENTS BELOW IF IT IS NOT RELATED TO THIS ISSUE OR IF YOU ALREADY HAVE QUESTIONS ON HOW TO SET IT UP AS I DON'T SUPPORT IT "YET".
    POST CORRECTIONS/SUGGESTION -> FINE WILL HELP A LOT

    I WILL SUPPORT IT AFTERWARDS!
     
  3. EckyBrazzz

    EckyBrazzz Active Member

    884
    186
    43
    Mar 28, 2018
    >>>>Click here<<<< i'm nearby......
    Ratings:
    +342
    Local Time:
    5:26 AM
    Latest
    Latest
    Not bad thanks to CMM and Cloudflare. Every subdomain A+. Only need to upgrade Cloudflare for SNI support, but as it is in test I'll wait for a while. Project_CMM_7294.png
     
  4. rdan

    rdan Well-Known Member

    5,018
    1,219
    113
    May 25, 2014
    Ratings:
    +1,847
    Local Time:
    4:26 PM
    Mainline
    10.2
    If you wish to make use of a custom SSL certificate that supports browsers without SNI support, you would need to upgrade to a Business plan and enable Legacy Client support when uploading the SSL certificate. Business plans support one custom SSL certificate per zone.
     
  5. EckyBrazzz

    EckyBrazzz Active Member

    884
    186
    43
    Mar 28, 2018
    >>>>Click here<<<< i'm nearby......
    Ratings:
    +342
    Local Time:
    5:26 AM
    Latest
    Latest
    @rdan That's why I wrote "I'll wait for a while."
     
  6. KlueMaster

    KlueMaster Member

    57
    10
    8
    Aug 5, 2017
    Ratings:
    +21
    Local Time:
    1:56 PM
    MariaDB 10
    I've tried these steps and it leads to HTTP 500 when trying to open the site. There is no entry in error logs anywhere.

    After reverting the changes, single site installation works, but CSS is now broken.


    After a couple of more attempts, multi-site worked! Though the CSS is still broken, but I can manage through theme change.
     
    Last edited: Jun 1, 2020
  7. EckyBrazzz

    EckyBrazzz Active Member

    884
    186
    43
    Mar 28, 2018
    >>>>Click here<<<< i'm nearby......
    Ratings:
    +342
    Local Time:
    5:26 AM
    Latest
    Latest
    Hi @KlueMaster

    I assume you have this in your wp-config.php

    Code (Text):
    define('MULTISITE', true);
    define('SUBDOMAIN_INSTALL', true);
    define('DOMAIN_CURRENT_SITE', 'domain.com');
    define('PATH_CURRENT_SITE', '/');
    define('SITE_ID_CURRENT_SITE', 1);
    define('BLOG_ID_CURRENT_SITE', 1);
    define('FORCE_SSL_ADMIN', true);
    /* That's all, stop editing! Happy publishing. */
    


    And this is a bit generic, you can use with most settings. (1-4)


    Code (Text):
    #x# HTTPS-DEFAULT
    map $uri $blogname{ ~^(?<blogpath>/[^/]+/)sites/(.*) $blogpath ;
    }
    map $blogname $blogid{
        default -999;
            include /home/nginx/domains/domain.com/public/wp-content/uploads/nginx-helper/map.conf;
    }
    server {
      listen 443 ssl http2;
      server_name domain.com www.domain.com ae.domain.com ar.domain.com be-nl.domain.com br.domain.com cw.domain.com de.domain.com dk.domain.com
    fi.domain.com uk.domain.com nz.domain.com us.domain.com nl.domain.com pt.domain.com mx.domain.com ch-de.domain.com ie.domain.com in.domain.com
    hr.domain.com sg.domain.com ky.domain.com za.domain.com au.domain.com es.domain.com pe.domain.com ca-en.domain.com ca-fr.domain at.domain.com
    fr.domain.com it.domain.com pl.domain.com pr.domain.com ru.domain.com se.domain.com sr.domain.com;
      include /usr/local/nginx/conf/ssl/domain.com/domain.com.crt.key.conf;
      include /usr/local/nginx/conf/ssl_include.conf;
      # cloudflare authenticated origin pull cert community.centminmod.com/threads/13847/
      ssl_client_certificate /usr/local/nginx/conf/ssl/cloudflare/domain.com/origin.crt;
      ssl_verify_client on;
      http2_max_field_size 16k;
      http2_max_header_size 32k;
      http2_max_requests 5000;
      # mozilla recommended
      ssl_ciphers
    ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
      ssl_prefer_server_ciphers on;
      #add_header Alternate-Protocol 443:npn-spdy/3;
      # before enabling HSTS line below read centminmod.com/nginx_domain_dns_setup.html#hsts add_header Strict-Transport-Security "max-age=31536000;
      #includeSubdomains;"; add_header X-Frame-Options SAMEORIGIN;
    
      # Nginx Bad Bot Blocker Includes
      include /usr/local/nginx/conf/ultimate-badbot-blocker/bots.d/ddos.conf;
      include /usr/local/nginx/conf/ultimate-badbot-blocker/bots.d/blockbots.conf;
    
      add_header X-Xss-Protection "1; mode=block" always;
      add_header X-Content-Type-Options "nosniff" always;
      #add_header Referrer-Policy "strict-origin-when-cross-origin"; spdy_headers_comp 5;
      ssl_buffer_size 1369;
      ssl_session_tickets on;
    
      # enable ocsp stapling
      resolver 8.8.8.8 8.8.4.4 1.1.1.1 1.0.0.1 valid=10m;
      resolver_timeout 10s;
      ssl_stapling on;
      ssl_stapling_verify on;
    
    # webp extension support if you are converting /uploads images to webp
      location ~ ^/wp-content/uploads/ {
      location ~* ^/wp-content/uploads/(.+/)?(.+)\.(|png|jpe?g)$ {
        expires 30d;
         add_header Vary "Accept-Encoding";
         add_header Cache-Control "public, no-transform, includeSubDomains; preload";
         try_files $uri$webp_extension $uri =404;
        }
      }
    
      # limit_conn limit_per_ip 16; ssi on;
      access_log /var/log/nginx/access.log combined buffer=256k flush=5m;
      error_log /var/log/nginx/error.log;
    #  access_log /home/nginx/domains/domain.com/log/access.log combined buffer=256k flush=5m; error_log /home/nginx/domains/domain.com/log/error.log;
      include /usr/local/nginx/conf/autoprotect/domain.com/autoprotect-domain.com.conf;
      root /home/nginx/domains/domain.com/public;
      # uncomment cloudflare.conf include if using cloudflare for server and/or vhost site
      include /usr/local/nginx/conf/cloudflare.conf;
      include /usr/local/nginx/conf/503include-main.conf;
      include /usr/local/nginx/conf/wpincludes/domain.com/wpfastcgicache_include_domain.com.conf;
    
      #WP ROCKET
      include /usr/local/nginx/conf/wpincludes/domain.com/rocket-nginx/default.conf;
    
       location / {
      include /usr/local/nginx/conf/503include-only.conf;
    
      if (-f $request_filename/index.html){
                    rewrite (.*) $1/index.html break;
        }
    
        if (-f $request_filename/index.php){
                    rewrite (.*) $1/index.php;
        }
        if (!-f $request_filename){
                    rewrite (.*) /index.php;
        }
      # Enables directory listings when index file not found autoindex on; Wordpress fastcgi_cache
        try_files $uri $uri/ /index.php?$args;
      }
    location ~* /(wp-login\.php) {
        limit_req zone=xwplogin burst=1 nodelay;
        #limit_conn xwpconlimit 30;
        auth_basic "Private";
        auth_basic_user_file /home/nginx/domains/domain.com/htpasswd_wplogin;
        include /usr/local/nginx/conf/wpincludes/domain.com/php-fastcgicache.conf;
    
        # https://community.centminmod.com/posts/18828/ include /usr/local/nginx/conf/php-rediscache.conf;
    }
    location ~* /(xmlrpc\.php) {
        limit_req zone=xwprpc burst=45 nodelay;
        #limit_conn xwpconlimit 30;
        include /usr/local/nginx/conf/wpincludes/domain.com/php-fastcgicache.conf;
    
        # https://community.centminmod.com/posts/18828/ include /usr/local/nginx/conf/php-rediscache.conf;
    }
    location ~* /wp-admin/(load-scripts\.php) {
        limit_req zone=xwprpc burst=5 nodelay;
        #limit_conn xwpconlimit 30;
        include /usr/local/nginx/conf/wpincludes/domain.com/php-fastcgicache.conf;
    
        # https://community.centminmod.com/posts/18828/ include /usr/local/nginx/conf/php-rediscache.conf;
    }
    location ~* /wp-admin/(load-styles\.php) {
        limit_req zone=xwprpc burst=5 nodelay;
        #limit_conn xwpconlimit 30;
        include /usr/local/nginx/conf/wpincludes/domain.com/php-fastcgicache.conf;
    
        # https://community.centminmod.com/posts/18828/ include /usr/local/nginx/conf/php-rediscache.conf;
    }
    # Pass uploaded files to wp-includes/ms-files.php.
        rewrite /files/$ /index.php last;
        if ($uri !~ wp-content/plugins) {
            rewrite /files/(.+)$ /wp-includes/ms-files.php?file=$1 last;
        }
        # Rewrite multisite '.../wp-.' and '.../.php'.
        if (!-e $request_filename) {
            rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
            rewrite ^/[_0-9a-zA-Z-]+.(/wp-admin/.\.php)$ $1 last;
            rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
        }
      include /usr/local/nginx/conf/wpincludes/domain.com/wpsecure_domain.com.conf;
      include /usr/local/nginx/conf/wpincludes/domain.com/php-fastcgicache.conf;
    
      # https://community.centminmod.com/posts/18828/ include /usr/local/nginx/conf/php-rediscache.conf;
      include /usr/local/nginx/conf/pre-staticfiles-local-domain.com.conf;
      include /usr/local/nginx/conf/pre-staticfiles-global.conf;
      include /usr/local/nginx/conf/staticfiles.conf;
      include /usr/local/nginx/conf/drop.conf;
      #include /usr/local/nginx/conf/errorpage.conf;
      include /usr/local/nginx/conf/vts_server.conf;
    


    I currently don't use it anymore with Redis, but with php-fpm. Hope it helps to solve your problem.
     
  8. Jay Chen

    Jay Chen Active Member

    134
    37
    28
    Sep 10, 2017
    Ratings:
    +72
    Local Time:
    3:26 AM
    Hi @EckyBrazzz

    I see that you are using redis object cache alongside with static cache, wp rocket.
    What is your experience with having object and static cache running at the same time on wordpress?

    Right now I only have static cache, Cache Enabler, curious to see what is the benefit to add object cache on top of this.
     
  9. EckyBrazzz

    EckyBrazzz Active Member

    884
    186
    43
    Mar 28, 2018
    >>>>Click here<<<< i'm nearby......
    Ratings:
    +342
    Local Time:
    5:26 AM
    Latest
    Latest
  10. Jay Chen

    Jay Chen Active Member

    134
    37
    28
    Sep 10, 2017
    Ratings:
    +72
    Local Time:
    3:26 AM
    I see now, you using it with php-fpm, thanks for the info.
     
  11. KlueMaster

    KlueMaster Member

    57
    10
    8
    Aug 5, 2017
    Ratings:
    +21
    Local Time:
    1:56 PM
    MariaDB 10
    It is now working fine, except for some reason homepage throws 404.

    I think it may be a redis issue. I will try to find out ways to remove redis and use cache enabler instead.
     
  12. KlueMaster

    KlueMaster Member

    57
    10
    8
    Aug 5, 2017
    Ratings:
    +21
    Local Time:
    1:56 PM
    MariaDB 10
    Is this working for you? Even after using this as it is (only changing domain.com part) I'm not able to get rid of 404 on main site's homepage. Everything else is working fine though.