You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose中Java容器启动失败:VM Thread创建失败(EPERM)

问题描述

尝试通过Docker Compose运行包含Java服务的多容器应用时,Next.js的web容器可正常启动,但两个Java服务初始化失败,报错信息如下:

[0.103s][warning][os,thread] Failed to start thread "VM Thread" - pthread_create failed (EPERM) for attributes: stacksize: 1024k, guardsize: 4k, detached.
Error occurred during initialization of VM
Cannot create VM thread. Out of system resources.

Docker Compose日志输出:

Attaching to compass-admin_resource_1, compass-admin_api_1, compass-admin_web_1
api_1       | [0.103s][warning][os,thread] Failed to start thread "VM Thread" - pthread_create failed (EPERM) for attributes: stacksize: 1024k, guardsize: 4k, detached.
api_1       | Error occurred during initialization of VM
api_1       | Cannot create VM thread. Out of system resources.
resource_1  | [0.046s][warning][os,thread] Failed to start thread "VM Thread" - pthread_create failed (EPERM) for attributes: stacksize: 1024k, guardsize: 4k, detached.
resource_1  | Error occurred during initialization of VM
resource_1  | Cannot create VM thread. Out of system resources.
web_1       |   ▲ Next.js 14.2.16
web_1       |   - Local:        http://af26e35c0d2b:3000
web_1       |   - Network:      http://192.168.128.4:3000
web_1       |
web_1       |  ✓ Starting...
web_1       |  ✓ Ready in 73ms

已验证主机内存和CPU资源充足、运行命令权限足够,需排查该问题的成因及解决方法。

成因分析
  • Docker容器线程数限制:即使主机资源充足,Docker默认可能给容器设置了过低的线程数阈值,JVM启动时需要创建多个核心线程(如VM Thread、GC线程等),超过容器允许的线程上限就会触发EPERM错误。
  • 主机系统线程配额不足:主机的ulimit配置(如nproc参数)限制了当前用户可创建的线程总数,若主机已运行大量进程,分配给Docker容器的线程配额会被耗尽。
  • Java镜像权限缺失:部分Java基础镜像使用非root用户运行,该用户在容器内没有足够权限创建线程,或容器未配置必要的系统能力(capabilities)。
解决方法

1. 在Docker Compose中配置容器线程限制

在docker-compose.yml的Java服务节点下添加ulimits字段,调高线程数和文件句柄限制:

services:
  api:
    image: your-java-api-image
    ulimits:
      nproc: 65535
      nofile:
        soft: 65535
        hard: 65535
  resource:
    image: your-java-resource-image
    ulimits:
      nproc: 65535
      nofile:
        soft: 65535
        hard: 65535

2. 调整主机的ulimit配置

临时生效(重启后失效)

执行命令调高当前用户的线程数上限:

ulimit -u 65535

永久生效

编辑/etc/security/limits.conf,添加以下配置:

* soft nproc 65535
* hard nproc 65535

保存后重启Docker服务:

systemctl restart docker

3. 配置Java容器的运行权限

方式A:添加系统能力(capabilities)

在docker-compose.yml中给Java服务添加线程相关的系统权限:

services:
  api:
    image: your-java-api-image
    cap_add:
      - SYS_NICE
      - SYS_RESOURCE

方式B:以root用户运行(注意安全风险)

若对容器安全性要求不高,可直接指定root用户启动Java服务:

services:
  api:
    image: your-java-api-image
    user: root

4. 调整JVM线程参数

启动Java服务时,通过JVM参数减少线程创建数量,比如限制GC线程数:

java -XX:ParallelGCThreads=2 -XX:ConcGCThreads=1 -jar your-app.jar

可将此命令写入Dockerfile的CMD/ENTRYPOINT,或在docker-compose.yml的command字段中配置。


内容的提问来源于stack exchange,提问作者이수민

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 03:27:24