Custom domain cho Cloudinary trên WordPress

Về mặt lý thuyết, ý tưởng custom domain, quản lý qua CDN Cloudflare để cache ảnh, nó phù hợp nhất cho các dịch vụ giới hạn băng thông như Cloudinary

Các ý tưởng trong bài, vẫn có đôi chỗ chưa hài lòng nhưng cũng được khoảng 80%-90% so với kế hoạch ban đầu

Mệt mỏi nhất vẫn là bước đưa các kích thước vào chính xác vị trí vị trí mình mong muốn, điểm này nếu bạn dùng Jetpack, thì hãng đã viết plugin, tự làm từ A -> Z cả rồi

Plugin gốc của Cloudinary sau nhiều lần cập nhập cũng rất tuyệt vời, trừ vụ họ quản lý link, ảnh chằng chịt quá, khi view code nhìn hơi rối mắt

Đây là 1 bài rất phức tạp, gần như không dùng plugin, mọi thứ đều làm thủ công, nên còn khá nhiều lỗi, mọi người tham khảo, đọc cho vui, chứ mình nghĩ khó ai rảnh mà làm theo 😛

Cloudinary khả năng nén, tối ưu hóa bằng các công nghệ liên quan tới ảnh cực kì mạnh, gần như hàng đầu thế giới

Trong tất cả các plugin, dịch vụ về ảnh mình từng dùng, Cloudinary cho ra dung lượng nhỏ nhất mà chất lượng gần như không thay đổi, tùy biến siêu nhiều, nếu thích có thể giảm dung lượng xuống rất nhỏ mà chất lượng chỉ thay đổi chút ít

Ngoài chuyện hỗ trợ định dạng AVIF rất mới, họ còn bóc tách, xem nội dung tấm ảnh, biết ảnh chụp cái gì, người, động vật hay cây cối, vật thể  (khá giống google images, facebook), nên khi sử dụng các tùy chọn biến thể ảnh, nó có thể tạo thumbnail chính xác hơn tới đối tượng bạn mong muốn

Nhờ thế Cloudinary sẽ hiệu quả hơn nếu bạn làm các shop bán hàng, ảnh thumbnail sẽ hiện, zoom chính xác hơn vào chủ thể, trên các blog cơ bản kiểu thèng bibica.net, thumbnail đa phần chỉ là làm nhỏ lại tấm ảnh, các ưu điểm mạnh nhất của Cloudinary gần như không dùng tới, khá là phí :]]

Đăng kí tài khoản Cloudinary

Tạo tài khoản Cloudinary miễn phí, tại phần Account sẽ thấy Cloud Name của tài khoản (có thể ấn edit để đổi sang 1 tên dễ nhớ)

2023-09-26_9-14-52

Sau đó đi tới Upload, tạo Auto upload mapping

2023-09-26_9-02-51

  • Folder: đặt tên gì cũng được không quan trọng
  • URL prefix: điền đường dẫn tới thư mục uploads trên WordPress

Các ảnh thông thường sẽ có url là: https://bibica.netwp-content/uploads2023/092023-09-25-10-27-33.png

Sau khi tạo Auto upload mapping, Cloudinary sẽ có url là: https://res.cloudinary.com/xinclub/f_webp,q_auto,dpr_auto/img/2023-09-25-10-27-33.png

Trong đó xinclub là Cloud Name, img là Folders bạn vừa chọn, giữa 2 giá trị này là các giá trị f_webp,q_auto,dpr_auto,w_500,h_300 … để tùy biến ảnh, tùy bạn đưa vào

Việc tiếp theo là tạo các custom riêng để dùng Cloudflare làm cache, và giúp các link ngắn gọn hơn

Custom domain và cache qua Webinoly Reverse Proxy FastCgi Cache

File cấu hình như bên dưới

# REVERSE PROXY NGINX CONFIGURATION by Webinoly

location / {
    proxy_set_header Connection "";
    proxy_http_version 1.1;

    # WebinolyProxyCacheStart
    proxy_cache img_bibica_net;
    proxy_cache_key "$scheme$request_method$host$request_uri";
    
    proxy_cache_valid 200 10y;
    proxy_cache_valid 301 302 303 307 308 404 410 451 1m;
    proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    proxy_buffer_size 16k;
    proxy_buffers 16 16k;
    
    set $skip_cache_img_bibica_net 0;
    include apps.d/img.bibica.net*site_custom_cache.conf;
    proxy_cache_bypass $skip_cache_img_bibica_net;
    proxy_no_cache $skip_cache_img_bibica_net;
    # WebinolyProxyCacheEnd
    proxy_connect_timeout 300;
    proxy_send_timeout    300;
    proxy_read_timeout    300;
    proxy_ignore_headers   Set-Cookie;
    proxy_intercept_errors on;
    #proxy_next_upstream error timeout http_500;
    
    # Upstream defined here: conf.d/upstream_proxy.conf
    proxy_pass https://res.cloudinary.com/xinclub/f_webp,q_auto:best/img/;
        
}

location /auto/ {
    proxy_set_header Connection "";
    proxy_http_version 1.1;

    # WebinolyProxyCacheStart
    proxy_cache img_bibica_net;
    proxy_cache_key "$scheme$request_method$host$request_uri";
    
    proxy_cache_valid 200 10y;
    proxy_cache_valid 301 302 303 307 308 404 410 451 1m;
    proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    proxy_buffer_size 16k;
    proxy_buffers 16 16k;
    
    set $skip_cache_img_bibica_net 0;
    include apps.d/img.bibica.net*site_custom_cache.conf;
    proxy_cache_bypass $skip_cache_img_bibica_net;
    proxy_no_cache $skip_cache_img_bibica_net;
    # WebinolyProxyCacheEnd
    proxy_connect_timeout 300;
    proxy_send_timeout    300;
    proxy_read_timeout    300;
    proxy_ignore_headers   Set-Cookie;
    proxy_intercept_errors on;
    #proxy_next_upstream error timeout http_500;
    
    # Upstream defined here: conf.d/upstream_proxy.conf
    proxy_pass https://res.cloudinary.com/xinclub/w_500,f_webp,q_auto:best/img/;
        
}

Link custom là img.bibica.net

Hiện tại thì mình dùng 2 kích thước, 1 là chiều rộng 500 px cho ảnh thumbnail, còn lại là giữ nguyên kích thước gốc

  • w_500 là vị trí thumbnail -> đường dẫn img/bibica.net/auto/ (chất lượng ảnh dùng auto best)
  • Ở ảnh full thì giữ nguyên kích thước gốc, đường dẫn img.bibica.net (chất lượng ảnh dùng auto best)

Các tùy biến ảnh như 500,f_webp,q_auto:best, Cloud Name và Folder images đều đã được ẩn hoàn toàn, link đã ngắn gọn và sạch sẽ hết sức có thể

Từ link gốc https://bibica.netwp-content/uploads2023/092023-09-25-10-27-33.png

Trong trường hợp muốn dùng ảnh có chiều rộng tối đa 500px, thêm /auto/ vào sau domain: https://img.bibica.net/auto/2023/09/2023-09-25-10-27-33.png

Bạn có thể thêm các tùy biến ảnh khác nhau, tùy vào sở thích, mình đang dùng 2 tùy chọn là /f_webp/q_auto:best/ ảnh nén về .webp và chất lượng ảnh tốt nhất có thể, kể cả ảnh thumbnail

Nếu thích hoặc đú đởn, có thể dùng trực tiếp custom domain các link Cloudinary lên chính domain gốc bibica.net, nhìn link ảnh là hú hồn con chồn, vì cứ tưởng ảnh gốc là để trên host 😀 có điều tách ra 1 domain phụ làm link ảnh cho dễ quản lý và cấu hình, chung hết 1 domain nhìn chằng chịt lắm 😛

Set ảnh vào các vị trí phù hợp

Sử dụng Code Snippets tạo 1 file php với nội dung:

 function cloudinary_photon_custom($attr, $attachment, $size) {
     
$image_id   = get_post_thumbnail_id();
$image_meta = wp_get_attachment_metadata( $image_id );
$image_path = get_attached_file( $image_id );
     
     if ($size === 'thumbnail') {
         $attr['src'] = "https://img.bibica.net/auto/".$image_meta['file'];
     } 
   else if ($size === 'large') {
        $attr['src'] = "https://img.bibica.net/w_768/".$image_meta['file'];
    }
 
     return $attr;
 }
 add_filter('wp_get_attachment_image_attributes', 'cloudinary_photon_custom', 999 , 3);

Đoạn code này mình làm thủ công, đó là cứ ảnh size thumbnail thì đập thẳng luôn link https://img.bibica.net/auto/ vào 😀 sau đó nối với thư mục và tên file

Nếu bạn dùng nhiều định dạng hơn thì cứ thêm vào

Đoạn code trên có 1 lỗi nhỏ, nó chỉ hoạt động tốt theo từng ảnh, trong trường hợp 1 album 4-6 tấm ảnh (tên file sẽ giống nhau) mà set ảnh là thumbnail, là nó hiện ra có 1 tấm à 😀

Khắc phục tạm lỗi trên thì ở vị trí thumbnail, featured image, để tránh việc trùng tên với các album trước đây tạo, ở vị trí đó mình set dùng ảnh medium hay 1 tên mới tùy ý chưa dùng là được

Ban đầu tính nhờ tay bạn già Vượng Nguyễn viết hộ phần này, mà thấy hắn cũng bận, nên thôi, cứ google loạn hết cả lên, xong cắt dán đủ kiểu, không hiểu sao cuối cùng cũng có chạy :]] bạn nào rành code chắc chỉ cần 5 phút là viết xong với xử lý tốt cái lỗi mình nói ở trên rồi

Lúc này, chúng ta đã xử lý cơ bản các ảnh ở các vị trí thumbnail và featured image

Về các ảnh trong nội dung bài viết có thể dùng Lucas String Replace, để tìm và thay thế các link, mình thì để tăng trải nghiệm xem bài, các ảnh bên trong nội dung bài viết, giữ nguyên ảnh gốc, nên chỉ cần đổi img.bibica.net/ sang img.bibica.net/ là xong

2023-09-26_9-54-00

Xử lý cache ảnh và header trên Cloudflare

Lúc này, tình huống phát sinh là đôi khi ảnh bạn upload lên, chưa kịp cache xuống Reverse Proxy mà Cloudflare đã HIT 😀 làm status của Reverse Proxy cứ MISS

Check thì mình thấy khi là admin, xem ảnh, nó có cookie wordpress_test_cookie và wordpress_logged_in

Có thể dùng Cache Rules thêm vào để khi là admin xem ảnh, Cloudflare không cache các ảnh này

(http.host eq "img.bibica.net" and http.cookie contains "wordpress_test_cookie" and http.cookie contains "wordpress_logged_in")

2023-09-28_12-38-31

Lúc này, khi bạn upload ảnh, do không bị Cloudflare cache, nên Reverse Proxy cache HIT bình thường

2023-09-28_14-45-37

Khách xem bài thì sẽ thấy Reverse Proxy và Cloudflare cache HIT cùng lúc

2023-09-28_14-55-39

Tiếp theo vào Transform Rules -> Modify Response Header, thêm và xóa 1 số header cho sạch sẽ 😀

2023-09-26_10-24-37

Mình thêm vào 1 header là cache-control: public, max-age=31536000, immutable

Còn lại Cloudinary có header nào mình xóa hết 😀

Preload lại ảnh lần đầu

Mặc định với hình thức Auto upload mapping, ảnh khi lần đầu tiên truy cập, sẽ được kéo về thư mục Folder trong tài khoản của bạn, nó sẽ hơi chậm 1 chút, rảnh thì có thể dùng precache.sh để chạy auto, lý thuyết thì khi ảnh cf-cache-status: HIT thì ảnh cũng đã về thư mục Folder rồi, cứ để nó chạy auto ít tiếng cũng được 😛

2023-09-26_10-36-17

Cloudinary <-> Cloudflare

Sau khi ảnh đã được đưa về server của Cloudinary, tạo thumbnail, nén ảnh …. từ các lần load tiếp theo, nó sẽ được Cloudflare load thẳng, nên sẽ nhanh hơn

Khi dùng trực tiếp, thỉnh thoảng mình vẫn có cảm giác, tốc độ khá chậm, có vẻ do Cloudinary dùng nhiều các công nghệ liên quan tới ảnh, đọc cả hình ảnh để xem nội dung hình ảnh, CDN thậm chí họ dùng tới 3 dịch vụ siêu to là Akamai, Fastly và cả CloudFlare

Vấn đề rất nhây, là cùng 1 IP mình đổi 3 trình duyệt, thấy ảnh radom ra 3 dịch vụ CDN luôn ….

-> tình huống này có thể giải thích lý do tại sao thi thoảng bạn thấy ảnh từ Cloudinary khá chậm, kiểu ban đầu tấm ảnh load sang CDN của Akamai, cache ở đó, khách nào được phân tới cụm Akamai thì nhanh, nhưng nếu khách bị đá sang CDN của Fastly hay CloudFlare, do chưa có cache, nên chậm

Thường sau khi dùng 2-3 ngày, để Cloudinary cache sang 3 cụm CDN thì vấn đề này ổn hơn

Có điều mình thấy xử lý đơn giản hơn, ở bước Reverse Proxy, cache lại 1 lần tại VPS của mình là được

WordPress -> Cloudinary (backup storage) -> Reverse Proxy (cache)-> Cloudflare

Đi theo tuyến đường này thì Cloudinary sau khi xử lý ảnh xong, ảnh sẽ được cache vào Reverse Proxy, rồi từ Reverse Proxy đi tới Cloudflare

Trên Cloudinary bạn chỉ tốn Credit cho Storage, Transformations, 1 ít cho Bandwidth nên lý thuyết là có thể dùng thoải mái ở tài khoản miễn phí

Kết luận sơ bộ

Cấu hình cho bài này, thực sự phức tạp quá sức cần thiết 😀 rất nhiều thứ mình làm, cũng không chắc hoạt động có đúng như mình nghĩ không 😀 cụ thể là vấn đề Reverse Proxy FastCgi Cache, trong cấu hình mình nhớ set là cache lưu 10 năm, mà thi thoảng ở 1 vài tấm ảnh, ấn vào coi thử thì thấy MISS cache rồi, chẳng hiểu lạc đi đâu 😀

Cloudinary cho chất lượng ảnh rất tốt, dung lượng file khá nhỏ, các tùy biến về ảnh thì cực kì đa dạng, các trang bán hàng, sản phẩm nhiều làm thumbnail mới thấy sự ưu việt về tùy biến của họ, còn thuần túy chỉ tạo thumbnail như mình đang dùng thì chưa tận dụng hết ưu điểm

Link ảnh rất gọn cũng có thể là 1 ưu điểm 😀 nếu bạn nào làm theo bài này, gần như không ai biết là đang dùng Cloudinary để nén ảnh, tạo thumbnail, vì các thông tin bị ẩn đi sạch sẽ

2023-09-28_13-58-56

Sử dụng Auto upload mapping, có một ưu điểm nhỏ, các ảnh sẽ được kéo về Cloudinary với cấu trúc thư mục tương tự trên WordPress, trong trường hợp bạn xóa nhầm ảnh, vẫn còn 1 nơi để sơ cua

Cách này cũng có thêm 1 ưu điểm, bạn có thể set chính xác các tùy biến vào vị trí mình mong muốn, ví dụ ở ảnh thumbnail, có thể giảm chất lượng ảnh, chọn các tỷ lệ cắt, zoom khác nhau …. các plugin khác đa phần áp dụng cùng 1 bộ lọc cho tất cả vị trí

Nói chung mình viết bài này vì … thích, dùng Cloudinary do đây là dịch vụ đầu tiên mình biết tới liên quan tới ảnh

Dùng bình thường mình thấy cài plugin Jetpack, bật Jetpack Photon lên, mất chưa tới 10s, quá đủ hiệu quả và siêu nhàn 😀

Comment policy: We love comments and appreciate the time that readers spend to share ideas and give feedback.
Notes: However, those deemed to be spam or solely promotional will be deleted.

You can create a Gravatar account, add avatar, then use that email to comment here, your account will have a more beautiful Avatar, easier to recognize with other members.