- Headless Codex CLI cho phép task chạy không cần terminal interactive, lý tưởng cho VPS qua đêm.
- Tmux giữ session sống ngay cả khi bạn đóng SSH, đảm bảo task không bị kill.
- Script wrapper với retry logic xử lý rate limit và lỗi tạm thời.
- Telegram bot hoặc webhook gửi notification về máy chính khi task xong/lỗi.
- Log monitoring giúp debug khi task fail mà bạn đang ngủ.
Dev solo nhưng muốn output như team 3 người? Một chiến thuật mạnh là để Codex CLI chạy task lớn qua đêm trên VPS. Bạn đi ngủ lúc 11h, Codex code đến 6h sáng, ngủ dậy review diff, accept nếu OK, merge. Tăng productivity gần gấp đôi mà không tăng giờ làm.
Bài này hướng dẫn dựng workflow headless ổn định cho Codex CLI: tmux setup, script wrapper xử lý rate limit, notification về máy chính, và monitoring để biết task fail giữa đêm. Tất cả setup 1 lần, dùng được hàng tháng.
Workflow này không phụ thuộc version Codex CLI cụ thể. Khi OpenAI update tool, các bước về tmux, wrapper, log vẫn áp dụng được. Chỉ syntax flag CLI có thể thay đổi nhỏ.
Tại sao headless là game changer cho dev solo
Dev solo có lợi thế tốc độ quyết định nhưng giới hạn thời gian làm việc trong ngày. Headless Codex CLI mở ra "ca 2" - 8 tiếng đêm Codex tự code, bạn ngủ. Nếu mỗi task qua đêm hoàn thành tương đương 4-6 tiếng work, bạn effectively có 12-14 tiếng productivity/ngày mà chỉ tốn 8 tiếng tỉnh táo.
Tất nhiên Codex không thay thế bạn 100%. Quality task qua đêm thường ở 70-85% so với bạn làm trực tiếp. Nhưng đối với task lặp đi lặp lại (viết test, refactor cơ học, generate migration), 70-85% là quá đủ. Bạn chỉ review và fix phần khó là xong.
Loại task phù hợp qua đêm:
- Viết unit test cho module 20-50 file.
- Refactor cơ học (đổi naming convention, migrate API version).
- Generate documentation từ code (JSDoc, docstring).
- Bulk migration script (database schema, file format).
- Lint fix toàn bộ codebase theo convention mới.
- Generate boilerplate cho CRUD operations.
Loại task KHÔNG phù hợp qua đêm (cần bạn review giữa từng quyết định):
- Thiết kế architecture mới.
- Debug bug khó với context production.
- Refactor đụng business logic phức tạp.
- Security-critical code (auth, payment).
- Database migration có nguy cơ data loss.
Setup tmux cho session always-on
Tmux là backbone của headless workflow. Nó giữ shell session sống ngay cả khi SSH connection đóng. Lúc sáng dậy bạn SSH lại, attach tmux, thấy task tiếp tục từ điểm dở.
# Cài tmux nếu chưa có
sudo apt install -y tmux
# Tạo tmux config nhẹ ở $HOME/.tmux.conf
cat > $HOME/.tmux.conf
Trong editor, paste config tối thiểu:
set -g history-limit 50000
set -g mouse on
set -g default-terminal "screen-256color"
set -g status-left-length 30
set -g status-right "#(date +%%Y-%%m-%%d_%%H:%%M)"
# Vim-style pane navigation
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
Save và reload tmux. History 50k dòng đủ để xem lại output Codex sau đêm dài. Mouse on giúp scroll qua output dễ.
Cấu trúc session tmux cho workflow đêm
Mình recommend chia tmux thành nhiều window theo concern:
# Tạo session với 3 window
tmux new -d -s night-shift -n codex
tmux new-window -t night-shift -n logs
tmux new-window -t night-shift -n monitor
# Window 1 (codex): Codex CLI chạy task
tmux send-keys -t night-shift:codex "cd $HOME/projects/main && codex" Enter
# Window 2 (logs): tail log realtime
tmux send-keys -t night-shift:logs "tail -f $HOME/.codex/logs/latest.log" Enter
# Window 3 (monitor): htop hoặc btop
tmux send-keys -t night-shift:monitor "htop" Enter
# Attach để xem
tmux attach -t night-shift
Switch giữa window bằng Ctrl+B sau đó số (1, 2, 3). Detach: Ctrl+B D. Session vẫn chạy nền.
Script wrapper với retry logic
Codex CLI có thể bị throttle khi quá quota tier. Khi headless, gặp lỗi sẽ exit và task dừng. Script wrapper retry tự động sau khi đợi rate limit window reset.
#!/usr/bin/env bash
# $HOME/bin/codex-night.sh
set -e
LOG=$HOME/.codex/logs/night-$(date +%F).log
RETRY_MAX=5
RETRY_WAIT=1800 # 30 phút
run_task() {
local task=$1
local retry=0
while [ $retry -lt $RETRY_MAX ]; do
echo "[$(date)] START: $task" >> $LOG
if codex exec "$task" >> $LOG 2>&1; then
echo "[$(date)] OK: $task" >> $LOG
return 0
fi
# Check log có phải rate limit không
if tail -50 $LOG | grep -qi "rate limit|too many request|quota"; then
retry=$((retry+1))
echo "[$(date)] THROTTLE retry $retry/$RETRY_MAX, sleep $RETRY_WAIT" >> $LOG
sleep $RETRY_WAIT
else
# Lỗi khác, không retry
echo "[$(date)] FATAL: $task" >> $LOG
return 1
fi
done
echo "[$(date)] FAIL after $RETRY_MAX retries: $task" >> $LOG
return 1
}
# Danh sách task đêm
TASKS=(
"viết unit test cho src/services/auth.ts dùng vitest"
"viết unit test cho src/services/billing.ts dùng vitest"
"refactor src/lib/utils.ts: tách functions trên 50 dòng ra file riêng"
"thêm JSDoc cho mọi export trong src/lib/"
)
for task in "${TASKS[@]}"; do
run_task "$task" || echo "Task failed: $task" >> $LOG
done
echo "[$(date)] NIGHT SHIFT DONE" >> $LOG
chmod +x script và run trong tmux. Output ghi vào log file riêng theo ngày. Sáng dậy chỉ cần xem log thấy task nào OK, task nào FAIL.
Notification Telegram khi task xong hoặc lỗi
Đợi sáng mới biết task xong hay lỗi là chậm. Telegram bot push notification về điện thoại ngay khi có event giúp bạn xử lý sớm nếu cần thiết.
- Tạo bot bằng @BotFather trên Telegram, lấy BOT_TOKEN.
- Lấy CHAT_ID bằng cách gửi message cho bot rồi gọi getUpdates API.
- Save token + chat_id vào $HOME/.codex/secrets/telegram.env (chmod 600).
- Source file env trong .bashrc để các script đọc được.
#!/usr/bin/env bash
# $HOME/bin/notify.sh
TOKEN="${TELEGRAM_BOT_TOKEN}"
CHAT_ID="${TELEGRAM_CHAT_ID}"
MSG="$1"
curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage"
-d "chat_id=${CHAT_ID}"
-d "text=${MSG}"
-d "parse_mode=Markdown" > /dev/null
Trong codex-night.sh, thêm gọi notify sau mỗi task quan trọng:
run_task "$task"
&& $HOME/bin/notify.sh "OK: $task"
|| $HOME/bin/notify.sh "FAIL: $task"
Sáng dậy nhìn Telegram là biết đêm qua như thế nào. Nếu có task FAIL quan trọng, bạn có thể xử lý ngay không phải đợi SSH check.
Cron schedule task định kỳ
Nếu task lặp đi lặp lại hằng đêm (vd: chạy linter, generate doc, sync data), cron là cách clean nhất. Khác với tmux interactive, cron job có thể tự khởi động không cần SSH.
# Edit crontab
crontab -e
# Thêm dòng: 11h đêm mỗi ngày
0 23 * * * /home/user/bin/codex-night.sh
# Hoặc: chỉ thứ 2 sáng cho weekly maintenance
0 2 * * 1 /home/user/bin/codex-weekly-clean.sh
# Verify
crontab -l
Cron job chạy không có terminal, nên log phải explicit. Quan trọng: trong cron môi trường ENV khá hạn chế, cần source env file đầu script để có TELEGRAM_TOKEN, PATH chứa npm-global/bin, vv.
# Đầu codex-night.sh, ensure ENV đúng cho cron
export PATH=$HOME/.npm-global/bin:/usr/local/bin:/usr/bin:/bin
source $HOME/.codex/secrets/telegram.env
source $HOME/.codex/secrets/github.env
# Sau đó mới run task
Log monitoring và debug post-mortem
Khi task fail, log là nguồn tin duy nhất bạn có. Đầu tư vào log format giúp debug nhanh sáng hôm sau.
- Mỗi entry timestamp đầy đủ (date +%FT%T%z).
- Log task name rõ ràng đầu mỗi block.
- Capture stderr cùng stdout (2>&1).
- Rotate log theo ngày để không file quá lớn.
- Backup log ra 1 thư mục riêng giữ 30 ngày.
# Log rotate đơn giản
# Trong $HOME/bin/codex-night.sh, thêm:
# Cleanup log cũ quá 30 ngày
find $HOME/.codex/logs/night-*.log -mtime +30 -delete
Sáng dậy, command kiểm tra nhanh:
# Số task OK đêm qua
grep -c "OK:" $HOME/.codex/logs/night-$(date +%F).log
# Số task FAIL
grep -c "FAIL|FATAL" $HOME/.codex/logs/night-$(date +%F).log
# Xem chi tiết task fail
grep -A 20 "FATAL" $HOME/.codex/logs/night-$(date +%F).log
# Tổng thời gian shift đêm
head -1 $HOME/.codex/logs/night-$(date +%F).log
tail -1 $HOME/.codex/logs/night-$(date +%F).log
Safety: tránh task đêm phá hỏng codebase
Đây là phần cẩn trọng nhất. Codex chạy không giám sát có thể edit nhầm hoặc commit code sai. Cần safety net.
- Luôn chạy trên branch riêng (tự tạo: night-shift-$(date +%F)), không main.
- Snapshot VPS trước khi bắt đầu shift đêm.
- Pre-commit hook chạy lint + test, fail thì không commit.
- Không cho Codex push lên remote tự động - chỉ commit local.
- Sáng review từng commit trước khi merge vào dev branch.
- CI/CD chạy test toàn bộ khi merge, catch bug Codex bỏ sót.
# Trong $HOME/bin/codex-night.sh, đầu tiên tạo branch
cd $HOME/projects/main
BRANCH="night-shift-$(date +%F)"
git checkout -b $BRANCH 2>/dev/null || git checkout $BRANCH
# Trong AGENTS.md project, hướng dẫn Codex:
# - Chỉ commit local, không push
# - Mỗi task 1 commit riêng để dễ revert
# - Sử dụng conventional commits
# Sau khi shift xong, không auto-push
# Để bạn review sáng và quyết định push
Hiệu năng tài nguyên VPS
Một concern: Codex CLI chạy 7-8 tiếng liên tục có tốn nhiều CPU/RAM không? Câu trả lời: không nhiều, vì model AI chạy ở server OpenAI, không phải VPS bạn.
- CPU: spike ngắn khi Codex run lint/test, idle khi đợi API response.
- RAM: ổn định ~500MB cho Codex + 500-1000MB cho dev tool (Node, test runner).
- Network: outgoing nhẹ (API call), incoming nhẹ (response).
- Disk I/O: tăng khi Codex edit nhiều file, không đáng kể.
VPS 2 vCPU 2GB RAM dư sức cho headless workflow này. 4GB RAM mới cần khi project lớn (đặc biệt Node.js monorepo với nhiều dependency). Network bandwidth không phải vấn đề trừ khi clone repo lớn.
Combo workflow: shift đêm + reviewing sáng
Workflow điển hình của dev solo dùng headless:
- 10h tối: chuẩn bị task list, push lên repo, tạo task file trên VPS.
- 10h30: SSH vào VPS, start tmux session, run codex-night.sh.
- 11h: đi ngủ, tin tưởng vào Codex.
- 7h sáng: dậy, xem Telegram notification.
- 7h30: SSH vào VPS, attach tmux, review log đêm qua.
- 8-10h: review từng commit Codex tạo, accept/reject.
- 10h: merge branch night-shift vào dev, push lên remote.
- 10-12h: code task khó cần bạn xử lý trực tiếp.
- Chiều: meeting, review code đồng nghiệp, etc.
- Tối: lập task list cho đêm mới.
Workflow này dùng ổn ~6-9 tháng đầu thấy tăng productivity 30-50% so với không có headless. Sau đó bạn calibrate được loại task nào hợp đêm, loại nào không, hiệu quả còn tăng tiếp.
FAQ về headless Codex CLI
Tier nào của Codex CLI hỗ trợ headless tốt nhất?
Pro hoặc Business hỗ trợ tốt nhất vì quota cao, ít bị throttle giữa task đêm. Plus có thể chạy headless nhưng task dài có khả năng bị gián đoạn. Nếu workflow chính là headless, đầu tư Pro là cần thiết.
Tmux có cần thiết hay dùng nohup đủ?
Tmux better vì cho phép attach lại xem state realtime. Nohup chỉ giữ process chạy, không thấy output. Cho debug và monitor, tmux mạnh hơn nhiều. Setup tmux mất 5 phút 1 lần, hiệu quả về sau lâu dài.
Có thể chạy nhiều task song song trong 1 đêm không?
Sequential an toàn hơn vì tránh xung đột file edit. Nếu task hoàn toàn độc lập (vd 2 module riêng biệt), có thể chạy 2 tmux window riêng, mỗi window 1 Codex session. Nhưng tốn 2 lần quota, cẩn thận với rate limit.
Codex có push code tự động lên GitHub không?
Tuỳ cấu hình. Mặc định Codex chỉ commit local. Có thể bảo Codex push, nhưng KHÔNG nên cho headless vì code chưa review. Practice tốt: cho Codex commit local, sáng bạn review rồi push thủ công.
Cron job có chạy ổn định không?
Có nếu setup ENV đúng. Cron chạy với PATH hạn chế, cần source env file đầu script. Test cron job bằng */5 * * * * trước, đảm bảo chạy được, rồi mới schedule giờ thật. Log đầy đủ giúp debug khi cron silent fail.
Có rủi ro Codex chạy task quá lâu tốn quota cả ngày không?
Có. Set timeout cho từng task bằng timeout command: timeout 3600 codex exec "...". Sau 1 tiếng tự kill. Cũng nên monitor quota tier - nếu Codex chạy quá lâu sẽ throttle và stop tự động. Quan trọng: đừng set retry vô hạn, max 5-10 lần là dừng.
VPS uptime cao cho shift đêm Codex CLI
Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. Uptime ổn định để task headless Codex CLI chạy qua đêm không lo gián đoạn, log đầy đủ giúp debug sáng hôm sau.
Xem 8 cấu hình Cloud VPS →


