Tạo trang tĩnh miễn phí cho WordPress với Simply Static và Vercel

Trước đây mình từng có khá nhiều bài viết về Simply Static, thường nó hoạt động ổn với Github, có điều đôi khi 2 thèng này lại lên cơn co giật ngáo đá sao đó, mình cũng chịu, không rõ lý do tại sao, phần cũng muốn cải thiện tốc độ khi tạo trang tĩnh, phần cũng muốn chuyển hẳn về dùng trên bản miễn phí

Hiện tại mình dùng cách đơn giản nhất, dùng Simply Static tạo file tĩnh xuống VPS, sau đó chuyển các file tĩnh sang 1 dịch vụ static file hosting, tổng thời hoàn thành mất khoảng 4-5 phút, không có ý nghĩa về mặt tốc độ, vì thường mình chạy cron lúc 3h sáng, 4h sáng tạo xong hay 3h05 tạo xong cũng thế, chủ yếu cách này hạn chế tối đa các lỗi khi upload thông qua Github, lại chỉ cần chạy trên bản Simply Static miễn phí

Hơi tiếc tí là bản free không hỗ trợ WP-CLI nên cách vận hành sẽ có vài công đoạn khá thủ công, không tự động hoàn toàn được so với bản Pro, nếu nhu cầu đơn giản, mỗi ngày chỉ tự tạo mới toàn bộ các trang, rồi tự cập nhập lên các dịch vụ static file thì bản free đã đáp ứng đủ

Do dạo này mình đang chuyển dần mọi thứ sang docker, nên Vercel ở bài này cũng chạy trên docker luôn :]]

Viết lại toàn bộ bài viết theo phiên bản Simply Static v3.1.8 miễn phí mới nhất, viết thêm các giải thích cụ thể hơn dành cho bạn nào chưa quen dùng docker …

Simply Static

Download Simply Static từ Wordpress plugins, cài đặt như plugin thông thường

2024 08 24 01 44 37

Deploy:

  • Deployment method: chọn Local Directory
  • Local Directory: tạo sẵn 1 thư mục tùy thích, mình dùng là /var/www/html/vercel-simply-static
  • Chọn Clear Local Directory để xóa các file trong thư mục này mỗi lần chạy

Cấu hình chính chỉ cần như thế, các phần râu ria khác thì tuỳ mọi người sử dụng

  • Advanced > Integrations, có thể tắt Simply Static (Admin Bar) đi cho sạch sẽ menu admin
  • Các thông số khác dùng mặc định là ổn

Mặc định bản thân Simply Static khi chạy, nó sẽ tự biết được thư mục root của WordPress đang là ở đâu, ví dụ mình đang chạy WordPress qua docker, đường dẫn của WordPress sẽ là /var/www/html/, -> vercel-simply-static sẽ là thư mục nằm ngang hàng với file wp-config.php

Nhớ phân quyền thư mục này theo đúng user WordPress đang chạy, mình dùng docker user đang dùng là 82 (www-data) nên chạy lệnh như bên dưới

chown -R 82:82 /home/bibica.net/www/vercel-simply-static
  • /home/bibica.net/www/vercel-simply-static là đường dẫn trực tiếp trên VPS của mình tới thư mục /vercel-simply-static (nếu đang ở bên trong docker WordPress thì sẽ là /var/www/html/vercel-simply-static)
  • Sau đó ấn button Generate Static Files chạy tạo các tĩnh lần đầu tiên

Để tạo các trang tĩnh tự động có thể chạy qua cron như tác giả hưởng dẫn, mình sửa lại 1 chút để có thể tự động các quá trình

Bên trong /wp-content/mu-plugins, tạo 1 file static.php chẳng hạn, nội dung điền code bên dưới

Chú ý, sửa lại dòng 4, thay /var/www/html/vercel-simply-static bằng đường dẫn tới thư mục chứa file tĩnh của bạn (dễ hiểu thì phần Deploy Local Directory ở trên điền là gì thì giờ điền vào đó lại)

<?php
if ( defined( 'WP_CLI' ) && WP_CLI ) {
    class Static_Command extends WP_CLI_Command {
        private $output_dir = '/var/www/html/vercel-simply-static';
        private $check_interval = 5; // Thời gian chờ giữa các lần kiểm tra (giây)
        private $stable_time = 5; // Thời gian xác nhận không có file mới (giây)
        private $initial_delay = 10; // Thời gian chờ ban đầu để Simply Static bắt đầu (giây)

        public function run() {
            // Đảm bảo rằng plugin Simply Static đã được nạp
            if ( class_exists( 'Simply_Static\Plugin' ) ) {
                $simply_static = Simply_Static\Plugin::instance();
                $simply_static->run_static_export();

                WP_CLI::success( 'Static export build started. Waiting for completion...' );

                // Chờ một khoảng thời gian ban đầu để quá trình sao chép file bắt đầu
                sleep($this->initial_delay);

                // Chờ đợi quá trình xuất tĩnh hoàn thành bằng cách kiểm tra thư mục
                $this->wait_for_completion();
            } else {
                WP_CLI::error( 'Simply Static plugin not found.' );
            }
        }

        private function wait_for_completion() {
            $previous_file_count = 0;
            $stable_check_time = 0;

            while (true) {
                $current_file_count = $this->get_file_count($this->output_dir);

                // Kiểm tra nếu có sự thay đổi về số lượng file trong thư mục
                if ($current_file_count > $previous_file_count) {
                    $previous_file_count = $current_file_count;
                    $stable_check_time = 0; // Reset thời gian kiểm tra ổn định
                } else {
                    // Nếu số lượng file không thay đổi, tăng thời gian ổn định
                    $stable_check_time += $this->check_interval;
                }

                // Nếu đã có ít nhất 1 file và thời gian ổn định đã đạt đến mức cần thiết, quá trình hoàn thành
                if ($current_file_count > 0 && $stable_check_time >= $this->stable_time) {
                    break;
                }

                sleep($this->check_interval);
            }

            WP_CLI::success( 'Static export files have been successfully created in ' . $this->output_dir );
        }

        private function get_file_count($dir) {
            if (!is_readable($dir)) return 0;
            $files = array_diff(scandir($dir), array('.', '..'));
            return count($files);
        }
    }

    WP_CLI::add_command( 'static', 'Static_Command' );
}

Tác dụng của đoạn script này là nó tạo ra 1 lệnh WP-CLI, cụ thể là wp static run (khi chạy nó sẽ gọi run_static_export từ Simply Static để tạo toàn bộ các trang tĩnh

Tiếp theo xử lý hơi thủ công, check thư mục /var/www/html/vercel-simply-static sau mỗi 5s, khi nào thấy có file mới tạo ra nghĩa là quá trình Simply Static tạo file tĩnh đã xong, để chắc cú tránh các vấn đề khi Simply Static chép file sang, bổ xung $stable_time, kiểm tra nếu không có file mới thêm sau 5s tiếp theo, đảm bảo hạn chế các sai sót, check nhầm

Phần này giải thích thêm, mọi người chỉ cần đổi phần thư mục như chú ý ở trên là đủ

Công đoạn tiếp theo là chuyển đống file html tại /vercel-simply-static sang dịch 1 vụ hỗ trợ static file nào đó tùy thích, Github Pages, Cloudflare Pages, Render, Vercel, Kinsta …. đợt này mình đổi sang dùng trên Vercel, cho vui thôi 😛

Vercel Static Site

Tạo tại khoản Vercel nếu chưa có, tạo xong thì lấy tokens

2024 08 17 23 46 51

Phần này đi lướt vì đơn giản lắm, ấn vào là xong

Cấu hình docker cho Vercel

Chạy qua docker, ở chế độ idle, container vercel dùng tầm 2MB RAM, 0% CPU, theo mình nên dùng cho khỏe, đỡ phải cài đặt nhiều thứ lỉnh kỉnh trên VPS gốc

  • Tạo 1 thư mục mới tuỳ thích, có thể đặt tên là vercel cho dễ nhớ, bên trong tạo 1 file compose.yml, điền nội dung bên dưới vào
services:
  vercel:
    image: dockette/vercel
    container_name: vercel
    user: "0"  # Chạy container với user root
    command: sh -c "vercel -t Tokens_KEY --yes --prod && tail -f /dev/null"
    working_dir: /static.bibica.net
    volumes:
      - /home/bibica.net/www/vercel-simply-static:/static.bibica.net
  • Thay Tokens_KEY bằng tokens của bạn
  • working_dir: đặt cho trang nào thì tạo tên thư mục cho dễ nhớ 1 chút
  • /home/bibica.net/www/vercel-simply-static: đường dẫn trực tiếp tới thư mục chứa file tĩnh trên VPS được tạo ra bởi Simply Static ở trên, thay bằng đường dẫn trực tiếp tới thư mục /vercel-simply-static trên VPS của bạn

Tiếp theo khởi động container bằng lệnh

docker compose up -d

Nó sẽ tự deploying, building … thư mục /home/bibica.net/www/vercel-simply-static thành project có tên static.bibica.net lên Vercel

2024 08 18 00 00 12

  • Lúc này bạn có thể đi tới Settings -> Domains, tạo các subdomain, domain tuỳ thích (static.bibica.net chẳng hạn)

2024 08 22 23 49 29

Do mình build từ server US, có vẻ mặc định Vercel dùng location gần nhất chứa file, ban đầu nó chạy ở location US, có thể vào Function Region đổi về Singapore, khách truy cập từ Việt Nam vào ổn định hơn, thực ra location nào cũng không quan trọng lắm, bản thân các dịch vụ static file họ cũng cache sang mọi location khác, ở đâu vào cũng nhanh cả, phần này mình làm thêm cho chắc kèo là chính

  • Từ lúc này trở đi, mỗi khi Simply Static tạo các file tĩnh mới, cần chạy lại container vercel để cập nhập dữ liệu mới lên Vercel lại (dùng stop -> start cũng được, do mặc định mình đã set sẵn mỗi lần khởi động container là tự build mới)

Có thể đổi sang dùng images bên dưới, mình xoá cài đặt rác còn sót từ bản gốc, dung lượng images nhỏ xuống 1 chút 😀 chủ yếu tạo riêng 1 bản images dùng cho an tâm, tránh tình huống tác giả xóa, sửa images gốc

  • image: dockette/vercel đổi lại thành image: bibica/vercel-cloudflare-pages-minimal

Tự động cập nhập hàng ngày

Các bước làm mệt mỏi nhất đã xong, giờ chỉ việc tự cập nhập mỗi ngày, tạo 1 bash script chạy tuần tự các lệnh

1. Tạo trang tĩnh: dùng WP-CLI đã tạo ra ở trên

wp static run

2. Upload các file lên Vercel

# Khởi động lại vercel
docker stop vercel
docker start vercel
  • Bash file hoàn chỉnh mình đang sử dụng, mọi người có thể tham khảo, bổ xung kiểm tra thời gian chạy toàn bộ các lệnh, sau khi xong thì gửi thông báo qua Telegram, hôm nào thấy chạy chậm quá thì vào theo dõi lại
#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

start=`date +%s`

# Sử dụng WP-CLI fake để tạo các file tĩnh
mkdir -p /home/bibica.net/www/vercel-simply-static
chown -R 82:82 /home/bibica.net/www/vercel-simply-static
docker exec --user 82 wordpress.bibica.net bash -c "wp static run"

# Khởi động lại vercel cho bibica.net
docker stop vercel.bibica.net
docker start vercel.bibica.net

end=`date +%s`
runtime=$((end-start))

# Set up Telegram bot API and chat ID
BOT_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
CHAT_ID="xxxxxxxxxxxx"

MESSAGE="Đã tạo trang tĩnh cho static.bibica.net, tổng thời gian: $runtime giây"
curl -s -X POST https://api.telegram.org/bot$BOT_API_KEY/sendMessage -d chat_id=$CHAT_ID -d text="$MESSAGE"
  • crontab -e, tạo 1 lệnh cron chạy lúc 3h sáng mỗi ngày
# Chạy Simply Static và Vercel lúc 3 giờ sáng mỗi ngày
0 3 * * * /home/backup/vercel-simply-static.sh

Giới hạn của Vercel

Giới hạn đầu tiên bạn cần biết, Vercel chỉ cho phép upload 5000 file mỗi ngày, với cách mình đang cấu hình cho thèng bibica.net, hình ảnh dùng thông qua Jetpack, toàn bộ trang tạo ra khoảng 760 files, quy đổi đơn giản thì mỗi ngày mình có thể cập nhập mới khoảng 6 lần, đa phần mình cho chạy auto, 1 ngày 1 lần nên con số này cũng khá rủng rỉnh, trong trường hợp cụ thế nào đó, 1 ngày cần tạo mới liên tục, đạt mức giới hạn upload file, có thể tạo thêm 1 tài khoản khác, thời gian để domain cập nhập lại DNS mất tầm 5-10 phút

Băng thông họ cho 100GB 1 tháng, để làm trang dạng backup như mình thì thừa, về space mình nhớ được đâu 23GB, max file 100MB, chắc dùng không hết nổi để mà phải nhớ các thông tin này

So với các dịch vụ như Cloudflare Pages mình dùng trước đây, giới hạn của họ khá Vercel, Cloudflare Pages mình dùng nhiều tới mức hiện tại có 1 project mà Cloudflare không xoá nổi, vì nhiều file quá, Cloudflare nói xoá thủ công đi =))

Vercel upload file lên rất tiện, cứ nguyên thư mục ném thẳng, không cần cấu hình thêm gì lằng nhằng, nhu cầu hiện tại của mình là đủ dùng

Kết luận

Cấu hình toàn bộ theo bài này theo mình là hơi phức tạp, nhất là phần tạo command cho file compose.yml, do gắn 1 thư mục vào 2 container, nên nó bị đụng quyền user qua lại điên cuồng, 1 thèng dùng user 1000, 1 thèng dùng user www-data, thêm nữa không hiểu sao cái container vercel, cứ bật chạy xong là tự tắt, lú người luôn, may sao cũng xử lý được =))

Thật ra vẫn có nhiều giải pháp khác hợp lý hơn, kiểu tách riêng thành 2 thư mục, sau khi Simply Static tạo file tĩnh xong thì copy sang thư mục riêng của Vercel, sau đó chmod về 1000 rồi build mới, sẽ không gặp vấn đề và cũng không cần phân quyền root cho container vercel như trong bài, mặc định thì không nên và hạn chế tối đa chạy quyền root bên trong container, nó không hợp lý về mặt bảo mật … có điều bản images đó nó cũng chỉ chạy lệnh đồng bộ file tĩnh lên Vercel, mình nghĩ đủ ổn, chính nhất là làm xong mình lười sửa lại các câu lệnh 😛

Cấu hình WordPress chạy Simply Static cũng phải phù hợp, ảnh nên dùng thông qua 1 dịch vụ khác như Jetpack, còn dùng link ảnh trực tiếp dạng domain.com/wp-content/uploads/, mỗi bài viết sẽ chuyển đủ các images sang trang tĩnh, 400-500 bài viết là 5000-10.000 file, chuyển hết lâu lắm

Về hiệu quả cách này có thể áp dụng được trên bản Simply Static miễn phí, hạn chế các lỗi upload (nếu có) từ Github, tổng thời gian hoàn thành nhanh hơn so với trước đây, ~4-5 phút hiện tại (>8 phút trước đây)

Nếu dùng Simply Static Pro, sẽ có nhiều tính năng hữu ích khác, như tạo form contact, comment, search hay chỉ tạo trang tĩnh cho 1 bài viết cụ thể, bạn nào thích tạo 1 trang tĩnh hoàn chỉnh có thể trải nghiệm thử


Related Posts

Chính sách bình luận: Chúng tôi rất trân trọng các bình luận của bạn và cảm ơn thời gian bạn dành để chia sẻ ý tưởng và phản hồi.
Ghi chú: Những bình luận được xác định là spam hoặc chỉ mang tính quảng cáo sẽ bị xóa.

• Để cải thiện trải nghiệm bình luận, chúng tôi khuyến khích bạn tạo một tài khoản Gravatar. Thêm avatar vào tài khoản Gravatar sẽ giúp bình luận của bạn dễ nhận diện hơn đối với các thành viên khác.

✂️ Sao chép và 📋 Dán Emoji 💪 giúp bình luận thêm sinh động và thú vị!