Docker Compose运行WordPress磁盘爆满及日志限制问题排查
先明确两个高占用Docker目录的作用:
/var/lib/docker/overlay2是Docker默认overlay2存储驱动的根目录,存放所有镜像分层、容器运行时可写层的所有数据,只要是正在运行的容器关联的这部分数据,docker system prune不会做任何清理,你之前执行prune返回0B就是因为所有可清理的无用镜像、停止容器已经被清完了,剩下的都是运行中业务正在使用的数据。/var/lib/docker/containers/<容器ID>/<ID>-json.log是Docker默认的JSON格式日志存储路径,容器内输出的所有标准输出、标准错误日志都会持续写入这个文件,默认没有任何大小限制。你找到的17GB超大日志文件,就是磁盘空间被快速占满的直接原因——你之前重启容器、临时prune只能短暂释放运行时缓存,日志一直在无限制写入,几小时就能再次把剩余空间写满,导致媒体上传、内容编辑功能失败。
不需要重启服务,直接执行命令清空超大日志即可立刻回收空间:
# 注意:不要直接用rm删除日志文件,会导致Docker持有文件句柄不释放,磁盘空间无法真正回收 truncate -s 0 /var/lib/docker/containers/*/*-json.log
执行完成后用df -h查看磁盘占用,就能看到空间已经释放,业务功能恢复正常。
1. 全局配置Docker默认日志轮转规则
修改Docker守护进程配置,给所有后续新建的容器默认加上日志大小限制,从根源避免日志无限增长:
- 编辑(文件不存在则新建)
/etc/docker/daemon.json,写入以下配置:
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }
配置含义:单个容器的日志文件最大为100MB,最多保留3个轮转后的历史日志文件,单个容器日志最多占用300MB空间,不会再出现十几GB的超大日志文件。
2. 重载配置并重启Docker让全局规则生效:
sudo systemctl daemon-reload sudo systemctl restart docker
注意:全局配置仅对规则生效后新创建的容器生效,已经存在的运行中容器需要重建才会应用规则。
2. 更新docker-compose配置,重建现有容器
在你当前的docker-compose.yml中,给每个服务单独加上日志配置,确保现有容器也应用日志轮转规则,修改后的完整配置如下:
services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: xx MYSQL_DATABASE: xx MYSQL_USER: xx MYSQL_PASSWORD: xx logging: driver: "json-file" options: max-size: "100m" max-file: "3" wordpress: depends_on: - db image: wordpress:latest volumes: - wordpress_data:/var/www/html - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini - ./my_theme:/var/www/html/wp-content/themes/my_theme ports: - "80:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: xx WORDPRESS_DB_PASSWORD: xx WORDPRESS_DB_NAME: xx logging: driver: "json-file" options: max-size: "100m" max-file: "3" phpmyadmin: image: corbinu/docker-phpmyadmin links: - db:mysql ports: - 8181:80 environment: MYSQL_USERNAME: xx MYSQL_ROOT_PASSWORD: xx MYSQL_PORT_3306_TCP_ADDR: db logging: driver: "json-file" options: max-size: "100m" max-file: "3" volumes: db_data: {} wordpress_data: {}
配置修改完成后,在docker-compose.yml所在目录执行以下命令重建容器,所有存储在数据卷里的WordPress内容、数据库数据不会丢失,业务只会有几秒的中断:
docker-compose up -d --force-recreate
3. 冗余服务清理
你之前的临时修复命令里有停止apache2的操作,说明宿主机上安装并运行了apache2服务,而你的WordPress容器本身已经自带了web服务监听80端口,宿主机的apache2不仅多余,还可能和容器产生端口冲突,直接关闭并禁用即可:
sudo systemctl stop apache2 sudo systemctl disable apache2
如果日志问题修复后,/var/lib/docker/overlay2目录还是出现异常的空间增长,执行以下命令定位具体是哪个容器的可写层占用过高:
docker ps -q | xargs docker inspect --format='{{.Id}} {{.Name}} {{.GraphDriver.Data.WorkDir}}' | while read cid cname cworkdir; do csize=$(du -sh $(dirname $cworkdir) 2>/dev/null | awk '{print $1}') echo "$csize $cname $cid" done
定位到高占用容器后,进入容器检查是否是业务产生的临时文件、缓存未定期清理,比如WordPress缓存插件生成的冗余缓存、PHP临时文件、MySQL慢查询日志等,针对性配置清理规则即可。
- 不要频繁执行
docker system prune --all,该命令会删除所有未被运行中容器关联的镜像,下次启动容器需要重新拉取镜像,既浪费带宽也无法解决运行中容器产生的磁盘占用问题。 - 你之前使用的
docker kill $(docker ps -q)加大范围prune的操作会强制中断所有运行业务,配置完日志轮转后不需要再执行这类破坏性操作。
服务器空间占用情况截图:
Screenshot
内容的提问来源于stack exchange,提问作者Jonas Schmitt

