Composer memory limit là lỗi quen thuộc khi chạy `composer install`, `composer update` hoặc `composer require` cho dự án Laravel trên VPS và shared hosting. Thông báo thường có dạng `Allowed memory size of ... bytes exhausted`, nhưng tăng memory_limit ngay lập tức chưa chắc là cách sửa đúng. Có thể bạn đang chạy Composer 1, dùng sai PHP CLI, thiếu swap, chạy `update` thay vì `install`, hoặc một plugin/child process cần thêm tài nguyên.
Bài này trình bày quy trình xử lý theo thứ tự ít rủi ro: xác định Composer và PHP đang dùng, đọc memory limit, phân biệt `install` với `update`, thử giới hạn tạm thời có kiểm soát, kiểm tra platform requirements của Laravel và xem xét RAM/swap. Composer khuyến nghị Composer 2; tài liệu Troubleshooting chính thức cũng giải thích `COMPOSER_MEMORY_LIMIT`, `php -d memory_limit` và giới hạn của child process [1].
Đừng mặc định dùng `COMPOSER_MEMORY_LIMIT=-1` lâu dài. Hãy dùng nó như phép thử hoặc biện pháp tạm thời, sau đó tìm nguyên nhân thật: phiên bản Composer, dependency graph, PHP CLI, RAM và quy trình deploy.
1. Nhận diện đúng lỗi memory của Composer
Lỗi memory có thể xuất hiện ở nhiều bước. `composer install` đọc `composer.lock` và thường ổn định hơn; `composer update` phải giải bài toán dependency và có thể dùng nhiều memory hơn. `composer require` vừa sửa `composer.json` vừa giải dependency mới. Nếu lỗi xảy ra ở Composer nhưng PHP web vẫn hoạt động, đừng suy ra toàn bộ server thiếu RAM; CLI có thể có memory_limit khác và command có thể tạo process con.
| Thông báo hoặc triệu chứng | Khả năng cần kiểm tra | Bước đầu tiên |
|---|---|---|
| Allowed memory size exhausted | PHP CLI hoặc Composer thiếu memory | Đọc `php -r "echo ini_get('memory_limit')"` và version Composer |
| Composer 1 dùng nhiều RAM | Composer cũ | Chạy `composer --version`, lập kế hoạch nâng Composer 2 |
| Install package chậm rồi chết | Dependency graph lớn hoặc thiếu swap | Dùng lock file, verbose log và kiểm tra `free -h` |
| Web chạy nhưng SSH lỗi | CLI khác PHP-FPM | Kiểm tra `command -v php`, `php -v`, `php --ini` |
| Child process failed | Process ngoài Composer thiếu giới hạn/tài nguyên | Kiểm tra command, `proc_open`, RAM và process limit |
2. Kiểm tra PHP CLI và Composer trước khi sửa
Trên shared hosting, lệnh `php` có thể trỏ đến binary hệ thống hoặc binary trong Node/PHP environment khác với website. Trên VPS nhiều version, `php8.2`, `php8.3` và `composer` có thể không cùng một runtime. Hãy lưu output trước khi thử `-1` để biết thay đổi có tác dụng hay không.
command -v php
php -v
php --ini
php -r "echo 'memory_limit=', ini_get('memory_limit'), PHP_EOL;"
command -v composer
composer --version
composer diagnose
free -h
swapon --showComposer Troubleshooting khuyến nghị trước hết phải chạy Composer 2, tốt nhất là bản 2.2.0 trở lên theo tài liệu của Composer tại thời điểm tài liệu được cập nhật [1]. Hãy kiểm tra version thật bằng `composer --version` thay vì dựa vào phiên bản package trong trí nhớ hoặc một binary khác trên PATH.
3. Dùng composer install thay vì update khi deploy
Nếu dự án Laravel đã có `composer.lock`, production thường nên dùng `composer install` để cài đúng phiên bản đã khóa. `composer update` giải lại toàn bộ dependency graph, có thể kéo package mới và tạo áp lực memory/CPU không cần thiết trong lúc deploy. Việc update nên thực hiện ở môi trường phát triển hoặc CI, review lock file rồi đưa lock file đã kiểm tra lên production.
# production: ưu tiên lock file
composer install --no-dev --prefer-dist --optimize-autoloader
# Laravel thường chạy sau khi vendor đã sẵn sàng
php artisan optimize
# chỉ chạy update khi thật sự muốn giải dependency mới
composer update --with-all-dependencies`--no-dev` chỉ phù hợp nếu production không cần dev dependencies; hãy đối chiếu script deploy của dự án. Nếu Laravel yêu cầu extension hoặc PHP version cụ thể, chạy kiểm tra platform sau khi dependency được giải. Không xóa `composer.lock` để “né” lỗi vì cách này thường làm dependency graph lớn hơn và giảm khả năng rollback.
4. Tăng memory tạm thời bằng COMPOSER_MEMORY_LIMIT
Composer tôn trọng biến môi trường `COMPOSER_MEMORY_LIMIT`. Có thể đặt một giá trị cụ thể như `1G` hoặc `2G` cho một command, thay vì chỉnh global php.ini và ảnh hưởng mọi ứng dụng. Tài liệu Composer cũng nêu tùy chọn `-1` cho unlimited và `php -d memory_limit=-1 composer.phar`; nhưng unlimited không tạo thêm RAM vật lý và có thể khiến máy swap hoặc OOM.
# kiểm tra giá trị hiện tại
php -r "echo ini_get('memory_limit'), PHP_EOL;"
# thử mức cụ thể cho một lần chạy
COMPOSER_MEMORY_LIMIT=1G composer install --no-dev --prefer-dist
# chỉ dùng -1 như biện pháp tạm thời khi đã hiểu rủi ro
COMPOSER_MEMORY_LIMIT=-1 composer update -W
# cách tương đương với composer.phar
php -d memory_limit=2G composer.phar installSau khi command chạy xong, biến môi trường đặt ở đầu dòng sẽ không tự thay đổi php.ini global. Đây là ưu điểm cho troubleshooting. Nếu phải dùng `-1` trên máy production, nên đặt timeout, theo dõi `free -h`, `vmstat`, log kernel và có kế hoạch rollback; không nên đưa tùy chọn này vào script deploy mặc định mà không có giới hạn tài nguyên.
5. Sửa lỗi memory theo nguyên nhân, không chỉ tăng limit
Composer 1 hoặc binary cũ
Composer 1 dùng nhiều memory hơn Composer 2 theo tài liệu chính thức. Kiểm tra PATH và cập nhật binary theo phương thức phù hợp với hosting. Sau khi nâng, chạy `composer --version` và `composer diagnose` lại; không trộn file composer.phar của nhiều version trong cùng một script.
Đang chạy update trên production
Nếu có lock file, chuyển sang `composer install`. Đây là thay đổi quy trình có tác động lớn hơn việc tăng memory nhưng thường giúp kết quả deterministic, giảm thời gian giải dependency và dễ rollback. Nếu lock file cũ, cập nhật nó ngoài production rồi review thay đổi.
Thiếu RAM hoặc swap
Memory limit của PHP không đồng nghĩa với RAM vật lý. Một command có thể được phép dùng 2G nhưng server chỉ còn vài trăm MB khả dụng; kết quả là swap thrashing hoặc kernel OOM killer. Dùng `free -h`, `swapon --show`, `vmstat 1` và `dmesg`/journal phù hợp để kiểm tra. Shared hosting có thể không cho tạo swap; khi đó cần giảm workload, chạy CI bên ngoài hoặc nhờ nhà cung cấp nâng resource limit.
Sai PHP CLI hoặc extension
Composer kiểm tra platform requirements của PHP đang chạy command. `php -v` và `php --ini` có thể khác với PHP-FPM. Nếu báo thiếu `ext-mbstring`, `ext-zip` hoặc version PHP không phù hợp, sửa đúng CLI environment trước khi tăng memory. Có thể tham khảo bài [cài PHP extension trên Ubuntu] để kiểm tra package và SAPI.
6. Kiểm tra platform requirements của Laravel
Sau khi Composer xử lý memory, hãy kiểm tra dependency có phù hợp với PHP và extension trên server. Lệnh `check-platform-reqs` giúp phát hiện mismatch giữa package đã cài và runtime hiện tại. Không dùng `--ignore-platform-reqs` như cách sửa mặc định; tùy chọn này có thể làm Composer tiếp tục dù server không đáp ứng yêu cầu thực tế, dẫn đến lỗi runtime khó truy vết.
composer check-platform-reqs
composer show --platform
php -m | sort
php -r "echo PHP_VERSION, PHP_EOL;"
# xem chi tiết command khi cần
composer install -vvv --no-interactionNếu command vẫn lỗi, lưu log đầy đủ và xác định nó chết ở bước resolve, download, script hoặc child process. Composer có thể gọi Git, unzip, plugin hoặc script trong `composer.json`; tăng memory của Composer không nhất thiết sửa được lỗi từ command bên ngoài. Tài liệu chính thức cũng cảnh báo child process hoặc external command có thể cần điều chỉnh riêng [1].
7. Cache, network và thư mục vendor
Không phải lỗi nào trông giống “Composer chậm” cũng là memory. Composer có cache package; thư mục home của user có thể hết quota; `vendor` có thể có quyền sai hoặc bản cài trước dở dang. Kiểm tra disk/quota, cache và quyền trước khi xóa. Trên production, tránh xóa `vendor` giữa một deploy đang phục vụ traffic nếu chưa có bản release mới hoặc symlink rollback.
composer clear-cache
composer config --global cache-dir
df -h
# tùy hệ thống hosting
quota -s 2>/dev/null || true
ls -ld vendor
find vendor -maxdepth 1 -type d | head`composer clear-cache` có thể làm lần cài sau tải lại package và tốn network; chỉ dùng khi cache hỏng hoặc cần loại trừ cache. Một quy trình release an toàn thường cài dependency vào thư mục build riêng, chạy test/check, sau đó đổi symlink atomically và giữ release cũ để rollback.
8. Quy trình deploy Laravel ít rủi ro
- Kiểm tra Composer 2, PHP CLI, php.ini và memory_limit đang thực sự được dùng.
- Đảm bảo `composer.lock` nằm trong source và production dùng `composer install`.
- Đo RAM, swap, disk/quota trước khi bắt đầu; không đặt unlimited như mặc định.
- Thử `COMPOSER_MEMORY_LIMIT=1G` hoặc mức phù hợp trong đúng command cần chạy.
- Chạy `composer check-platform-reqs` và kiểm tra extension/PHP version.
- Build vendor và asset ở release riêng nếu có thể, rồi chạy test/health check.
- Chỉ chuyển traffic sau khi cache, queue, scheduler và quyền file đã kiểm tra.
- Ghi log version, command, memory và rollback point vào runbook.
9. Kết luận
Xử lý Composer memory limit hiệu quả là bài toán của cả dependency graph, PHP CLI, Composer version và tài nguyên máy. Bắt đầu bằng `composer --version`, `php --ini`, `ini_get`, `free -h` và lock file; sau đó áp dụng giới hạn tạm thời có kiểm soát. Khi production dùng Laravel, ưu tiên build deterministic với `composer install`, kiểm tra platform requirements và giữ một điểm rollback thay vì liên tục tăng memory hoặc dùng `--ignore-platform-reqs`.
Nguồn tham khảo
[1] Composer — Troubleshooting: Memory limit errors; [2] Composer — Basic usage.