Skip to content

🚀 使用 Docker Compose 部署 NPS(轻量级内网穿透工具:服务端 + 客户端)

🚀 使用 Docker Compose 部署 NPS 内网穿透服务

NPS 是一款轻量级、高性能、功能强大的内网穿透代理服务器,支持 TCP、UDP、SOCKS5、HTTP 等几乎所有流量转发。通过 Docker Compose 部署可以简化安装流程,提高部署效率。

📝 项目简介

NPS 是一款专为内网穿透设计的代理服务器工具,它通过 Web 界面提供可视化管理,让用户能够轻松配置和管理内网服务的外部访问。

核心特点:

  • 多协议支持:支持 TCP、UDP、HTTP、HTTPS、SOCKS5 等多种协议转发
  • Web 管理界面:提供友好的 Web 图形界面,方便配置和管理
  • 高性能:轻量级设计,资源占用少,性能出色
  • 全平台兼容:支持 Linux、Windows、macOS 等多种平台
  • 安全可靠:支持流量加密、访问控制等安全特性

🔧 部署前准备

系统环境要求

  • 操作系统:支持 Linux、Windows、macOS
  • Docker 引擎:确保已安装 Docker 服务
  • Docker Compose:版本 2.0+
  • 硬件资源
  • 内存:至少 512MB
  • 存储空间:至少 1GB 可用空间

环境检查

1.检查 Docker 服务状态

   systemctl status docker

确保 Docker 服务处于 active (running) 状态

2.检查 Docker 版本

   docker -v

3.创建部署目录

   mkdir -p /home/compose/nps && cd /home/compose/nps

⚙️ 配置 Docker Compose

NPS 服务端配置

创建 docker-compose-nps.yml 文件:

services:
    nps:
        # NPS 服务端镜像(yisier1 优化版,稳定兼容 Docker)
        image: yisier1/nps
        container_name: nps  # 容器名称,便于管理(如查看日志、重启)
        restart: always  # 容器退出后自动重启(保障服务稳定,避免断连)
        volumes:
            # 核心挂载:本地 ./conf → 容器 /conf(存储配置文件,必须挂载!)
            - ./conf:/conf
            # 时区同步:确保服务端日志时间与本地一致(避免时间错乱)
            - /etc/localtime:/etc/localtime:ro
        network_mode: 'host'   # 关键!使用主机网络,直接监听服务端端口(避免端口映射冲突)
        #privileged: true  # 特权模式(默认关闭,仅特殊网络场景需开启,如修改路由)

接下来 在./conf子目录,创建对应的配置文件,文件必须存在否则启动失败。

1.创建 clients.json 文件:

{"Cnf":{"U":"","P":"","Compress":false,"Crypt":false},"Id":2,"VerifyKey":"qplcfr11qs0u95qh","Addr":"223.74.26.13","Remark":"","Status":true,"IsConnect":true,"RateLimit":0,"Flow":{"ExportFlow":0,"InletFlow":0,"FlowLimit":0},"Rate":{"NowRate":0},"NoStore":false,"NoDisplay":false,"MaxConn":0,"NowConn":0,"WebUserName":"","WebPassword":"","ConfigConnAllow":true,"MaxTunnelNum":0,"Version":"0.26.20","BlackIpList":[""],"CreateTime":"2025-10-17 07:55:30","LastOnlineTime":"2025-10-17 08:00:51"}

*#*

2.创建 hosts.json 文件,无需填写内容保持空白就好。

3.创建 nps.conf 文件:

# 应用名称
appname = nps
#Boot mode(dev|pro)
#runmode = dev
# 运行模式(dev开发模式|pro生产模式)
# 优化:生产模式关闭冗余调试输出,减少性能损耗
runmode = pro

#HTTP(S) proxy port, no startup if empty# HTTP(S)代理端口,留空则不启动
http_proxy_ip=0.0.0.0
http_proxy_port=20000
https_proxy_port=20001
https_just_proxy=true
#default https certificate setting# 默认HTTPS证书配置
https_default_cert_file=conf/server.pem
https_default_key_file=conf/server.key

##bridge## 桥接配置(TCP穿透核心)
# 桥接类型为TCP(符合需求)
bridge_type=tcp
# 桥接端口(确保无占用且防火墙放行)
bridge_port=20002
# 桥接监听IP(允许所有IP连接)
bridge_ip=0.0.0.0

# Public password, which clients can use to connect to the server
# After the connection, the server will be able to open relevant ports and parse related domain names according to its own configuration file.
# 客户端连接服务器的公共密钥
# 连接后服务器会根据配置开放端口和解析域名
public_vkey=123  # 建议修改为复杂密钥(如随机字符串)提升安全性

#Traffic data persistence interval(minute)
#Ignorance means no persistence
# 流量数据持久化间隔(分钟)
# 留空表示不持久化(减少磁盘IO,提升性能)
#flow_store_interval=1

# log level LevelEmergency->0  LevelAlert->1 LevelCritical->2 LevelError->3 LevelWarning->4 LevelNotice->5 LevelInformational->6 LevelDebug->7
# 日志级别(LevelEmergency->0 紧急 | LevelAlert->1 警报 | LevelCritical->2 严重 | LevelError->3 错误 | LevelWarning->4 警告 | LevelNotice->5 通知 | LevelInformational->6 信息 | LevelDebug->7 调试)
# 优化:降低日志级别,减少IO开销(视频流无需详细调试日志)
log_level=4 #7
# 日志文件路径(留空使用默认,避免额外IO)
#log_path=nps.log

#Whether to restrict IP access, true or false or ignore # 是否限制IP访问(true/false/留空)
#ip_limit=true

#p2p # P2P配置(暂不使用,保持注释)
#p2p_ip=127.0.0.1
#p2p_port=6000

#web # Web管理界面配置

# 管理域名(无需可留空)
web_host= #a.o.com
# 管理员账号(建议修改)
web_username=admin
# 管理员密码(强烈建议修改为复杂密码)
web_password=123
# 管理端口(确保安全)
web_port = 20003
web_ip=0.0.0.0
web_base_url=
# 不启用SSL(减少加密开销,非管理场景优先性能)
web_open_ssl=false
web_cert_file=conf/server.pem
web_key_file=conf/server.key
# if web under proxy use sub path. like http://host/nps need this.
# 若Web管理在代理子路径下(如http://host/nps)需配置
#web_base_url=/nps

#Web API unauthenticated IP address(the len of auth_crypt_key must be 16)
#Remove comments if needed
# Web API无验证IP地址(auth_crypt_key长度必须为16)
# 需启用时取消注释
#auth_key=test
auth_crypt_key =1234567812345678  # 建议修改为随机16位字符串

#allow_ports=9001-9009,10001,11000-12000
# 允许穿透的端口范围(优化:添加视频流常用端口,避免被拦截)
# 包含HTTP(80)、HTTPS(443)、RTSP(554)、RTMP(1935)等常见视频端口
allow_ports=80,443,554,1935,20000-20010

#Web management multi-user login # Web管理多用户登录
allow_user_login=false
allow_user_register=false
allow_user_change_username=false


#extension # 扩展限制(优化:全部关闭,避免限制视频流传输)
allow_flow_limit=false  # 不限制流量(视频流需大流量)
allow_rate_limit=false  # 不限制速率(避免视频卡顿)
allow_tunnel_num_limit=false  # 不限制隧道数量
allow_local_proxy=false
allow_connection_num_limit=false  # 不限制连接数(视频可能多连接)
allow_multi_ip=false
system_info_display=false  # 关闭系统信息显示,减少资源占用

#cache # 缓存配置(TCP穿透无需HTTP缓存,保持关闭)
http_cache=false
http_cache_length=100

#get origin ip  # 获取源IP(无需,关闭减少处理步骤)
http_add_origin_header=false

#pprof debug options  # pprof调试(关闭,避免性能损耗)
#pprof_ip=0.0.0.0
#pprof_port=9999

#client disconnect timeout
#disconnect_timeout=60
# 客户端断开超时时间(优化:延长超时,减少视频流频繁重连)
# 原60秒→120秒,适应网络波动
disconnect_timeout=120

[!NOTE] 提示 上面的文件,allow_ports 开放了 80,443,554,1935,20000-20010 端口,创建TCP端口从20005开始,我只有一个服务要开放够用了。20010你按情况调大调小需要开放的数字。

4.创建 tasks.json 文件:

{"Id":19,"Port":20005,"ServerIp":"","Mode":"tcp","Status":true,"RunStatus":true,"Client":{"Cnf":{"U":"","P":"","Compress":true,"Crypt":true},"Id":2,"VerifyKey":"qplcfr11qs0u95qh","Addr":"223.74.26.13","Remark":"","Status":true,"IsConnect":true,"RateLimit":0,"Flow":{"ExportFlow":4703739,"InletFlow":4703739,"FlowLimit":0},"Rate":{"NowRate":15619},"NoStore":false,"NoDisplay":false,"MaxConn":0,"NowConn":9,"WebUserName":"","WebPassword":"","ConfigConnAllow":true,"MaxTunnelNum":0,"Version":"0.26.20","BlackIpList":[""],"CreateTime":"2024-11-30 15:35:13","LastOnlineTime":"2025-10-15 05:36:20"},"Ports":"","Flow":{"ExportFlow":0,"InletFlow":0,"FlowLimit":0},"Password":"","Remark":"","TargetAddr":"","NoStore":false,"IsHttp":false,"LocalPath":"","StripPre":"","ProtoVersion":"","Target":{"TargetStr":"192.168.0.3:5006","TargetArr":["192.168.0.3:5006"],"LocalProxy":false},"MultiAccount":null,"HealthCheckTimeout":0,"HealthMaxFail":0,"HealthCheckInterval":0,"HealthNextTime":"0001-01-01T00:00:00Z","HealthMap":null,"HttpHealthUrl":"","HealthRemoveArr":null,"HealthCheckType":"","HealthCheckTarget":""}

*#*

NPC 客户端配置

创建 docker-compose-npc.yml 文件:

services:
  npc:
    # NPS 客户端镜像(与服务端镜像同源,确保兼容性)
    image: yisier1/npc
    container_name: npc3  # 容器名称,可自定义(如多客户端区分)
    restart: always  # 客户端断连后自动重连,保障穿透稳定
    network_mode: host  # 使用主机网络,直接转发内网服务端口
    # 核心命令:指定服务端地址假设为19*.*.1**.1**、VKey、连接类型(必须替换为你的服务端参数)
    command: -server=19*.*.1**.1**:20002 -vkey=xlg1v6a05qtavd3w -type=tcp
    # 命令参数说明:
    # -server:服务端公网IP:通信端口(替换为你的服务端IP,默认端口20002)
    # -vkey:客户端唯一验证密钥(从服务端Web界面生成,下文详述)
    # -type:连接类型(tcp,无需修改)

关键配置说明

  1. 网络模式:使用 host 网络模式简化网络配置
  2. 数据持久化./conf:/conf 挂载确保配置数据持久化
  3. 重启策略always 确保服务异常时自动重启
  4. 客户端参数
  5. server:NPS 服务端地址和端口
  6. vkey:客户端验证密钥
  7. type:连接类型(TCP/UDP)

关键配置说明(新手必看)

配置项 作用与注意事项
network_mode: 'host' 服务端 / 客户端均需开启!避免 Docker 网络转发导致的端口冲突,确保直接监听主机端口(穿透效率更高)。
服务端 ./conf:/conf 核心配置目录!删除此目录会丢失所有客户端、隧道配置,需定期备份(下文维护部分详述)。
客户端 command 必须替换 server 和 vkey 为实际值!server 格式为「公网 IP:20002」,vkey 从服务端生成。
/etc/localtime:/etc/localtime:ro 只读挂载本地时区文件,确保日志时间与本地一致,排查问题时更易追溯时间线。

🚀 启动与验证

启动 NPS 服务端

docker compose -f docker-compose-nps.yml up -d

验证服务端状态

  1. 检查容器运行状态 bash docker ps 应该看到 nps 服务处于 Up 状态

  2. 查看服务日志 bash docker compose -f docker-compose-nps.yml logs -f

  3. 访问 Web 管理界面

  4. 在浏览器中访问 http://你的服务器IP:8080
  5. 使用默认账号密码登录(admin/123)

启动 NPC 客户端

docker compose -f docker-compose-npc.yml up -d

验证客户端连接

  1. 检查客户端状态 bash docker ps | grep npc

  2. 查看客户端日志 bash docker compose -f docker-compose-npc.yml logs -f

  3. 在 NPS 管理界面验证

  4. 登录 NPS Web 管理界面
  5. 查看客户端列表,确认客户端在线状态

🚀 启动与验证2

(2)访问服务端 Web 管理界面

  1. 打开浏览器,输入 http://服务端公网IP:8080(如 http://190.1.111.111:8080);
  2. 首次登录使用 默认账号密码
    • 用户名:admin
    • 密码:123
  3. 登录后强制跳转至「密码修改页面」,设置新密码(建议包含字母 + 数字 + 符号,如 NPS@2024!),避免默认密码泄露风险。

(3)添加客户端并获取 VKey(核心!)

  1. 密码修改完成后,进入主界面,点击左侧「客户端管理」→「新增客户端」;
  2. 填写客户端基础信息(仅需配置必填项):
    • 客户端名称:自定义(如「家庭 NAS」「本地电脑」,便于区分多客户端);
    • 备注:可选(如「映射 NAS 的 Web 服务」);
    • 其他参数(如流量限制、过期时间):默认即可,新手无需修改;
  3. 点击「确定」,客户端列表中会新增一条记录,记录中的 「VKey」列 即为客户端连接所需的密钥(如用户配置中的 xlg1v6a05qtavd3w),复制此 VKey 备用。

2. 步骤 2:启动客户端并验证连接

(1)修改客户端配置并启动

  1. 内网设备操作:进入客户端部署目录,编辑 docker-compose.yml,将 command 中的 server 和 vkey 替换为实际值(服务端公网 IP+VKey);
  2. 启动客户端容器:
    cd /opt/nps-client
    docker compose up -d

(2)验证客户端是否连接成功

方法 1:查看客户端容器日志(最直接)

# 查看客户端实时日志,按 Ctrl+C 退出
docker compose logs -f npc3
  • 若日志显示 success connect to server 或「连接服务端成功」,说明客户端已正常绑定服务端;
  • 若日志显示 connect server fail,需排查服务端端口是否开放、VKey 是否正确(下文常见问题部分详述)。

方法 2:服务端 Web 界面验证

  1. 回到服务端 http://服务端IP:8080 →「客户端管理」;
  2. 查看新增客户端的「状态」列,若显示「在线」,说明连接成功;若显示「离线」,需排查客户端配置。

🔌 基础配置与使用

NPS 服务端基础配置

  1. 修改默认密码
  2. 登录 Web 管理界面后立即修改默认密码
  3. 在客户端配置文件中修改 web_password 参数

  4. 配置端口映射

   # 在服务器防火墙开放所需端口
   iptables -A INPUT -p tcp --dport 8080 -j ACCEPT  # Web 管理端口
   iptables -A INPUT -p tcp --dport 8024 -j ACCEPT  # 客户端连接端口

创建内网穿透隧道

  1. TCP 隧道配置
  2. 应用场景:SSH 访问、远程桌面、数据库连接
  3. 配置步骤

    • 在 NPS 管理界面进入"隧道管理"
    • 添加 TCP 隧道,配置目标内网服务地址和端口
    • 设置服务端监听端口
  4. HTTP/HTTPS 隧道配置

  5. 应用场景:内网网站访问、微信公众号开发
  6. 配置步骤

    • 添加 HTTP/HTTPS 隧道
    • 配置域名和内网目标地址
    • 设置 SSL 证书(如需要)
  7. SOCKS5 代理配置

  8. 应用场景:全局内网访问
  9. 配置步骤
    • 添加 SOCKS5 代理
    • 设置监听端口
    • 配置客户端使用 SOCKS5 代理

客户端管理

  1. 添加客户端
  2. 在 NPS Web 管理界面进入"客户端"菜单
  3. 点击"新增"创建客户端,记录验证密钥

  4. 客户端连接

   # 使用 Docker 运行 NPC 客户端
   docker run -d --name=npc --restart=always --net=host yisier1/npc -server=IP:PORT -vkey=密钥 -type=tcp

🔌 基础配置与使用2(核心:创建隧道映射内网服务)

客户端连接成功后,需在服务端创建「隧道」,将内网服务(如 Web、SSH、远程桌面)映射到公网,实现外网访问:

以「映射内网 Web 服务(端口 80)」为例,步骤如下:

1. 确认内网服务状态

确保内网客户端设备上的 Web 服务已启动(如本地 Nginx、NAS 的管理界面),且内网可访问(如在客户端设备上访问 http://localhost:80 能打开页面)。

2. 服务端创建 TCP 隧道

  1. 服务端 Web 界面 → 左侧「隧道管理」→「新增隧道」;
  2. 选择隧道类型为「TCP 隧道」(适配 Web、SSH 等 TCP 协议服务),填写关键配置:

    配置项 说明与示例值
    所属客户端 下拉选择已连接的客户端(如「家庭 NAS」)
    隧道名称 自定义(如「NAS-Web-80」)
    本地 IP 内网服务所在的 IP(客户端设备的内网 IP,如 192.168.1.100,本地服务填 127.0.0.1
    本地端口 内网服务的端口(如 Web 服务默认 80,SSH 默认 22)
    服务端端口 公网映射端口(自定义未占用端口,如 8081,需提前开放此端口)
    其他参数 默认即可(如压缩、加密:新手无需开启,按需配置)
  3. 点击「确定」,隧道列表中新增记录,状态显示「正常」即生效。

3. 外网访问内网服务

在外网设备(如手机流量、非内网电脑)的浏览器中输入:http://服务端公网IP:服务端端口(如 http://19*.*.1**.1**:8081

  • 若能打开内网 Web 服务页面,说明穿透成功;
  • 若无法访问,需排查隧道配置(本地 IP / 端口是否正确)、内网服务是否启动、服务端端口是否开放。

🛠️ 维护与管理

日常维护操作

1.服务启停

   # 停止服务
   docker compose -f docker-compose-nps.yml down

   # 启动服务
   docker compose -f docker-compose-nps.yml up -d

2.数据备份

   # 备份配置文件
   tar -czf nps-backup-$(date +%Y%m%d).tar.gz ./conf

3.服务更新

   # 更新服务端
   docker compose -f docker-compose-nps.yml pull
   docker compose -f docker-compose-nps.yml down
   docker compose -f docker-compose-nps.yml up -d

监控与日志

  1. 查看实时日志 bash docker compose -f docker-compose-nps.yml logs -f

  2. 监控资源使用 bash docker stats nps

  3. 检查网络连接 bash netstat -tulpn | grep -E ':(8080|8024)'

🐛 常见问题排查

1. 无法访问 Web 管理界面

问题现象:浏览器访问 http://IP:8080 无响应

解决方案: - 检查防火墙设置:

  # 开放 8080 端口
  iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
  • 验证服务绑定:
  netstat -tulpn | grep 8080

2. 客户端连接失败

问题现象:NPC 客户端无法连接服务端

解决方案: - 检查服务端端口开放:

  # 开放客户端连接端口
  iptables -A INPUT -p tcp --dport 8024 -j ACCEPT
  • 验证客户端配置:
  docker logs npc3

3. 隧道连接失败

问题现象:隧道已建立但无法访问内网服务

解决方案: - 检查内网服务状态 - 验证隧道配置的目标地址和端口 - 检查内网防火墙设置

4. 性能问题

问题现象:传输速度慢或连接不稳定

解决方案: - 检查服务器带宽使用情况 - 调整隧道压缩设置 - 考虑使用 P2P 模式(如支持)

5. 容器启动失败

问题现象:Docker 容器无法正常启动

解决方案: - 检查端口冲突:

  netstat -tulpn | grep -E ':(8080|8024)'
  • 验证目录权限:
  chmod -R 755 ./conf

通过本教程,您应该已经成功部署并配置了 NPS 内网穿透服务。NPS 的强大功能和简单配置让它成为内网穿透的优秀解决方案。如果在使用过程中遇到其他问题,可以参考项目官方文档或社区支持资源。


🐛 常见问题排查2

1. 客户端连接失败(日志显示「connect server fail」)

  • 原因 1:服务端 20002 端口未开放或被占用。解决

    1. 服务端执行 sudo ufw status 确认 20002 端口已允许;
    2. 云服务器检查安全组是否添加 20002 端口入站规则;
    3. 检查端口是否被占用:sudo lsof -i :20002,若占用则停止对应服务。
    4. 原因 2:客户端 command 中的 server 或 vkey 错误。解决

    5. 确认 server 格式为「公网 IP:20002」(无多余空格,IP 无误);

    6. 回到服务端「客户端管理」,核对 VKey 是否与客户端配置一致(区分大小写)。
    7. 原因 3:客户端设备无法访问外网(或服务端公网 IP 不可达)。解决:客户端设备执行 ping 服务端公网IP,若无法 ping 通,排查内网网络(如路由器是否正常联网、有无防火墙限制)。

2. 服务端 Web 管理界面无法访问(ERR_CONNECTION_REFUSED)

  • 原因 1:8080 端口未开放或服务端容器未启动。解决

    1. 服务端执行 docker compose ps 确认 nps 容器状态为「Up」;
    2. 开放 8080 端口:sudo ufw allow 8080/tcp,云服务器同步配置安全组。
    3. 原因 2:忘记修改后的管理员密码(或密码输入错误)。解决:重置服务端配置(会丢失所有客户端、隧道配置,谨慎操作):
    # 服务端操作:停止容器 → 删除配置目录 → 重启容器(恢复默认账号密码 admin/123)
    docker compose down
    rm -rf ./conf
    mkdir -p conf && sudo chmod 777 conf
    docker compose up -d

3. 隧道创建成功但外网无法访问内网服务

  • 原因 1:隧道配置的「本地 IP / 本地端口」错误。解决

    1. 确认「本地 IP」是客户端设备的内网 IP(如 192.168.1.100,非服务端 IP);
    2. 确认「本地端口」与内网服务端口一致(如 Web 服务是 80,而非 8080);
    3. 客户端设备执行 curl http://本地IP:本地端口,验证内网服务是否正常(若无法访问,先修复内网服务)。
    4. 原因 2:服务端「自定义代理端口」未开放。解决:开放隧道配置中「服务端端口」(如 8081):sudo ufw allow 8081/tcp,云服务器同步配置安全组。
  • 原因 3:客户端与服务端连接已断开(状态显示「离线」)。解决:客户端执行 docker compose restart 重连,服务端确认客户端状态恢复「在线」后重试。

4. 隧道访问时出现「连接超时」(Timeout)

  • 原因:内网服务未启动,或隧道转发的端口与服务端口不匹配。

    解决: 1. 客户端设备启动内网服务(如 sudo systemctl start nginx 启动 Web 服务); 2. 服务端「隧道管理」中,核对「本地端口」是否与内网服务实际端口一致(如 SSH 是 22,而非 2222)。

通过以上步骤,新手可快速搭建 NPS 内网穿透服务,实现外网访问内网的 Web、SSH、远程桌面等服务。如需探索更多功能(如 UDP 隧道、HTTP 域名绑定、流量限制),可参考 NPS 官方文档(注:官方为原版 NPS,Docker 部署逻辑一致)。