Deploy xong, file Blade đã có marker release mới nhưng trang ngoài vẫn giống hệt bản cũ. Tình huống này dễ dẫn tới phản xạ chạy một chuỗi lệnh “clear all”, hard reload rồi hy vọng mọi thứ tự ổn. Vấn đề là HTML cũ, CSS cũ và cấu hình cũ có thể đến từ ba lớp khác nhau; xóa rộng ngay từ đầu vừa làm mất bằng chứng, vừa khiến rollback khó đoán hơn.

Cách an toàn hơn là gắn marker A/B cho từng release, kiểm tra từ ngoài vào trong, rồi chỉ thay đổi một lớp mỗi lần. Bài này dùng một fixture nhỏ trên Windows 11 với Node.js 24.19.0 để kiểm chứng logic marker/hash. Fixture không phải môi trường Botble production, không phải benchmark CDN và cũng không thay thế việc đọc output Artisan trên đúng version site của bạn.

“Bản cũ” là HTML, asset hay cấu hình?

Trước khi chạm vào cache, hãy tách triệu chứng. Nếu response HTML vẫn chứa marker A trong khi origin đã chạy B, nghi ngờ đầu tiên là browser cache, reverse proxy, CDN hoặc page cache. Nếu HTML là B nhưng URL CSS hoặc checksum file public vẫn là A, vấn đề nằm gần bước publish asset, đường dẫn public hoặc release symlink hơn. Nếu HTML và CSS đều là B nhưng giá trị cấu hình vẫn cũ, hãy kiểm tra config cache và nguồn cấu hình mà process đang đọc.

Ma trận phân biệt HTML cũ, CSS cũ và lỗi quyền ghi sau deploy Botble
Mỗi triệu chứng cần một probe riêng trước khi xóa cache hoặc publish lại asset.
Triệu chứngProbe nên chạy trướcLớp cần nghi ngờ
HTML marker ABody hash, Age, ETag, request bypass CDNBrowser, CDN, proxy, page cache
HTML B, CSS AURL asset, SHA-256, mtime và public pathPublish asset, symlink, CDN asset
HTML/CSS B, config AGiá trị runtime và trạng thái config cacheLaravel config cache, process cũ
Lệnh exit 0 nhưng file không đổiOwner/group, write probe, file sinh ra và logQuyền ghi, path sai, release sai

Botble cũng phân biệt trang cấu hình cache với trang dọn cache: phần Settings → Cache điều khiển hành vi, còn Cache Management cho xem và xóa các loại cache. Tài liệu Cache Management liệt kê CMS cache, compiled views, config cache, route cache và các cache cho menu, shortcode, widget. Vì vậy “Botble cache” không phải một file duy nhất.

Gắn marker và checksum trước khi xóa cache

Một release nên tự nhận diện được mà không cần mở source qua SSH. Marker có thể là response header chỉ hiện trong nội bộ, HTML comment không chứa secret và checksum của asset đã build. Đừng đưa commit private, hostname nội bộ hay token vào marker public; một chuỗi ngắn như release-B là đủ.

# Kiểm response và asset từ bên ngoài
curl -I https://example.com/
curl -s https://example.com/ | sha256sum
curl -s https://example.com/themes/my-theme/css/app.css | sha256sum

Fixture trong bài tạo ba marker HTML, CSS và config cho release A/B. Positive control B/B/B đạt; ba negative control lần lượt giữ HTML ở A, giữ asset ở A và chặn write probe. Rollback chỉ được coi là xong khi cả ba marker quay về A. Tám assertion đều đạt, nhưng kiểm tra quyền ghi ở fixture là ranh giới EACCES được mô phỏng, không phải ACL Linux thật.

Bảng kết quả fixture A B cho HTML, CSS và config trong deploy và rollback
Fixture kiểm ba marker: chỉ B/B/B hoặc rollback A/A/A mới được coi là đồng bộ.

Cách ghi bằng chứng này giúp tránh một kết luận sai rất phổ biến: health endpoint trả 200 không chứng minh HTML, asset và config đang cùng một release. Tương tự, exit code 0 chỉ nói process kết thúc thành công; vẫn phải đọc output, checksum và response thực tế.

Kiểm tra từ ngoài vào trong

Thứ tự dưới đây giữ được nhiều bằng chứng nhất. Sau mỗi bước, request lại cùng URL và ghi marker/hash; nếu đã đồng bộ thì dừng, không tiếp tục xóa các lớp khác cho “chắc ăn”.

  1. Browser và service worker: so sánh cửa sổ private, hard reload và curl. Nếu chỉ browser cũ, đừng đổ lỗi cho server.
  2. CDN, proxy, page cache: đọc Age, Cache-Control, ETag và request origin/bypass nếu hạ tầng cho phép. Purge đúng URL hoặc cache tag trước khi purge cả zone.
  3. Cache ứng dụng và theme: xem lớp nào đang giữ menu, widget, shortcode, compiled view hoặc theme lookup.
  4. Laravel optimization: kiểm config, route, event và view cache. Đừng coi optimize:clear là lệnh nhẹ.
  5. Published assets: so checksum trong source release và thư mục public; kiểm document root và symlink trỏ đúng B.
  6. Quyền ghi: xác nhận process web/CLI có cùng user, group và path; chạy write probe nhỏ trong đúng thư mục rồi xóa file probe.

Nếu cần đối chiếu smoke test public sau deploy, checklist SEO kỹ thuật cho Botble có phần canonical, indexability và asset. Còn lỗi thumbnail/media là pipeline khác; bài tạo lại thumbnail Botble an toàn xử lý đúng nhóm đó.

Khi nào publish asset, khi nào chỉ clear cache?

Botble Commands hiện mô tả cms:publish:assets là lệnh tổng để copy core, plugin và theme assets vào public. Với phạm vi nhỏ hơn, docs có cms:theme:assets:publish [theme] và cms:plugin:assets:publish <plugin>. cms:theme:clear-cache lại dọn cached theme data như option, registered asset và compiled partial lookup; nó không đồng nghĩa với copy lại file CSS/JS.

Vì docs là rolling, trước khi chạy trên site thật hãy xác minh lệnh có tồn tại và đọc help của chính bản đang deploy:

php artisan list | grep 'cms:.*assets\|cms:theme:clear-cache'
php artisan help cms:theme:assets:publish
php artisan help cms:plugin:assets:publish

Nguyên tắc chọn lệnh khá thẳng: đổi CSS/JS theme mà file public còn hash A thì publish theme asset; đổi asset plugin thì publish đúng plugin; HTML/widget/shortcode stale nhưng file public đã B thì kiểm cache tương ứng. Không cần chạy lệnh tổng nếu marker đã chỉ ra một phạm vi nhỏ.

optimize:clear rộng hơn tên gọi của nó

Laravel 13 Deployment nói optimize cache configuration, event, route và view cho production. Đáng chú ý, optimize:clear không chỉ xóa file do optimize sinh ra; tài liệu hiện hành ghi nó còn xóa các key trong default cache driver.

Điều đó có thể ảnh hưởng nhiều hơn một compiled view. Nếu site dùng default cache cho dữ liệu ứng dụng, hãy coi đây là thao tác cần maintenance window hoặc fixture, không phải nút reset vô hại. Muốn hiểu cache entry và TTL không đồng nghĩa với việc ghi lại value, có thể đọc thêm bài Laravel 13 Cache::touch().

Quyền file đúng không phải là chmod 777

Botble Troubleshooting nhắc tới quyền ghi cho storage và bootstrap/cache. Nhưng con số mode chỉ là một nửa câu chuyện: process PHP-FPM, CLI deploy và queue worker có thể chạy bằng user/group khác nhau. Một lệnh chạy tốt qua SSH chưa chắc web process có thể tạo compiled view hoặc cache file.

Hãy ghi owner, group và mode trước khi sửa. Chạy write probe bằng đúng process user, trong đúng thư mục cần kiểm, với tên file có phạm vi; sau đó xóa chính file đó. Không đổi owner cả project và không mở 777 chỉ để triệu chứng biến mất. Với deploy theo symlink, kiểm thêm document root, public path và cache directory sống qua lần switch release như thế nào.

Rollback code và asset phải về cùng một bản

Rollback code về A nhưng public asset vẫn B cũng là một deploy lệch. Giữ manifest nhỏ cho mỗi release gồm marker HTML, checksum CSS/JS và version cấu hình không nhạy cảm. Khi rollback, chuyển code và asset về cùng release, invalidate đúng lớp cache rồi kiểm homepage, một trang động, một asset và health endpoint.

Fixture của bài chỉ pass rollback khi HTML, CSS và config đều là A. Đó là negative control quan trọng: nếu chỉ nhìn /up hoặc chỉ nhìn giao diện, một phần lệch version có thể bị bỏ qua cho tới khi người dùng mở trang khác.

Runbook ngắn sau khi đã biết nguyên nhân

  1. Ghi release dự kiến và marker/hash quan sát được.
  2. Phân loại HTML, asset, config hay quyền ghi.
  3. Chạy một probe không thay đổi trạng thái.
  4. Chọn lệnh nhỏ nhất trên đúng Botble version; đọc output và file sinh ra.
  5. Request lại qua browser, CDN và origin nếu có; so marker/hash.
  6. Nếu không khớp, rollback code và asset cùng release rồi kiểm lại.

Tóm lại, “Botble vẫn hiện bản cũ” không phải một lỗi duy nhất. Marker A/B biến cảm giác giao diện chưa đổi thành bằng chứng có thể kiểm: HTML đến từ đâu, asset nào đang được phục vụ, config nào đang chạy và process có thực sự ghi được hay không. Tìm đúng lớp rồi mới clear hoặc publish; tới đó mọi thứ bớt “tới công chuyện” hẳn.