61 Comments

  1. Luigi
    June 12, 2017 @ 9:06 pm

    Thank you very much for this guide. What i wish to see if possible is another layer of how to control and maintain this installation in order to avoid having a broken website/server.
    That would be really fabulous if you could explain.

    Thanks,
    Luigi

    Reply

  2. andrew
    June 13, 2017 @ 12:02 pm

    What is better for a large woocommerce affiliate store – MariaDB or PerconaDB?

    Reply

    • David H.
      June 13, 2017 @ 12:08 pm

      Both are far better than plain MySQL, but PerconaDB is better because it comes with better performance analysis tools.

      Reply

  3. Danny
    July 13, 2017 @ 10:22 pm

    Hi Dave,
    Very interesting article, but there’s little info about the setup. For the average webmaster it will be hard to control and debug… and the paid services are out of reach for many. I’m curious why you use Varnish when in the serverpilot guide you use cloudflare to replace it . I’m setting up a daily deals site, and some posts need to be changed or deleted every day, so I’m curious how long pages are pages cached, or how to configure it. Or maybe I can decide not to use it and just skip the varnish setup? And what about redis? Perhaps the serverpilot setup is more suitable for those less familiar with configuring a server?

    Reply

    • David H.
      July 14, 2017 @ 2:33 pm

      Varnish only caches pages for a VERY short amount of time – circa 5 minutes typically. It’s used to handle RUSH traffic.

      For page-caching, using something like W3 Total Cache you can control how long the page cache exists, and you can also provide an XML sitemap to prime the cache.

      For sure, the Server Pilot set up is probably simpler – especially because Varnish cache can be technical to configure if there are any plugins that need configured that aren’t included in my scripts.

      Redis is awesome for object caching – even with page caching in W3 Total Cache I will typically use disk-based caching because this allows W3 Total Cache to pump these pages out without loading all of WordPress core (if you use Redis for page caching, it has to load all of WordPress core).

      Reply

      • Danny
        July 17, 2017 @ 2:40 pm

        The drawback of serverpilot is that when you install other applications on the server then serverpilot could screw them up. So I will probably go far this rocketstack. My only concern is the caching, having read about Simple Ajax Chat in the cache busting list: what happens if a logged in admin views a front-end page. Will the admin bar at the top, any admin edit buttons on the page, etc. get cached, so the next visitor will see that, or how does that work? As that’s no admin url, there’s no url parameters, and it doesn’t look like the extra content is added via js. Is it possible to just disable / override varnish for the time being? And how does one test plugins and themes for cache busting behavior?

        Reply

        • David H.
          July 18, 2017 @ 9:45 am

          Yes – you can just skip installing varnish. Or follow the full guide and just switch varnish off. It’s clever enough that if Varnish isn’t working, is broken, or is off, then nginx just passes the web requests directly to PHP/WordPress.

          re: Simple Ajax Chat – I highly recommend you use a different plugin.

          re: Admin bar – these don’t get cached because there are varnish rules to avoid caching for logged in users.

          re: testing for cache busting behaviour – typically most plugins don’t even qualify for needing testing – i.e. most plugins apply content to your pages that applies to all users. Plugins that require testing are the ones that create different content per user – e.g. shopping baskets, user wishlists, users recently viewed products, or plugins that do messaging between users (or between users and admin). To test, view a page (logged out) with user-specific content in browser 1 (e.g. add something to your wishlist, or send a message with simple ajax chat or similar), then immediately view the same page in browser 2 (also logged out). If browser 2 sees browser 1’s user-specific content then they have not implemented their code in a page-caching compatible way.

          Reply

  4. Emiel
    August 9, 2017 @ 9:11 am

    Hi Dave,

    Thanks for this awesome post!

    I was wondering if you have any advise on a server management tool to go with this setup, like Vesta, Froxlor or ISPManager. Really curious which server management tool would you advise.

    Thanks for your reply in advance.

    Reply

    • David H.
      August 13, 2017 @ 1:55 pm

      I’ve used Ajenti in the past, but personally I prefer to modify the files directly – much more control and confidence that the server-management tool isn’t ruining performance.

      Also – once you start using a server management tool, (with all the ones I’ve tried) it becomes impossible to alter the config files manually since it needs to have exclusive control.

      But yes – there’s nothing to stop you adding the ones you listed provided you can live with the constraints above.

      Reply

  5. Emiel
    August 9, 2017 @ 2:16 pm

    Would it not be easier to install the “one-click” LEMP on 16.04 droplet image from Digital Ocean and install and configure PerconaDB, Varnish, Redis, fail2ban and Letsencrypt afterwards? Or would that result in a much different setup?
    Besides that, would it also be possible to have multiple WordPress installs under different users on the same droplet using this server stack?
    Thanks for your reply in advance. Looking forward to it!

    Reply

    • David H.
      August 13, 2017 @ 2:50 pm

      Yeah sure – you can do it that way too – of course – there’s many ways to skin this cat – I’ve shown how to do it from scratch.

      re: Multiple wordpress installs, if you’re planning to have different users on the one droplet, you should probably choose a server-management tool too so that you have an interface for your users. Which one you choose will/may limit your stack behind the admin tool however.

      Reply

      • Emiel
        August 14, 2017 @ 3:07 pm

        Thanks for your replies Dave!

        I guess it’s a lot of work to manage users, user quota etc from the command line, right? We don’t want to offer a server management interface to our clients, but were considering installing a server management tool to be able to manage users and their limits easily ourselves 🙂
        Would you (based on the possible performance loss or another reason) advise us to learn managing users and user quota from the command line or would you recommend installing a server management tool?

        Another question: Do you prefer Nginx only instead of Nginx as a reverse proxy for Apache in general?

        Thanks already for your reply, very much appreciated!

        Reply

        • David H.
          August 15, 2017 @ 7:29 pm

          I’ve seen situations where people make nginx + apache work – specifically, the only real reason to do this is if you absolutely need .htaccess rules which apache provides.

          Otherwise, apache is a memory hog and should be avoided.

          Edit: re: managing users, it depends on your server-admin skill levels and the volume of users you’ll be managing. And it depends what you’re aiming for with these users. You can’t give servers reboot capabilities when there are multiple users on the server, amongst of whole bunch of other stuff – I’m in the practice, now that droplets are so cheap, of using 1 droplet per website, so that would be my primary recommendation, but if you’re aiming to have 20 to 100 users on one droplet in order to get economies of scale, then sure it’ll work better perf-wise with this stack, but still, one or more users will run some batch jobs which screw stuff up for others which is where the admin tools can be handy to make it trivial to restrict and control resource usage.

          Depends what you’re doing. Personally, as a user, I’d prefer a whole droplet to myself. I can reboot it, install stuff, add whatever, reconfigure, all without affecting others. And I have confidence that my resources are my own and any perf issues are not because of contention.

          Reply

  6. Frank
    August 21, 2017 @ 11:24 am

    Hi Dave! Great blog post! How can I host all 3 websites of mine on 1 single droplet with this rocketstack setup? All 3 are wordpress websites naturally. Thanks, Frank.

    Reply

    • David H.
      August 28, 2017 @ 10:00 pm

      Hi Frank – the easiest way is to download another copy of wordpress_latest.zip, extract it to another folder in /var/www/ then make copies of the two files in /etc/nginx/sites-available/ (the varnish and the rocketstack ones).

      Enter the domain names in those files and change the server location to point to the new folder.

      I personally don’t like installing multiple websites on one server – servers are so cheap now I don’t see much point – and separation of concerns really helps if you ever have performance issues from one of the websites.

      Reply

  7. Pete
    August 22, 2017 @ 3:39 pm

    Almost flawlessly worked through this tutorial succesfully, except for the fail2ban configuration part:

    Change nginx enabled=true (instead of false) -> I can’t find this value anywhere in the file. Should I just add it there?

    Add the following after the nginx section in the jail.conf -> Can’t find this nginx section here. How can I recognize or find it?

    Reply

    • David H.
      August 28, 2017 @ 10:04 pm

      Did you copy the jail.conf or jail.local file from the cloned repository? It contains the nginx section, as well as specific filters to catch the vast majority of WordPress bots.

      Reply

      • Pete
        September 1, 2017 @ 9:08 am

        Do you mean by running this command: cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local ?

        Also, the wordpress.conf file doesn’t exist in /etc/fail2ban/filter.d/, I had to create it myself.

        I followed your guide precisely, but somehow this last part is not going perfectly for me.

        Thanks for your help!

        Reply

        • Emiel M.
          September 13, 2017 @ 9:53 am

          I also couldn’t find the nginx enabled value, neither did I find the nginx section in jail.conf. Also the wordpress.conf was not there. Am I doing something wrong?

          Reply

          • Emiel M.
            September 13, 2017 @ 10:01 am

            Hi David, could you please remove my last name from the comment above? Apparently when logged in, first and last name are shown as comment name. Thanks!

          • David H.
            September 14, 2017 @ 2:22 pm

            I’ve now changed this site-wide.

          • David H.
            September 14, 2017 @ 5:46 pm

            It should have read ‘create wordpress.conf’ rather than ‘edit wordpress.conf’ and add the lines above.

            Then you can add the [wordpress] section to jail.local or jail.conf. Also, I’ve updated the [nginx] part to reference [nginx-http-auth] which is the filter you need to enable.

      • James
        September 10, 2017 @ 10:56 pm

        same issue. followed to a T but no nginx section in jail.conf and also filter.d was empty

        Reply

        • David H.
          September 14, 2017 @ 5:47 pm

          I’ve updated the post above – create wordpress.conf using the values above in /etc/fail2ban/filter.d/wordpress.conf and I meant to say [nginx-http-auth] rather than just [nginx]

          Reply

  8. Faizan
    September 16, 2017 @ 8:37 am

    Hi. Thanks for the awesome tutorial. I’m yet to try though.
    Is this the same as the product https://www.wpintense.com/product/wpi-fast-wordpress-stack/?
    Also, is the let’s encrypt certificate automatically renewed? Thanks.

    Reply

    • David H.
      September 17, 2017 @ 4:49 pm

      It’s the same config as the Rocket Stack. The LetsEncrypt cert auto renews – there’s a step detailed to create a monthly cron job to run the renewal.

      Reply

      • Faizan
        September 19, 2017 @ 3:52 pm

        You are awesome!!!

        Reply

        • Faizan.
          September 19, 2017 @ 10:00 pm

          I tried installing. Was very fast.
          But while migrating data from my old site which is apache based broke the site. I tried updraft plus and all in one WP migration. Both of them failed. Does this not work with restoring from old site? Or is there another plugin you recommend? Your help would be really appreciated. Thanks.

          Reply

          • David H.
            October 5, 2017 @ 1:15 pm

            Sorry about the delay in replying – had an awful chest infection for 3 weeks. Updraft Plus is normally very reliable, BUT if your site is huge, you might be running out of disk space?

            I’ve regularly encountered issues moving large sites around from server to server which is why I wrote this article that I think you’ll find very handy:

            https://www.wpintense.com/2017/05/18/migrating-huge-wordpress-sites-reliably/

  9. Jay
    October 14, 2017 @ 6:20 pm

    Thanks so much for this Dave.
    Just want to check if there are any changes that need to be addressed if using this for a Multisite?

    Reply

    • David H.
      October 14, 2017 @ 6:36 pm

      No changes required – Multisite is an application-level system, so it’s unaffected by your choice of stack.

      Reply

  10. Todd Richard
    October 26, 2017 @ 7:47 pm

    David,

    At server reboot Percona/MySQL fails to start and seems to point to the mysql.socket not being available. What could be going on?

    Reply

  11. Todd Richard
    October 26, 2017 @ 8:10 pm

    Nevermind, the issue is from the my.cnf file in /etc/mysql not having [mysql] at the top of the file.

    Reply

  12. nickolas ribeiro
    November 5, 2017 @ 7:32 am

    Meu parabéns, muito bom!!!

    Reply

  13. Michael Law
    November 23, 2017 @ 2:25 am

    Thanks very much for this, I have some wee problems but I got around them. Now I am able to prove the theme is slow..

    My question is one of emails? would you host emails for the website separate or add them in the server? Also what do you recommend to get them up and running?

    Reply

    • David H.
      November 23, 2017 @ 12:58 pm

      For emails, don’t host them on your own server. Sending emails is no trivial thing – there’s quite a bit to set up to get it right, and if your server is unknown then some emails will still bounce to some recipients even if you set everything up perfectly.

      To make your life WAAAY easier, use a third-party email service like SparkPost or SendGrid – take a look at both of them and choose which one you prefer. Both are good, both offer free plans, both have WordPress plugins to get everything set up, both have guides to configuring your DNS properly for good email delivery.

      Reply

      • Michael
        November 30, 2017 @ 7:12 pm

        I think I am being dumb. I signed up to SendGrid and intergrated with WordPress but for the life of me have no idea what to do. This looks great but I need to work out how to see emails, I assume I use an email client like gmail.

        Reply

        • David H.
          December 4, 2017 @ 10:49 am

          SendGrid is a great choice to enable your site to send emails out to users. SendGrid is nothing to do with you receiving emails, just the ability to send emails.

          There are 2 techniques to be able to receive emails at your domain – one technique is to set up email forwarding – e.g. from your domain provider, they often have the option to forward emails to another email address. I use this on some of my domains, and I set up emails to forward to my gmail account.

          The 2nd technique is to use a service like that provided by Zoho – they offer a free ‘mailbox’ service which is what I think you’re after – note: your DNS/Domain provider may provide an easier, free mailbox, although frequently they charge for mailboxes. Anyway, with Zoho you can set up a free mailbox and they guide you through the changes you need to make in your DNS settings. Once set up, you can then either use Zoho directly or you can set up your mailbox to forward emails to your gmail account.

          Reply

          • Michael Law
            December 14, 2017 @ 9:48 pm

            Thank you very much! Zoho it is

  14. Narender Chopra
    December 5, 2017 @ 4:27 pm

    Hey David,
    Thanks a lot for this guide. I really want to configure my New WordPress site using your article but I encountered an error while doing the stuff.

    I am getting the following error while creating the mysql database using the commands provided by you:
    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

    Reply

    • David H.
      December 5, 2017 @ 4:42 pm

      Presumably that means you chose a password for your root user when setting up PerconaDB? I leave that blank so that Percona uses authentication based on the fact I’m logged in as root.

      Anyway – where the command says mysql you can append -p, e.g. mysql -p

      This will make mysql ask you for a password. You can right click in the putty window to paste the password if you have it stored in your clipboard.

      Reply

      • Narender Chopra
        December 6, 2017 @ 7:22 am

        Hey David,
        Thanks a ton for quick reply and working solution. I am having two queries:

        1. Currently, I am using DO $10 Plan which comes with 1 CPU so I have run the following command as you explained:
        mkdir /etc/systemd/system/nginx.service.d
        printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf
        systemctl daemon-reload

        So, will there be any need to make changes if I shift to Multi-CPU Plan in future?

        2. For Current $10 DIgital Ocean Plan what should be the best PerconaDB Config?

        Reply

        • David H.
          December 6, 2017 @ 1:40 pm

          1. No – this is to cover a bug that exists for single-cpu servers. No need to change this for multi-cpu servers

          2. Best config really depends how much work is happening in your db versus PHP.

          Probably something like this would work well for you:

          key_buffer = 32M
          max_allowed_packet = 32M
          query_cache_limit = 32M
          query_cache_size = 64M
          innodb_buffer_pool_size = 128M
          innodb_buffer_pool_instances = 1
          innodb_io_capacity = 5000

          Reply

          • Narender
            December 7, 2017 @ 3:49 am

            Thanks a lot for the help David. I am more than happy to finally setting up a WordPress site on Cloud Server with the fastest possible LEMP for WP.

            There is just one concern for now. When I added your suggested configuration to “/etc/mysql/my.cnf” , my site failed to open and shown “MYSQLI_REAL_CONNECT(): (HY000/2002)”

            Then I added these Configs just below [mysql] line in “/mysql/conf.d/mysql.conf” and no error was shown. Is there anything wrong or is it done properly?

          • David H.
            December 13, 2017 @ 12:21 pm

            How you’ve done it is correct. The files changed slightly in the percona installation since the original article. I’ve updated the article to reflect the changes. You can also add these entires to my.cnf so long as you add [mysql] above the config.

          • Narender Chopra
            December 7, 2017 @ 12:44 pm

            I would like to add more issues that I have been facing after setting up WordPress and W3TC as guided in the article.

            Following are the Two errors with my setup:

            1. W3TC Cache isn’t working properly. I added a few codes in Head Section of my Theme and Even in Yoast SEO and they didn’t reflect on my website, no matter how many times I cleared whole cache.

            The Workaround was Deactivating the plugin, restarting the server, activating the plugin again. I had to do this to reflect every single change on the frontend of my site.

            2. I am having a weird issue with Adsense Ads on my site. Sometimes a single Ad Unit Loads out of 3-4 Units and mostly none of the ad unit loads. Tried deactivating the cache plugin and restarting the server but it didn’t work too.

            It would be extremely Thankful if you may have a look at my site examsmate.in to help with these issues. I can also provide any log if you want.

  15. Julien
    December 6, 2017 @ 1:03 am

    David,
    Have you tried wp rocket instead of W3 Total Cache?

    Reply

    • David H.
      December 6, 2017 @ 11:50 am

      Yes I have. To be honest, they’re much of a muchness. WP Rocket defo needs less configuration, and there’s less danger with WP Rocket of breaking your site, but W3 Total Cache gives more options.

      But really page-caching should be handled at the nginx/varnish level. Recently I’ve been using Nginx fastcgi_cache instead of Varnish and it’s working well – it’s easier than Varnish to configure and gives way better performance than either W3 Total Cache or WP Rocket because it’s running before PHP or MySQL even gets involved. I have a video about Nginx fastcgi_cache configuration coming out soon.

      Reply

  16. Narender Chopra
    December 17, 2017 @ 8:01 am

    Hey David,
    Can we use Redis for “Database Cache” option in W3TC for better results? Currently using Memcached for Database cache and Redis for Object cache options.

    Reply

    • David H.
      December 19, 2017 @ 1:40 pm

      You won’t see any difference. Redis and Memcached are very much similar, especially when you’re on a single server. I would personally prefer to use just one caching store to reduce maintenance and updates, but other than that it’s fine.

      Having said that, I’m not really a fan of using BOTH database caching AND object caching. If you’re going to pick one, pick Object Caching. Database Caching is useful if plugins are not coded to allow object caching to be used, but Object Caching is more performant because not only is the DB query cached, but also whatever object structure that is created as a result is also cached.

      Reply

  17. Tom Dings
    December 22, 2017 @ 4:38 am

    Great tutorial, thanks! May I ‘suggest/ask’ 2 little different options ? Maybe your experience is learning me something new or I have to consider a slightly different setup :

    1. How about using Apache2 as dynamic content server and add Nginx as a reverse – caching – server ? even with Varnish, Redis as configured your way ?

    2. I read somewhere it is helping a lot when you are on a dedicated, colocated or virtual server and add / install a proxy like TinyProxy to speed-up the traffic to the server. A few days ago I tried this situation and honestly I am completely surprised about the speed of running WordPress this way. In my situation it is really a big difference. Does this sound logical or is it complete nonsense ?

    Hopefully you do not mind but I am writing this down here but I am providing a few – non-commercial – on social media based services for really large groups of people. I had to learn most configurations with Nginx, Apache2, Varnish, HaProxy, ProxySql, MariaDb Galera Clusters etc by practicing.

    Most of the times all setups are working great but I like to learn a bit and especially know why certain setups are preferred. Just curious!

    Thanks again.

    Reply

    • David H.
      January 5, 2018 @ 12:10 pm

      1) Yes this is an option. It’s not one I like because of how much more RAM Apache uses, but if you need .htaccess compatibility, then yeah you can set up nginx as a caching engine and SSL end point and use Apache to generate pages.
      2) You can set up Nginx as a reverse proxy if you wish instead of TinyProxy. When you say you are getting better speed using TinyProxy, is this when you have Apache at the backend?

      Reply

  18. Tapan Patel
    December 27, 2017 @ 3:46 pm

    how many way for Installing and configuring the WordPress on Ubuntu ?

    Reply

    • David H.
      January 2, 2018 @ 3:19 pm

      Plenty – but this tutorial you’ve commented on is my fastest at this point in time.

      Reply

  19. Gaurav Chopra
    January 5, 2018 @ 6:43 am

    Hey David, Thanks a lot for this guide. I really want to configure my New WordPress site using your article but I encountered an error while doing the stuff.

    I am getting the following error while creating the mysql database using the commands provided by you: ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: NO)

    Reply

    • David H.
      January 5, 2018 @ 11:58 am

      That means that when you set up your PerconaDB you entered a password for your root user. I personally don’t do this and what happens then is that you get ‘inferred’ authentication because root is logged in.

      Anyway, if you append -P to all the commands it will then ask you for the password and you’ll need to enter the password that you created when you set up PerconaDB.

      Reply

  20. Rodrigo Guerra
    January 19, 2018 @ 7:17 pm

    Hi,

    after the installation displays error, (ERR_TOO_MANY_REDIRECTS)

    Works only using IP number.

    How to solve? What are the possible problems?

    The domain is registered in Cloudflare, does it have something related?

    Reply

  21. Rodrigo Guerra
    January 20, 2018 @ 3:12 am

    Hi David,
    You are right. I changed my SSL modein Cloudflate to Full, and it worked. Thanks a lot for the help.
    Note: I’m Brazilian, sorry, my English.

    Reply

    • David H.
      January 20, 2018 @ 7:56 am

      Your English is excellent. I’m glad it’s working for you and thanks for the comment, I’m sure it’ll come in useful for others too.

      Reply

Leave a Reply to Danny Cancel reply

Your email address will not be published. Required fields are marked *