emcniece / docker-wordpress

Extended WordPress Docker image with Nginx Helper and Redis Object Cache support
40 stars 20 forks source link

woocommerce glitches when using using suggested docker-compose.yml file #3

Open dc232 opened 6 years ago

dc232 commented 6 years ago

Hi, I have installed your stack using your docker-compose.yml suggested setup as is I notice that when I install woocommerce and add products despite having a clean database there is a seldom replication of the data. In other words, if I go to the shop page and add a product to the basket in chrome and then try adding another product as another different customer in internet explorer, for example, I can see the product in both baskets however upon deleting the folders within the /tmp folder in the docker host machine an then rebooting it this issue seems to have stopped?.

Another possible glitch that i have seen is that when I created the create the stack and then add a product I can view the basket page correctly and add and remove items as needed but when another person in a different location tries to view the basket after adding the item they cannot the items in the basket and it says the basket is empty even though there is an item in the basket? example http://ip172-18-0-55-b9ninpqr91k000boh5n0-8080.direct.labs.play-with-docker.com/basket/ link expires in about 1 hour and 40 minutes

I'm not sure what can be done to fix the problems, any advice would be most helpful

emcniece commented 6 years ago

Very interesting... thanks for the report. The link expired by the time I saw this, but I tried replicating the behaviour on my local machine and I could not get the same results until I enabled permalinks. I am testing this against 4 browsers/windows:

Please confirm: Carts work properly when permalinks are disabled, right? For example, URLs should have GET parameters, like http://localhost:8080/?p=123.

This has to do with the Nginx PHP-FPM caching not being exempted from WooCommerce links. The carts should work when permalinks are disabled because of this block:

  if ($query_string != "") {
    set $skip_cache 1;
  }

That means if the URL has a ?param=whatever on it, caching is disabled. When we enable permalinks and get URLs like http://localhost:8080/cart/ the caching takes over and users are presented with a cached page... which happens to have the most recent cart session.

We can add cache exemption rules for various WooCommerce pages, and I will do that shortly:

if ($request_uri ~* "/(cart|checkout|my-account)/*$") {
    set $skip_cache 1;
}

This will disable caching on /cart, /checkout and /my-account pages.

There is a bigger problem however: any non-WooCommerce page that has a cart widget is going to be cached (ie. shared between users) if the cart is generated in PHP during page load. If your particular theme makes an AJAX request to get the cart contents, the caching shouldn't be a problem because AJAX requests are cache-exempt. But if the theme "builds" the cart data in PHP on page load (like the default WooCommerce Storefront theme) then this data is cached and shared.

I am not sure how to handle the page-load-generated-cart situation yet - there are many scenarios in which different themes/plugins/users could cause this caching problem. People using this stack will need to be aware of this issue and work around it... perhaps by not having a dynamic cart widget anywhere and hard-linking to the /cart page.

In summary: Please test the no-permalinks scenario, and I'll push a fix for the WooCommerce page cache exemption in a few minutes.

dc232 commented 6 years ago

Current Observations and method used for test Downloaded new Docker container stack, via http://ip172-18-0-5-b9nn3u2r91k000bohg5g-8080.direct.labs.play-with-docker.com Looks like mailgun and akismet need updating (irrelevant for test though) Not sure to update to WordPress 4.9.2 will leave for the time being Plugins  install  Woocommerce In original test when issue was detected storefront theme was used (thanks for letting me know about the caching issue associated with it)

Proceeded to create 2 dummy products Original permalink i.e by default Permalink: http://ip172-18-0-5-b9nn3u2r91k000bohg5g-8080.direct.labs.play-with-docker.com/product/test/ ‎ Permalink: http://ip172-18-0-5-b9nn3u2r91k000bohg5g-8080.direct.labs.play-with-docker.com/product/test2/

Default permalink setting

Day and name http://ip172-18-0-5-b9nn3u2r91k000bohg5g-8080.direct.labs.play-with-docker.com/2018/01/29/sample-post/

Permalinks confirmation Please confirm: Carts work properly when permalinks are disabled, right? For example, URLs should have GET parameters, like http://localhost:8080/?p=123. Set to permalinks to plain to check Plain http://ip172-18-0-5-b9nn3u2r91k000bohg5g-8080.direct.labs.play-with-docker.com/?p=123 However, would a custom base be needed for a product permalink or is standard fine?

Seems to work fine on phone with Google chrome Edge – works fine Google Incognito mode – works fine Edge incognito – works fine

Current plugins enabled during analysis Jetpack by WordPress.com WooCommerce

Will do some further test perhaps with Nginx Helper plugin enabled and see what happens and then maybe progress to Redis Object Cache if that helps

emcniece commented 6 years ago

Yep, that recent test looks good with permalinks disabled (eg. http://ip172-18-0-5-b9nn3u2r91k000bohg5g-8080.direct.labs.play-with-docker.com/?page_id=5). Confirmed that the Nginx cache config is the problem.

The Nginx Helper plugin exists as an aid to auto-clear the cache when content is updated. It runs when a user edits (and publishes) a post or page or when comments are made. It is the equivalent of visiting /purge/ in the browser, which is a manual trigger for clearing the PHP-FPM cache.

You can perform this cache bust yourself: http://ip172-18-0-5-b9nn3u2r91k000bohg5g-8080.direct.labs.play-with-docker.com/purge/ - if there is a cache you will get a cache clear success message, otherwise it will return a 404.

You may have noticed that after initial WP installation, logged out users keep getting redirected to the WP install page - this is because PHP-FPM has cached the install/login pages, including their redirects. Visiting the /purge/ URL will get rid of this caching and allow users to visit the home page as usual.

emcniece commented 6 years ago

Ok, the fix is published and ready. Please update your docker-compose.yml file to the following:

The first 2 services should look like this:

version: '3.1'

services:

  nginx:
    image: emcniece/nginx-cache-purge-wp:0.0.2
    ports:
      - 8080:80
    links:
      - wp-fpm
    volumes:
      - wproot:/var/www/html

  wp-fpm:
    tty: true
    stdin_open: true
    image: emcniece/wordpress:0.0.2
    volumes:
      - wproot:/var/www/html
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WPFPM_WP_REDIS_HOST: redis
      WPFPM_RT_WP_NGINX_HELPER_CACHE_PATH: "/tmp/cache"
      WP_PLUGINS: "nginx-helper redis-cache"

# ... myql, redis, etc

After doing so, setting up this stack including enabling permalinks should not cache the WooCommerce pages any more.

Side note: I noticed that it is not caching the cart widget on the home page either!

dc232 commented 6 years ago

Awesome I'll give the setup a try and post my observations

dc232 commented 6 years ago

image: emcniece/wordpress:0.0.2 Hi during test I'm getting Pulling wp-fpm (emcniece/wordpress:0.0.2)... ERROR: manifest for emcniece/wordpress:0.0.2 not found?, Have the changes been merged into emcniece/wordpress:4-php7.1-fpm-alpine?

emcniece commented 6 years ago

Oh, I'm so sorry - I missed the docker push emcniece/wordpress:0.0.2 step! Apologies...

0.0.2 is released now, try again.

dc232 commented 6 years ago

Ok very interesting so it seems that the shared basket caching issue seems to be resolved for the most part and the new stack works well set to plain permalink even when using a plugin such as Shortcode Pagination for WooCommerce.

However when changing the permalink to post name I did notice that the basket contents doesn't show, this is with the nginx helper and reddis cache plugin inactive, I recall that there is caching with this permalink. However even doing the /purge/ seems to yield the same result even though the purge is successful.

Is there a way around this?, the structure of the permalink is /%postname%/

emcniece commented 6 years ago

What theme are you using? I thought I saw the cart contents in the Storefront theme update, I'll double-check this tomorrow.

dc232 commented 6 years ago

The theme being used is storefront theme you will the cart contents when permlinks are set to plain try setting the permalinks to postname and see if you get the same result, I'll try again to see if I get the same result

dc232 commented 6 years ago

Hmm ok it seems like content created by plugins such as shortcode Pagination for WooCommerce does not get cached if permalinks are set to plain and nor does the content in the basket, the basket does seem to get cached when permalinks are set to /%postname%/ even when using the /purge/ and the plugin Redis Object Cache and Nginx Helper inactive, best example I can give you https://www.vinsonjewellers.co.uk/basket/