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

Spring Boot+Docker环境下无法扫描COM4串口问题求助

串口扫描Docker部署问题排查思路

问题背景

Windows 11本地环境下,Spring Boot项目使用com.fazecast.jSerialComm组件可正常识别硬件所在的COM4端口,但部署到Docker后,即便在docker-compose.yml中配置了/dev/ttyS3:/dev/ttyS3等设备映射,仍无法扫描到目标端口。

排查步骤

  • 端口映射名称不匹配
    Windows串口是COMx格式,而Docker容器(通常基于Linux镜像)识别的串口为/dev/ttySx或/dev/ttyUSBx格式。本地COM4对应的容器内设备路径可能不是/dev/ttyS3,需确认映射关系:可通过Docker Desktop的「Devices」面板查看正确路径,或执行docker run --rm -it --privileged alpine ls /dev列出容器内可见设备。

  • 容器权限不足
    串口设备需要特定访问权限,默认容器权限可能不够:

    • 在docker-compose.yml的backend服务中添加privileged: true(生产环境谨慎使用,此权限极高),或添加cap_add: - SYS_RAWIO获取串口访问权限;
    • 进入容器执行ls -l /dev/ttyS3,检查当前用户是否有读写权限,必要时在Dockerfile中添加RUN chmod 666 /dev/ttyS3,或把用户加入dialout组。
  • jSerialComm兼容性问题
    jSerialComm在Linux环境下的端口扫描逻辑与Windows不同,可能无法自动识别映射的ttySx设备:

    • 尝试在代码中手动指定容器内的设备路径(如/dev/ttyS3),而非依赖自动扫描,验证是否能正常打开端口;
    • 检查jSerialComm版本,升级到最新版排查兼容性问题。
  • Docker Desktop设备访问权限
    Windows上的Docker Desktop需开启串口设备访问权限:

    • 打开Docker Desktop设置,进入「Resources」→「Devices」,确保目标串口设备已被勾选;
    • 重启Docker Desktop和容器,使配置生效。
  • 容器内设备存在性验证
    进入运行中的容器,执行ls /dev查看是否存在映射的/dev/ttyS3设备,若不存在说明映射配置有误,需修正docker-compose.yml中的设备路径(比如Windows的COM4可能对应容器内的/dev/ttyUSB0而非ttyS3)。

  • 串口占用问题
    确认Windows本地是否有其他程序占用COM4端口,关闭占用程序后重启容器重试。

相关代码

SerialConfig.java

package com.XXXXXXXX.config;

import com.fazecast.jSerialComm.SerialPort;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SerialPortConfig {

    @Value("${xxxxxxxxx.node.serial.port:}")
    private String configuredPortName;

    @Bean
    public SerialPort serialPort() {
        SerialPort[] ports = SerialPort.getCommPorts();
        System.out.println("******************");
        System.out.println("Available Port:");
        for (SerialPort port : ports) {
            System.out.println("    Port "+port.getSystemPortName());
        }
        System.out.println("******************");
        if (ports.length == 0) {
            System.err.println("ERROR: No serial ports available. Workpass function may not be working");
            return null;  // Gracefully return null if no ports are available
        }
        else{
            System.out.print("Current Available port:'");
            for (SerialPort port : ports) {
                System.out.print(port.getSystemPortName()+",");
            }
            System.out.println("'");
        }


        SerialPort selectedPort = null;
        if (!configuredPortName.isEmpty()) {
            // Try to find the configured port by name
            for (SerialPort port : ports) {
                if (port.getSystemPortName().equalsIgnoreCase(configuredPortName)) {
                    selectedPort = port;
                    break;
                }
            }
            if (selectedPort == null) {
                System.err.println("ERROR: Configured serial port not found: " + configuredPortName);
                return null;  // Return null if the configured port is not found
            }
        } else {
            // Default to the first available port if no configured port is specified
            selectedPort = ports[0];
        }

        return selectedPort;
    }
}

docker-compose.yml

version: '3.8'

services:
  postgres_db:
    image: postgres:16.4
    container_name: xxxx_postgres_db
    environment:
      POSTGRES_USER: xxxx
      POSTGRES_PASSWORD: xxxx
      POSTGRES_DB: xxxxx-db
    ports:
      - "5431:5432"
    volumes:
      - xxxx_container_data:/var/lib/postgresql/data
    networks:
      - xxxx-network

  backend:
    build:
      context: .  # Path to the Dockerfile location
      dockerfile: Dockerfile  # Optional if the Dockerfile is named 'Dockerfile'
    image: xxxx-img
    container_name: xxxx_backend
    ports:
      - "8080:8080"
    networks:
      - xxxx-network
    depends_on:
      - postgres_db
    devices:
      - "/dev/ttyS0:/dev/ttyS0"
      - "/dev/ttyS1:/dev/ttyS1"
      - "/dev/ttyS2:/dev/ttyS2"
      - "/dev/ttyS3:/dev/ttyS3"

volumes:
  xxxx_data:

networks:
  xxxx-network:

内容的提问来源于stack exchange,提问作者AlexMoshi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:13:17