cloudinary / cloudinary_wordpress

Cloudinary's WordPress plugin
GNU General Public License v2.0
38 stars 28 forks source link

Cloudinary plugin not working when deployed in k8s #438

Closed pepoandra closed 3 years ago

pepoandra commented 3 years ago

Hello.

Quick glance at set-up: WordPress 5.7.2 Cloudinary plugin Version 2.7.2 PHP 7.4

When running in a docker container in my laptop, everything works fine. Images are uploaded to cloudinary no problem. Image says "Uploading to new cloud name" and after a few moments, it works.

However, when I deploy the exact same set-up in Kubernetes. then the upload to Cloudinary doesnt work. It is stuck in " Uploading to Cloudinary" until it eventually fails with no error message.

I was comparing the Apache logs from both these instances (The one running locally in my machine versus the logs coming from Kubernetes) & I noticed that there is one POST call that happens in the localdev one that never seems to be logged in the k8s deployment. Namely, this

127.0.0.1 - - [18/May/2021:17:57:56 +0000] "POST /index.php?rest_route=/cloudinary/v1/queue HTTP/1.1" 200 28193 "https://localhost/index.php?rest_route=/cloudinary/v1/queue" "WordPress/5.7.2; https://localhost"

Anybody has any clue what might be happening here?

pereirinha commented 3 years ago

Hey @pepoandra

Thank you for reaching out. I'll be performing some tests on my end, and I'll let you know about my findings.

pereirinha commented 3 years ago

Hi again @pepoandra

I just tested Cloudinary in a k8s environment running on Google Cloud, and I didn't find any issues. You don't see in the logs the requests coming into your REST API infers that those aren't getting into WordPress.

Can you check if you're using any security measures to block access to the REST API? Is your endpoint /wp-json/cloudinary/v1 publicly available — can you please visit https://your-domain.com/wp-json/cloudinary/v1?

pepoandra commented 3 years ago

A bit more context:

This same deployment was working up until last week with Wordpress 4.4, Cloduinary 1.1 & PHP 5.6

So i don't think there's something about Kubernetes that's blocking the calls.

That being said, when I visit the endpoint you suggest, wp-json/cloudinary/v1, i get a 404.

pepoandra commented 3 years ago

Now I can't get it to work locally, for some reason. After it failed locally, I added the image to cloduinary's report.

Im not sure there's any useful information here, but sharing just in case.

{
    "system_status": {
        "home": "https://localhost",
        "wordpress": "5.7.2",
        "php": "7.4.18",
        "php_extensions": [
            "Core",
            "date",
            "libxml",
            "openssl",
            "pcre",
            "sqlite3",
            "zlib",
            "ctype",
            "curl",
            "dom",
            "fileinfo",
            "filter",
            "ftp",
            "hash",
            "iconv",
            "json",
            "mbstring",
            "SPL",
            "PDO",
            "bz2",
            "posix",
            "Reflection",
            "session",
            "SimpleXML",
            "pdo_sqlite",
            "standard",
            "tokenizer",
            "xml",
            "xmlreader",
            "xmlwriter",
            "mysqlnd",
            "apache2handler",
            "bcmath",
            "Phar",
            "calendar",
            "dba",
            "exif",
            "gd",
            "gettext",
            "imagick",
            "imap",
            "intl",
            "mysqli",
            "pdo_mysql",
            "soap",
            "sockets",
            "sodium",
            "tidy",
            "xmlrpc",
            "xsl",
            "zip"
        ]
    },
    "theme_status": {
        "name": "SSENSE Email Campaign Builder",
        "version": "1.3.6",
        "author": "Bureau Principal",
        "author_url": "http://www.bureau-principal.com",
        "child_theme": false
    },
    "plugins_report": {
        "must_use": [],
        "plugins": [
            {
                "Name": "Advanced Custom Fields",
                "PluginURI": "https://www.advancedcustomfields.com",
                "Version": "5.9.5",
                "Description": "Customize WordPress with powerful, professional and intuitive fields. <cite>By <a href=\"https://www.advancedcustomfields.com\">Elliot Condon</a>.</cite>",
                "Author": "<a href=\"https://www.advancedcustomfields.com\">Elliot Condon</a>",
                "AuthorURI": "https://www.advancedcustomfields.com",
                "TextDomain": "acf",
                "DomainPath": "/lang",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "Title": "<a href=\"https://www.advancedcustomfields.com\">Advanced Custom Fields</a>",
                "AuthorName": "Elliot Condon"
            },
            {
                "Name": "Cloudinary",
                "PluginURI": "https://cloudinary.com/documentation/wordpress_integration",
                "Version": "2.7.2",
                "Description": "With the Cloudinary plugin, you can upload and manage your media assets in the cloud, then deliver them to your users through a fast content delivery network, improving your website\u2019s loading speed and overall user experience. Apply multiple transformations and take advantage of a full digital asset management solution without leaving WordPress. <cite>By <a href=\"https://cloudinary.com/\">Cloudinary Ltd., XWP</a>.</cite>",
                "Author": "<a href=\"https://cloudinary.com/\">Cloudinary Ltd., XWP</a>",
                "AuthorURI": "https://cloudinary.com/",
                "TextDomain": "cloudinary",
                "DomainPath": "/languages",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "Title": "<a href=\"https://cloudinary.com/documentation/wordpress_integration\">Cloudinary</a>",
                "AuthorName": "Cloudinary Ltd., XWP"
            },
            {
                "Name": "Post Duplicator",
                "PluginURI": "",
                "Version": "2.22",
                "Description": "Creates functionality to duplicate any and all post types, including taxonomies &amp; custom fields <cite>By <a href=\"http://www.metaphorcreations.com\">Metaphor Creations</a>.</cite>",
                "Author": "<a href=\"http://www.metaphorcreations.com\">Metaphor Creations</a>",
                "AuthorURI": "http://www.metaphorcreations.com",
                "TextDomain": "post-duplicator",
                "DomainPath": "",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "Title": "Post Duplicator",
                "AuthorName": "Metaphor Creations"
            },
            {
                "Name": "Regenerate Thumbnails",
                "PluginURI": "https://alex.blog/wordpress-plugins/regenerate-thumbnails/",
                "Version": "3.1.5",
                "Description": "Regenerate the thumbnails for one or more of your image uploads. Useful when changing their sizes or your theme. <cite>By <a href=\"https://alex.blog/\">Alex Mills (Viper007Bond)</a>.</cite>",
                "Author": "<a href=\"https://alex.blog/\">Alex Mills (Viper007Bond)</a>",
                "AuthorURI": "https://alex.blog/",
                "TextDomain": "regenerate-thumbnails",
                "DomainPath": "",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "Title": "<a href=\"https://alex.blog/wordpress-plugins/regenerate-thumbnails/\">Regenerate Thumbnails</a>",
                "AuthorName": "Alex Mills (Viper007Bond)"
            },
            {
                "Name": "Advanced Editor Tools (previously TinyMCE Advanced)",
                "PluginURI": "https://wordpress.org/plugins/tinymce-advanced/",
                "Version": "5.6.0",
                "Description": "Extends and enhances the block editor (Gutenberg) and the classic editor (TinyMCE). <cite>By <a href=\"https://automattic.com\">Automattic</a>.</cite>",
                "Author": "<a href=\"https://automattic.com\">Automattic</a>",
                "AuthorURI": "https://automattic.com",
                "TextDomain": "tinymce-advanced",
                "DomainPath": "",
                "Network": false,
                "RequiresWP": "5.6",
                "RequiresPHP": "5.6",
                "Title": "<a href=\"https://wordpress.org/plugins/tinymce-advanced/\">Advanced Editor Tools (previously TinyMCE Advanced)</a>",
                "AuthorName": "Automattic"
            }
        ]
    },
    "media_report": {
        "48713": {
            "width": 782,
            "height": 991,
            "file": "2021/05/untitled-43.png",
            "sizes": {
                "medium": {
                    "file": "untitled-43-237x300.png",
                    "width": 237,
                    "height": 300,
                    "mime-type": "image/png"
                },
                "thumbnail": {
                    "file": "untitled-43-150x150.png",
                    "width": 150,
                    "height": 150,
                    "mime-type": "image/png"
                },
                "campaign-large": {
                    "file": "untitled-43-760x963.png",
                    "width": 760,
                    "height": 963,
                    "mime-type": "image/png"
                },
                "campaign-medium": {
                    "file": "untitled-43-600x760.png",
                    "width": 600,
                    "height": 760,
                    "mime-type": "image/png"
                },
                "campaign-mobile": {
                    "file": "untitled-43-300x380.png",
                    "width": 300,
                    "height": 380,
                    "mime-type": "image/png"
                },
                "campaign-mobile-retina": {
                    "file": "untitled-43-600x760.png",
                    "width": 600,
                    "height": 760,
                    "mime-type": "image/png"
                }
            },
            "image_meta": {
                "aperture": "0",
                "credit": "",
                "camera": "",
                "caption": "",
                "created_timestamp": "0",
                "copyright": "",
                "focal_length": "0",
                "iso": "0",
                "shutter_speed": "0",
                "title": "",
                "orientation": "0",
                "keywords": []
            },
            "_cloudinary_v2": {
                "_sync_signature": {
                    "0": "",
                    "file": "",
                    "upgrade": "c4ca4238a0b923820dcc509a6f75849b",
                    "download": "d41d8cd98f00b204e9800998ecf8427e"
                },
                "_process_log": []
            },
            "all_meta": {
                "_wp_attached_file": [
                    "2021/05/untitled-43.png"
                ],
                "_wp_attachment_metadata": [
                    "a:6:{s:5:\"width\";i:782;s:6:\"height\";i:991;s:4:\"file\";s:23:\"2021/05/untitled-43.png\";s:5:\"sizes\";a:6:{s:6:\"medium\";a:4:{s:4:\"file\";s:23:\"untitled-43-237x300.png\";s:5:\"width\";i:237;s:6:\"height\";i:300;s:9:\"mime-type\";s:9:\"image/png\";}s:9:\"thumbnail\";a:4:{s:4:\"file\";s:23:\"untitled-43-150x150.png\";s:5:\"width\";i:150;s:6:\"height\";i:150;s:9:\"mime-type\";s:9:\"image/png\";}s:14:\"campaign-large\";a:4:{s:4:\"file\";s:23:\"untitled-43-760x963.png\";s:5:\"width\";i:760;s:6:\"height\";i:963;s:9:\"mime-type\";s:9:\"image/png\";}s:15:\"campaign-medium\";a:4:{s:4:\"file\";s:23:\"untitled-43-600x760.png\";s:5:\"width\";i:600;s:6:\"height\";i:760;s:9:\"mime-type\";s:9:\"image/png\";}s:15:\"campaign-mobile\";a:4:{s:4:\"file\";s:23:\"untitled-43-300x380.png\";s:5:\"width\";i:300;s:6:\"height\";i:380;s:9:\"mime-type\";s:9:\"image/png\";}s:22:\"campaign-mobile-retina\";a:4:{s:4:\"file\";s:23:\"untitled-43-600x760.png\";s:5:\"width\";i:600;s:6:\"height\";i:760;s:9:\"mime-type\";s:9:\"image/png\";}}s:10:\"image_meta\";a:12:{s:8:\"aperture\";s:1:\"0\";s:6:\"credit\";s:0:\"\";s:6:\"camera\";s:0:\"\";s:7:\"caption\";s:0:\"\";s:17:\"created_timestamp\";s:1:\"0\";s:9:\"copyright\";s:0:\"\";s:12:\"focal_length\";s:1:\"0\";s:3:\"iso\";s:1:\"0\";s:13:\"shutter_speed\";s:1:\"0\";s:5:\"title\";s:0:\"\";s:11:\"orientation\";s:1:\"0\";s:8:\"keywords\";a:0:{}}s:14:\"_cloudinary_v2\";a:2:{s:15:\"_sync_signature\";a:4:{i:0;s:0:\"\";s:4:\"file\";s:0:\"\";s:7:\"upgrade\";s:32:\"c4ca4238a0b923820dcc509a6f75849b\";s:8:\"download\";s:32:\"d41d8cd98f00b204e9800998ecf8427e\";}s:12:\"_process_log\";a:0:{}}}"
                ],
                "_cloudinary_pending": [
                    "1621436595"
                ],
                "_cloudinary_sync_queued": [
                    "auto_sync_thread_0"
                ],
                "auto_sync_thread_0": [
                    "1"
                ]
            }
        }
    },
    "config_report": {
        "cloudinary": [],
        "about": [],
        "usage": null,
        "last_usage": {
            "plan": "SSENSE - 1,515 Annual Units Bucket",
            "last_updated": "2021-05-18",
            "transformations": {
                "usage": 2656413,
                "credits_usage": 2.66
            },
            "objects": {
                "usage": 118161626
            },
            "bandwidth": {
                "usage": 160880156547578,
                "credits_usage": 146.32
            },
            "storage": {
                "usage": 8468803716793,
                "credits_usage": 7.7
            },
            "credits": {
                "usage": 156.68
            },
            "requests": 160880104502772,
            "resources": 2023505,
            "derived_resources": 116138121,
            "jpegmini": {
                "usage": 0,
                "limit": 100
            },
            "media_limits": {
                "image_max_size_bytes": 41943040,
                "video_max_size_bytes": 1048576000,
                "raw_max_size_bytes": 41943040,
                "image_max_px": 50000000,
                "asset_max_total_px": 300000000
            },
            "max_image_size": 41943040,
            "max_video_size": 1048576000
        },
        "signature": "REMOVED SIGNATURE JUST IN CASE",
        "version": "2.7.2",
        "url": "cloudinary://REMOVED-CREDENTIALS@ssenseweb",
        "status": {
            "status": "ok"
        },
        "media_display": {
            "image_optimization": "on",
            "image_format": "auto",
            "image_quality": "auto",
            "enable_breakpoints": "off",
            "breakpoints": 3,
            "bytes_step": 200,
            "max_width": 2048,
            "min_width": 800,
            "image_preview": "https://res.cloudinary.com/demo/image/upload/w_600/sample.jpg",
            "video_player": "wp",
            "video_controls": "on",
            "video_loop": "off",
            "video_autoplay_mode": "off",
            "video_limit_bitrate": "off",
            "video_bitrate": "500",
            "video_optimization": "on",
            "video_format": "auto",
            "video_quality": "auto"
        },
        "setup": {
            "enable_report": "on"
        },
        "sync_media": {
            "auto_sync": "off",
            "cloudinary_folder": ".",
            "offload": "dual_full"
        },
        "gallery": {
            "transition": "fade",
            "aspectRatio": "3:4",
            "navigation": "always",
            "zoom": true,
            "carouselLocation": "top",
            "carouselOffset": 5,
            "carouselStyle": "thumbnails",
            "displayProps": {
                "mode": "classic",
                "columns": 1
            },
            "indicatorProps": {
                "shape": "round"
            },
            "themeProps": {
                "primary": "#cf2e2e",
                "onPrimary": "#000000",
                "active": "#777777"
            },
            "zoomProps": {
                "type": "popup",
                "viewerPosition": "bottom",
                "trigger": "click"
            },
            "thumbnailProps": {
                "width": 64,
                "height": 64,
                "navigationShape": "radius",
                "selectedStyle": "gradient",
                "selectedBorderPosition": "all",
                "selectedBorderWidth": 4,
                "mediaSymbolShape": "round"
            },
            "cloudName": "ssenseweb",
            "container": ""
        }
    }
}
pereirinha commented 3 years ago

@pepoandra

Thanks for the updates.

A couple of things here to consider, as the internals from Cloudinary v1 to v2 changed dramatically. The Cloudinary v2, released in March 2020, depends on WP REST API introduced in WP 4.7, in December 2016.

You might want to give it a try and install the plugin that was merged into the core to enable the REST API. Please note that this plugin is untouched for the last 5y and I'm unsure if it supports all the functionality we need in the most recent version of Cloudinary.

That being said, it's important to keep in mind that running so old versions of WordPress and plugins will accrue technical debt.

I hope this helps, but I don't think we'll provide further support for legacy versions.

pepoandra commented 3 years ago

Thanks for the info.

However, my problem is that I want to migrate to the new versions of PHP (5.6 -> 7.4), Wordpress (4.4 -> 5.7.2) & Cloudinary (1.1 -> 2.7.2) and I can't because the new cloudinary plugin is not working for me.

My current situation is that when I ran it locally, it stays in "Uploading to Cloudinary" for a couple minutes. Then it says 'Not Synced", without any errors. And if I re-push it to Cloudinary, then it immediately says "Synced".

I suspect that there might be some timeout happening.

And on Kubernetes, it just never uploads.

It seems to me that the problem involves the HTTP call POST /index.php?rest_route=/cloudinary/v1/queue

That sometimes doesn't happen, sometimes it times out without responding, (i think)

Any advice as to how to debug this?

I tried with

define('WP_DEBUG', true);
define('DEBUG_SCRIPTS', true);

which was more verbose but didn't help me much, tbh.

Thanks once again for your time.

pepoandra commented 3 years ago

Update: I changed the permalink structure from plain text to post names & now I have access to [my domain]/wp-json/cloudinary/v1

However, I still have the same issue of the call not being triggered & consequently the image not being uploaded.

Running WordPress 5.7.2 & Cloudinary 2.7.2

pereirinha commented 3 years ago

@pepoandra

Do you have enabled any service to prevent hotlinking of the images? Also, is your domain protected by HTTP Basic auth?

pepoandra commented 3 years ago

Our domain is serving plain HTTP over HTTPS (I think), using only WordPress authentication but only accessible through the company's VPN.

Regarding the hotlinking of the images, I'm not sure what you mean, but that's another issue we have currently. Our images are now being uploaded to a folder in the docker container (Its a monopod) In the next week or two we're going to add an Elastic Shared Volume on Kubernetes and have more than one pod.

pepoandra commented 3 years ago

Update: There was just no way around this error, none of the suggestions on this thread were useful at all & I couldn't find any documentation for this plugin.

So the solution was to downgrade the version of the plugin until I found one that worked. None of the 2.x versions worked.

So I installed v 1.1.8, which is problematic because it seems to have a serious memory leak when uploading images.

Conclusion: if PHP sucks & WordPress sucks, it was naive of me to expect this plugin not to suck just as much, if not more.

Welp. Now I know.

Vdeub-cloudinary commented 3 years ago

Hi @pepoandra,

Sorry for the inconvenience.

Would you be available for a call with @pereirinha and me in order to go over your configurations and see what could be the culprit here? So far, we have never been able to replicate the issues you are having.

Please let me know an email we can add to the invitation as I can't locate you in the company account and also your availabilities.

Best, Loic

pepoandra commented 3 years ago

Absolutely.

Don't let my fleeting frustration fool you: I do appreciate the work you do & this plugin.

I'm available for a call whenever you'd like.

Vdeub-cloudinary commented 3 years ago

Hi @pepoandra,

Could you share an email and your availabilities for tomorrow or Friday? Thanks!

pepoandra commented 3 years ago

you can contact me at pepo dot andrade at gmail dot com im available tomorrow from 10h till 17h ((GMT-4) Friday, 11h till 13h ((GMT-4)

Vdeub-cloudinary commented 3 years ago

Hi @pepoandra,

You should have received the invitation.

Best, Loic

pepoandra commented 3 years ago

boiis (@Vdeub-cloudinary @pereirinha) i figured it out.

The problem was that Kubernetes elastic load balancer had the loadBalancerSourceRanges set to the IP ranges of the company's VPN.

But with the WP_REST_API or whatever's called, the server needs to be able to call itself.

The quick solution was to remove all IP ranges, in which case, the plugin works.

The real solution would be to add the server's VPC IP range to the loadBalancerSourceRanges so the calls the server makes to itself (The so called loopback) are not blocked by the ELB.

Thanks for your time.

pereirinha commented 3 years ago

Thanks for sharing this, @pepoandra. We'll add it to our knowledge base.