VPSSPark 部落格
← 返回開發日記

伺服器磁碟空間滿了?一鍵清理常用快取目錄的腳本

機房手記 · 2026.07.23 · 約 11 分鐘閱讀

常見搜尋:伺服器磁碟滿了 · Linux 清理磁碟 · VPS 磁碟空間 · 一鍵清理快取腳本 (Docker · journal · apt)

機房機櫃與伺服器線纜——Linux VPS 磁碟空間與維運清理場景
磁碟告警往往是日誌、容器層與套件管理快取日積月累;先診斷再腳本清理,比慌亂 rm 可靠得多。

凌晨三點,監控告警把值班手機震醒:/ 分割區使用率 98%,MySQL 寫不進 binlog,CI 部署在 docker pull 階段直接報 no space left on device。我們連上機器跑 df -h,根分割區只剩 412MB——不是突然被駭客塞了木馬,而是三個月沒人管的日誌、Docker 層、apt 快取和 journal慢慢把 40GB 小碟吃光了。

這類故障在中小 VPS 上極其常見:套餐磁碟不大,業務卻 7×24 跑容器、拉映像檔、打日誌。手動 rm -rf 既慢又容易誤刪;更靠譜的做法是先定位大戶,再用腳本批次清理「可再生」目錄。本文把我們生產環境裡反覆用過的一鍵清理腳本整理成可複製版本,並標明哪些操作安全、哪些需要二次確認。

前提:你已有 SSH 登入權限和 sudo。若此刻已經連不上(例如 SSH 金鑰寫不進去),請先參考 Linux 伺服器 SSH 連線被拒排查指南,確認是磁碟滿導致還是網路/防火牆問題。磁碟救回來之前,別急著改 UFW 規則——先把空間騰出來,服務才能正常寫日誌。

5 分鐘
定位 + 安全清理
8+
常見快取目錄
1 條
可複製清理腳本

磁碟滿了,你會先看到什麼?

Linux 在根分割區寫滿時,表現往往很「玄學」:SSH 還能登入,但 vim 儲存不了、apt install 失敗、Docker 容器起不來、Nginx 回傳 500 且 error.log 不再增長。MySQL / PostgreSQL 可能直接唯讀或崩潰;systemd 服務反覆 restart,因為無法建立 pid 檔案或寫 socket。

第一步永遠是看掛載點,而不是猜哪個目錄「看起來大」:

快速診斷
# 各分割區剩餘空間
                df -hT

                # 根目錄下一層誰最大(可能較慢)
                sudo du -xh --max-depth=1 / 2>/dev/null | sort -hr | head -20

                # inode 用盡也會「假滿」
                df -ih

du 在檔案特別多時會掃很久;若機器已經卡死,可只對可疑路徑點查,例如 sudo du -sh /var/lib/docker /var/log /var/cache。官方 du(1) 手冊-x(不跨檔案系統)和 --apparent-size 有詳細說明——跨碟掛載時別被 du 總數誤導。

伺服器磁碟清理四步流程:df 診斷、du 定位大戶、腳本清理可再生快取、df 驗證並設定 logrotate
順序建議:先診斷再清理;清理後立刻 df 驗證,並把 logrotate / 定時任務補上,避免三個月後重演。

常見「吃碟」目錄對照表

不同業務組合不同,但下面幾類在 Ubuntu / Debian VPS 上出現頻率最高。表裡標注了是否適合腳本一鍵清——帶「謹慎」的請先確認沒有業務依賴再動。

路徑 / 來源 典型體積 可否自動清 說明
/var/lib/docker 數 GB~數十 GB 部分可 懸空映像檔、停止的容器、未用 volume;執行中容器的資料卷勿刪
/var/log/journal 1~10+ GB systemd 日誌預設無上限時膨脹極快
/var/log/*.log 數百 MB~GB 謹慎 可 truncate 或 logrotate;直接 rm 可能導致行程仍占 inode
/var/cache/apt 數百 MB~數 GB apt-get clean 安全,只刪已下載 deb 包
/tmp/var/tmp 不定 部分可 刪 7 天未存取檔案;注意是否有程式把暫存上傳放這裡
Nginx proxy_cache 數 GB 快取可重建;若你按我們 Nginx 反向代理調優 設了 cache,清完會短暫 MISS
舊核心 /boot 數百 MB apt autoremove --purge 刪舊 kernel,保留目前與上一個
core dump、崩潰轉儲 不定 /var/crash、應用目錄下的 core.*
先排除「真資料」
/home/var/lib/mysql、物件儲存掛載點或備份目錄最大,腳本清快取幫不上忙——需要歸檔、擴容或遷走冷資料。清理只能回收「可再生」空間,不能代替容量規劃。

一鍵清理腳本(可複製)

下面腳本預設乾跑(dry-run):只列印將釋放的空間與將執行的命令,加 --apply 才真正刪除。建議先 dry-run,確認輸出合理後再 apply。腳本按模組拆分,你可以註解掉不需要的部分(例如機器沒裝 Docker 就跳過 Docker 段)。

disk-cleanup.sh — 儲存為 /usr/local/sbin/disk-cleanup.sh
#!/usr/bin/env bash
                # 伺服器磁碟一鍵清理 — 僅處理可再生快取
                # 用法: sudo ./disk-cleanup.sh          # 預覽
                #       sudo ./disk-cleanup.sh --apply  # 執行
                set -euo pipefail

                APPLY=false
                [[ "${1:-}" == "--apply" ]] && APPLY=true

                log() { echo "[$(date '+%F %T')] $*"; }
                run() {
                  if $APPLY; then
                    log "EXEC: $*"
                    eval "$@"
                  else
                    log "DRY-RUN: $*"
                  fi
                }

                before=$(df -h / | awk 'NR==2 {print $3 " used, avail " $4}')
                log "Before: $before"

                # 1. apt 快取
                if command -v apt-get >/dev/null; then
                  run "apt-get clean -y"
                  run "apt-get autoremove -y --purge"
                fi

                # 2. systemd journal — 保留最近 7 天或 500MB
                if command -v journalctl >/dev/null; then
                  run "journalctl --vacuum-time=7d"
                  run "journalctl --vacuum-size=500M"
                fi

                # 3. Docker 未使用資源(不含命名 volume 內業務資料)
                if command -v docker >/dev/null && docker info >/dev/null 2>&1; then
                  run "docker system prune -af --filter 'until=168h'"
                  run "docker builder prune -af --filter 'until=168h'"
                fi

                # 4. 暫存目錄 — 7 天未存取
                run "find /tmp /var/tmp -type f -atime +7 -print 2>/dev/null | head -20"
                if $APPLY; then
                  find /tmp /var/tmp -type f -atime +7 -delete 2>/dev/null || true
                fi

                # 5. Nginx proxy_cache(依你的 cache_path 修改)
                NGINX_CACHE="/var/cache/nginx"
                if [[ -d "$NGINX_CACHE" ]]; then
                  run "du -sh '$NGINX_CACHE'"
                  run "find '$NGINX_CACHE' -type f -delete 2>/dev/null || true"
                fi

                # 6. 崩潰轉儲
                [[ -d /var/crash ]] && run "rm -rf /var/crash/*"

                # 7. pip / npm 快取(若存在)
                [[ -d /root/.cache/pip ]] && run "rm -rf /root/.cache/pip/*"
                for u in /home/*; do
                  [[ -d "$u/.npm" ]] && run "npm cache clean --force --cache '$u/.npm' 2>/dev/null || rm -rf '$u/.npm/_cacache'"
                done

                after=$(df -h / | awk 'NR==2 {print $3 " used, avail " $4}')
                log "After:  $after"
                $APPLY || log "預覽模式結束。確認無誤後: sudo $0 --apply"

賦予執行權限:sudo chmod 750 /usr/local/sbin/disk-cleanup.sh。第一次務必不加 --apply,把 DRY-RUN 輸出存一份;若 Docker 段顯示將刪除大量映像檔,確認沒有「只剩本地、倉庫已刪」的唯一副本。

Docker prune 不是萬靈丹
docker system prune -a 會刪掉所有未使用的映像檔,下次部署要重新 pull,在頻寬緊張的 VPS 上可能反而拖慢恢復。更穩妥的是加 --filter until=168h(一週未用才刪),或定期清理 dangling 映像檔:docker image prune -f。詳見 Docker 官方 pruning 文件

分模組說明:清什麼、不清什麼

journalctl--vacuum-time--vacuum-size 可組合使用,systemd 會按 journalctl 文件 規則裁剪二進位日誌。若你希望永久限制體積,在 /etc/systemd/journald.conf 裡設 SystemMaxUse=500Msystemctl restart systemd-journald

日誌檔案:對仍在被行程開啟的大日誌,用 truncate -s 0 /var/log/nginx/access.logrm 安全——行程仍持有 fd,rm 只刪目錄項,空間不會立刻釋放。長期應配 logrotate,讓 Nginx / 應用日誌按天切割並保留 N 份。

aptapt-get clean 只清 /var/cache/apt/archivesautoremove --purge 會刪舊核心和孤兒依賴。升級核心後建議保留「目前 + 上一版」兩個 kernel,防止新核心啟動失敗時無法回退。

業務資料別碰/var/lib/mysql/var/lib/postgresql、Redis RDB、使用者上傳目錄、備份掛載點——這些不在腳本預設範圍內。若 du 顯示它們最大,需要的是歸檔、擴容或遷冷儲存,而不是清快取。

清理之後:別讓磁碟再次悄悄滿

救急腳本跑完,根分割區從 98% 降到 60% 只是開始。我們給中小 VPS 的最低配預防是三件事:

  • 監控閾值:雲端廠商或自建 Prometheus 在 80% 告警,85% 發簡訊——別等 95% 才有人看。
  • 每週 cron0 4 * * 0 root /usr/local/sbin/disk-cleanup.sh --apply >> /var/log/disk-cleanup.log 2>&1
  • journald + logrotate 上限:把「無限增長」改成「有頂的天花板」。

若跑 Docker Compose 堆疊,給 json-file 日誌加 max-sizemax-file,否則單個容器的 stdout 就能把碟寫滿——這和清映像檔一樣重要,卻常被忽略。

小碟 VPS 的容量心態
40GB 套餐跑 Web + DB + Docker 並不寬裕。把靜態資源放物件儲存或 CDN、資料庫 binlog 定期歸檔、CI 建置放獨立 Runner——比每個月手動救急更省心。磁碟是便宜資源,但維運時間不是。

上線前檢查清單

把下面幾條抄進你的維運筆記,下次告警來時按順序打勾:

  • df -hTdf -ih — 確認是空間滿還是 inode 滿
  • du -sh 點查 docker、journal、log、cache 目錄
  • 腳本 dry-run → 人工掃一眼 → --apply
  • 清理後 df -h 驗證,並抽查核心服務(DB、Nginx、Docker)是否正常
  • 補 journald 限制、logrotate、cron 與 80% 告警

磁碟滿從來不是「刪幾個檔案」就結束的維運事件,而是一次容量與日誌策略的體檢。腳本負責把你在凌晨三點的手速從「慌亂 rm」拉回到「可重複的標準流程」——剩下的,是把預防補上,讓告警少響幾次。

開發建置占滿磁碟?考慮分工部署

若你的 VPS 既要跑生產服務,又要本地 xcodebuild、Docker 多層建置或 Ollama 模型快取,小碟很容易在編譯週被 DerivedData 和映像檔層擠爆。更穩妥的做法是生產 VPS 保持精簡,把重建置遷到專用環境——例如雲端 Mac 跑 iOS 出包、獨立 Runner 跑 CI,生產機只拉最終產物。

Mac mini M4 憑藉統一記憶體與低功耗,適合作為「只幹建置、不扛 7×24 業務流量」的節點;與 Linux VPS 分工後,生產碟只留執行時資料,編譯快取不再和生產日誌搶同一塊 SSD。

如果你正在規劃「生產機瘦身 + 建置環境分離」,可以先把重活遷到雲端 Mac,讓 VPS 回歸輕量維運——了解 VPSSPark 套餐,少在凌晨三點和 df -h 搏鬥。

限時特惠

建置占滿磁碟?把重活遷出生產 VPS

雲 Mac 跑編譯出包 · Linux VPS 專注執行時 · 分工少救急

返回首頁
限時特惠 點擊查看方案