# Cron job

> Chạy script PHP, WP-CLI, Laravel scheduler, script Node.js hay bất kỳ lệnh nào theo lịch bằng tài khoản hosting, nhận kết quả qua e-mail hoặc file log.

Source: https://zopanel.net/vi/docs/cron-jobs  
Updated: 2026-10-09

**Cron Job** chạy lệnh theo lịch bằng tài khoản hosting: Laravel scheduler mỗi phút, xuất dữ liệu hằng đêm, script PHP gửi nhắc nhở. Mỗi tài khoản có danh sách riêng. Dịch vụ cron của hệ thống giữ lịch (trong `/etc/cron.d/zopanel-<user>`) và khởi chạy từng job bằng tài khoản đó, với quyền của nó, bên trong slice của tài khoản: giới hạn CPU, RAM và số tiến trình của gói áp dụng cho cron job giống như cho website.

## Ai được dùng

Khách hàng quản lý cron job của tài khoản mình. Reseller và quản trị viên chọn tài khoản ở ô chọn phía trên trang. Thành viên website không có quyền truy cập.

| Giới hạn | Giá trị |
| --- | --- |
| Số cron job mỗi tài khoản | Theo giới hạn **Cron Job** của gói (0 = không giới hạn). Gói `Default` do trình cài đặt tạo cho phép 20. |
| Tính năng | Gói có thể bỏ **Cron job**; khi đó khách hàng nhận lỗi "this feature is not included in your hosting package". |
| Độ dài lệnh | 1.024 ký tự, trên một dòng. |
| Ghi chú | 200 ký tự. |

Xem [Gói hosting và giới hạn](/vi/docs/packages-limits).

## Tạo cron job

1. Vào **Cron Job** trên menu. Quản trị viên và reseller: chọn tài khoản.
2. Bấm **Thêm cron job**.
3. Chọn **Tần suất**, hoặc **Tuỳ chỉnh** để tự nhập lịch (xem bên dưới).
4. Kiểm tra ô **Lịch chạy**. Ô này hiển thị biểu thức năm trường của tần suất đã chọn.
5. Nhập **Lệnh**, dùng đường dẫn tuyệt đối (xem [Lệnh](#lenh)).
6. Có thể thêm **Ghi chú** để nhớ job làm gì.
7. Bấm **Lưu**. Lịch được cập nhật ngay.

Để sửa, bấm biểu tượng bút chì, chỉnh trong **Sửa cron job** rồi bấm **Lưu**. Công tắc **Bật** tạm dừng job mà không xoá. Biểu tượng thùng rác xoá job sau khi xác nhận **Xoá cron job này?**.

## Cú pháp lịch chạy

Lịch chạy gồm năm trường, cách nhau đúng một dấu cách:

```text
┌───────── phút (0-59)
│ ┌─────── giờ (0-23)
│ │ ┌───── ngày trong tháng (1-31)
│ │ │ ┌─── tháng (1-12)
│ │ │ │ ┌─ thứ trong tuần (0-7, 0 và 7 là Chủ nhật)
│ │ │ │ │
* * * * *
```

Mỗi trường nhận số và các ký hiệu `*` (mọi giá trị), `,` (danh sách), `-` (khoảng), `/` (bước nhảy). Không dùng được tên như `MON` hay `JAN`.

| Tần suất | Lịch chạy |
| --- | --- |
| **Mỗi phút** | `* * * * *` |
| **Mỗi 5 phút** | `*/5 * * * *` |
| **Mỗi giờ** | `0 * * * *` |
| **Mỗi ngày (00:00)** | `0 0 * * *` |
| **Mỗi tuần (Chủ nhật)** | `0 0 * * 0` |
| **Mỗi tháng** | `0 0 1 * *` |
| Mỗi 15 phút | `*/15 * * * *` |
| 03:30 hằng ngày | `30 3 * * *` |
| 2 giờ một lần vào ngày thường | `0 */2 * * 1-5` |
| Ngày 1 và 15 hằng tháng lúc 06:00 | `0 6 1,15 * *` |

Các dạng viết tắt `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly` và `@reboot` cũng được chấp nhận. Giờ tính theo múi giờ của server.

**Lưu ý:** khi giới hạn cả ngày trong tháng lẫn thứ trong tuần (cả hai đều khác `*`), cron chạy job khi một trong hai khớp.

## Lệnh

Lệnh chạy bằng `/bin/bash`, dưới quyền tài khoản hosting, bắt đầu ở thư mục home (`/home/<tài-khoản>`, `~` cũng chỉ thư mục này). `PATH` chỉ gồm `/usr/local/bin:/usr/bin:/bin`, nên hãy ghi đường dẫn đầy đủ tới chương trình và file.

**Quan trọng:** lệnh không được chứa xuống dòng hay ký tự `%` (cron coi `%` là xuống dòng). Với lệnh dài, hoặc cần `date +%F`, hãy viết vào một script rồi chạy script đó:

```bash
bash /home/alice/scripts/nightly.sh
```

### PHP

Dùng đúng phiên bản PHP của website, ví dụ `/usr/bin/php8.3`:

```bash
/usr/bin/php8.3 /home/alice/domains/example.com/public_html/cron.php
```

### WordPress (WP-CLI)

wp-cli được cài tại `/usr/local/bin/wp`. Chạy bằng phiên bản PHP của website và chỉ rõ thư mục:

```bash
/usr/bin/php8.3 /usr/local/bin/wp --path=/home/alice/domains/example.com/public_html transient delete --expired
```

Với tác vụ định kỳ của chính WordPress, đừng thêm cron job: xem [Tác vụ định kỳ của WordPress](#tac-vu-dinh-ky-cua-wordpress).

### Laravel scheduler

Laravel cần một dòng chạy `schedule:run` mỗi phút (lịch `* * * * *`):

```bash
cd /home/alice/domains/example.com/public_html && /usr/bin/php8.3 artisan schedule:run >> /dev/null 2>&1
```

Với website Laravel deploy từ Git, dùng thư mục bản đang chạy `domains/<tên-miền>/current` thay cho `public_html`. Xem [Deploy từ Git](/vi/docs/git-deploy).

### Node.js

Node.js không nằm trong `PATH` của cron. Dùng đường dẫn đầy đủ của phiên bản đã cài trong `/opt/zopanel/runtimes/node/<major>/bin`:

```bash
cd /home/alice/scripts && /opt/zopanel/runtimes/node/22/bin/node report.js
```

### Gọi một URL

```bash
curl -fsS --max-time 60 https://example.com/tasks/run > /dev/null
```

Chạy script trực tiếp bằng PHP thường tốt hơn: không bị giới hạn thời gian của web server và không chiếm PHP worker dành cho khách truy cập.

## Kết quả và log

Panel không lưu lịch sử chạy. Hãy chọn nơi nhận kết quả:

- **Gửi kết quả qua e-mail:** ở đầu trang, nhập địa chỉ và bấm **Lưu**. Mọi thứ job in ra (đầu ra chuẩn và lỗi) được gửi tới địa chỉ này sau mỗi lần chạy. Thiết lập áp dụng cho mọi job của tài khoản. Để trống nếu muốn bỏ qua kết quả. Việc gửi cần server có mail server hoạt động (xem [Email](/vi/docs/email)).
- **Tắt tiếng một job:** thêm `> /dev/null 2>&1` vào cuối lệnh.
- **Ghi ra file log:** ghi nối kết quả vào một file trong thư mục `logs` của tài khoản và đọc bằng [Quản lý file](/vi/docs/file-manager):

  ```bash
  /usr/bin/php8.3 /home/alice/domains/example.com/public_html/cron.php >> /home/alice/logs/cron-example.log 2>&1
  ```

  File ghi nối sẽ lớn dần và tính vào dung lượng đĩa của tài khoản. Dùng `>` thay cho `>>` để chỉ giữ lần chạy gần nhất.

Để thử lệnh, hãy chạy một lần trong [terminal](/vi/docs/ssh-terminal) với đúng các đường dẫn đầy đủ trước khi đặt lịch.

## Tác vụ định kỳ của WordPress

WordPress có bộ lập lịch riêng (wp-cron) cho bài hẹn giờ, email cửa hàng và tác vụ của plugin. Ở tab **WordPress** của website, thẻ **Vận hành**, tuỳ chọn **Server chạy tác vụ định kỳ (5 phút/lần, không theo lượt khách)** để server chạy các tác vụ này 5 phút một lần bằng wp-cli. Tuỳ chọn này bật sẵn với WordPress do ZoPanel cài.

Các lượt chạy này dùng timer hệ thống riêng: không hiện trong **Cron Job** và không tính vào giới hạn cron job. Đừng thêm cron job gọi `wp-cron.php`, nếu không tác vụ sẽ chạy hai lần. Xem [Bộ công cụ WordPress](/vi/docs/wordpress).

## Khi tài khoản bị khoá hoặc được chuyển đến

- Khi tài khoản bị khoá, cron job không chạy. Chúng được khôi phục khi mở lại tài khoản.
- Cron job trong bản backup cPanel và DirectAdmin được nhập cùng tài khoản (tối đa 100). Xem [Chuyển sang ZoPanel](/vi/docs/migration).

## Xử lý sự cố

| Thông báo hoặc hiện tượng | Cách xử lý |
| --- | --- |
| "cron job limit reached (20)" | Gói không cho thêm job. Xoá bớt, gộp nhiều lệnh vào một script, hoặc tăng giới hạn **Cron Job** của gói. |
| "schedule must have 5 fields separated by single spaces" | Dùng đúng năm trường, hoặc một dạng viết tắt `@`. |
| "invalid schedule field …" | Một trường chứa ký tự ngoài số, `*`, `,`, `-`, `/` (ví dụ `MON`). Hãy dùng số. |
| "invalid cron command (no newlines or % allowed)" | Bỏ `%` và xuống dòng: chuyển lệnh vào một script. |
| "invalid e-mail address" | Nhập một địa chỉ đơn, không có dấu cách hay dấu ngoặc kép. |
| "this feature is not included in your hosting package" | Gói không có **Cron job**. Liên hệ nhà cung cấp. |
| E-mail báo "command not found" | Dùng đường dẫn đầy đủ, ví dụ `/usr/bin/php8.3` hoặc `/opt/zopanel/runtimes/node/22/bin/node`. |
| E-mail báo "Permission denied" với một script | Chạy qua trình thông dịch (`bash script.sh`, `/usr/bin/php8.3 script.php`) hoặc cấp quyền thực thi cho script. |
| Job chạy sai giờ | Lịch tính theo múi giờ của server, không phải của bạn. |
| Không nhận được e-mail | Job không in ra gì, chưa nhập địa chỉ, hoặc server chưa có mail server hoạt động. Hãy ghi ra file log. |
| Lệnh chạy được trong terminal nhưng không chạy trong cron | Cron có `PATH` tối giản và không nạp profile của shell. Dùng đường dẫn đầy đủ và `cd` tới đúng thư mục trước. |
| Job nặng chạy chậm hoặc dừng giữa chừng ("Killed") | Cron job dùng chung giới hạn CPU, RAM và số tiến trình của gói với các website của tài khoản. Hãy chạy job nặng vào giờ vắng, chia nhỏ job, hoặc nâng giới hạn của gói. |

## Xem thêm

- [Bộ công cụ WordPress](/vi/docs/wordpress)
- [SSH và terminal](/vi/docs/ssh-terminal)
- [Deploy từ Git](/vi/docs/git-deploy)
- [Laravel](/vi/docs/laravel)
- [Gói hosting và giới hạn](/vi/docs/packages-limits)
- [Laravel Task Scheduling](https://laravel.com/docs/scheduling) và [hướng dẫn crontab(5)](https://manpages.debian.org/bookworm/cron/crontab.5.en.html)
