使用 Docker 部署 3x-ui 并配置 VPN 节点 使用新ip
写给新管理员:本文基于真实踩坑经验整理而来,请从头到尾阅读一遍再开始操作,能帮你避开 80% 的常见问题。
此文档根据Qingwen和ChatGPT沟通部署成功后的聊天记录 由Claude Sonnet 4.6总结而成
背景与架构说明
3x-ui 是一个基于 Xray 的图形化管理面板,可以方便地创建和管理代理节点(VMess / VLESS / Trojan / Reality 等协议)。
本文的使用场景:
- 在外区家里内网的 Windows 电脑上运行 Docker 容器
- 管理员通过本机浏览器访问面板
- 自己/他人通过公网连接代理节点实现安全访问外区家里ip地址网络
最终网络架构如下:
[ 管理员 ]
↓ 内网访问 (127.0.0.1:2053)
[ 3x-ui 面板 ]
↓ 配置
[ Xray 代理节点 ]
↑ 公网连接 (443 端口)
[ 自己/他人 ]
重要原则:面板(admin UI)永远不对外暴露,只有代理节点端口对外开放。
前置条件
在开始之前,确认以下条件均已满足:
- 公网 IP:访问 https://ifconfig.me,确认显示的 IP 与路由器后台 WAN IP 一致,否则说明你在运营商 NAT 后面,需要向运营商申请公网 IP 或改用云服务器
- 路由器管理权:需要配置端口转发(Port Forwarding)
- Windows 或 Linux 主机,已安装 Docker 和 Docker Compose
一、Windows 部署
1.1 关键注意:network_mode: host 在 Windows 不可用
这是 Windows 上最常见的坑。在 Linux 原生 Docker 中,network_mode: host 让容器直接共享宿主机网络。但在 Windows Docker Desktop 中,Docker 实际运行在一个内部虚拟机里:
Windows 宿主机
↓
Docker 虚拟机 (Linux)
↓
你的容器
因此容器监听的端口不是 Windows 的 localhost。如果你看到日志显示:
INFO - Web server running HTTP on [::]:2053
但浏览器访问 http://localhost:2053 却无法连接,就是这个原因。
解决方法:删除 network_mode: host,改用显式端口映射。
1.2 docker-compose.yml 配置
创建工作目录(例如 C:\3xui),在其中新建 docker-compose.yml:
services:
3xui:
image: ghcr.io/mhsanaei/3x-ui:latest
container_name: 3xui_app
volumes:
- $PWD/db/:/etc/x-ui/ # persist panel database
- $PWD/cert/:/root/cert/ # TLS certificate directory
environment:
XRAY_VMESS_AEAD_FORCED: "false"
XUI_ENABLE_FAIL2BAN: "true"
ports:
# Panel: local-only access, not exposed to the internet
- "127.0.0.1:2053:2053"
# VPN node port, exposed to the internet
- "443:443"
# (Optional) HTTP port, can be removed if not needed
- "80:80"
- "2096:2096" # for sharing subscription links port
restart: unless-stopped
端口说明:
127.0.0.1:2053:2053:面板端口,仅本机可访问,外网完全无法到达443:443:代理节点端口,对外开放2096:2096:订阅链接端口,对外开放 (Optional: 如果需要分享订阅链接; 如果使用,需要和443一样操作 接下来的Window防火墙,路由器端口转发)
1.3 启动服务
打开 PowerShell(或 CMD),切换到 docker-compose.yml 所在目录:
# Start service in detached mode
docker compose up -d
# Verify container is running
docker ps
# Check which ports are mapped
docker port 3xui_app
# View live logs
docker compose logs -f
服务正常启动后,在本机浏览器访问:
http://127.0.0.1:2053
默认用户名/密码通常为 admin / admin,首次登录后立即修改。
二、Linux 部署(Debian / Ubuntu)
Linux 上的 Docker 原生支持 network_mode: host,但为了保持一致性和可控性,同样推荐使用端口映射方式。
2.1 安装 Docker(如未安装)
# Install prerequisites
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine and Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# (Optional) Allow running Docker without sudo
sudo usermod -aG docker $USER
newgrp docker
Debian 用户将上面的
ubuntu换成debian即可,其余步骤相同。
2.2 部署 3x-ui
# Create working directory
mkdir -p ~/3xui && cd ~/3xui
mkdir -p db cert
# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
services:
3xui:
image: ghcr.io/mhsanaei/3x-ui:latest
container_name: 3xui_app
volumes:
- ./db/:/etc/x-ui/
- ./cert/:/root/cert/
environment:
XRAY_VMESS_AEAD_FORCED: "false"
XUI_ENABLE_FAIL2BAN: "true"
ports:
- "127.0.0.1:2053:2053" # panel: local-only
- "443:443" # VPN node port
- "80:80" # optional HTTP port
restart: unless-stopped
EOF
# Start the service
docker compose up -d
2.3 Linux 特有:防火墙设置(UFW)
如果系统启用了 UFW:
# Allow VPN node port
sudo ufw allow 443/tcp
# Do NOT expose panel port (2053) to the public
# 127.0.0.1:2053 binding already handles this at Docker level
sudo ufw status
2.4 Linux 特有:设置开机自启
Docker 的 restart: unless-stopped 已经处理容器重启,但需要确保 Docker 服务本身开机自启:
sudo systemctl enable docker
sudo systemctl start docker
三、Windows 防火墙配置
即使 Docker 已经绑定了端口,Windows 防火墙仍然可能拦截外部流量,需要手动添加入站规则。
方法一:图形界面
- 按
Win + R,输入wf.msc打开高级防火墙设置 - 点击左侧 Inbound Rules(入站规则)
- 右侧点击 New Rule…
- 类型选 Port → Next
- 选 TCP,端口填
443→ Next - 选 Allow the connection → Next
- 三个 Profile(Domain / Private / Public)全部勾选 → Next
- 名称填
xray-443→ Finish
方法二:PowerShell(快捷)
以管理员身份运行 PowerShell:
# Add inbound rule for port 443 (TCP)
New-NetFirewallRule `
-DisplayName "xray-443" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 443 `
-Action Allow
# Verify the rule was created
Get-NetFirewallRule -DisplayName "xray-443"
验证端口是否正在监听:
# Should show "0.0.0.0:443 LISTENING"
netstat -ano | findstr :443
四、路由器端口转发
如果服务器在外区家里内网,还需要在路由器上将公网流量转发到这台机器。
4.1 获取内网 IP
# Windows
ipconfig
# Find "IPv4 Address" under the active adapter, e.g. 192.168.1.100
# Linux
ip addr show | grep "inet "
# or
hostname -I
4.2 在路由器设置端口转发
登录路由器管理页(通常是 192.168.1.1),找到 端口转发 / Virtual Server / NAT 相关设置,添加如下规则:
| 字段 | 值 |
|---|---|
| External Port(外部端口) | 443 |
| Internal IP(内网 IP) | 你的机器 IP,如 192.168.1.100 |
| Internal Port(内部端口) | 443 |
| Protocol(协议) | TCP(不要选 ALL,部分路由器有 bug) |
| Status(状态) | Enabled |
强烈建议:在路由器的 DHCP 地址保留(Address Reservation)功能里,将这台机器的 MAC 地址与 IP 绑定,防止 DHCP 重新分配 IP 后端口转发失效。
A successful setup example: 
4.3 验证端口是否开放
在非局域网网络(如手机 4G)上,访问以下地址测试: https://www.yougetsignal.com/tools/open-ports/
输入你的公网 IP 和端口 443,显示 Open 即为成功。
注意:不要在同一个局域网内测试,因为路由器可能不支持 NAT loopback(内网绕回)。比如使用手机,关闭wifi后流量查询。
五、在 3x-ui 面板创建代理节点
以下操作均在面板英文界面中进行。
5.1 登录面板
http://127.0.0.1:2053
5.2 新建 Inbound
- 左侧菜单点击 Inbounds
- 点击 + Add Inbound
5.3 基础配置
| 字段 | 值 |
|---|---|
| Protocol | vless |
| Listen IP | 0.0.0.0 |
| Port | 443 |
| Remark | office-vpn(任意命名) |
5.4 添加客户端(每位自己/他人一个)
点击 Clients 区域,点击 + Add Client:
| 字段 | 值 |
|---|---|
自己/他人名称,如 myself | |
| UUID | 点击 Generate 自动生成 |
安全原则:每人分配独立 UUID,不要共用同一个 Client,这样可以单独吊销某人的访问权限。
5.5 Transmission 设置
在 Transmission 下拉菜单中选择:
TCP (RAW)
5.6 Security 设置(推荐:Reality)
在 Security 下拉菜单中选择 Reality,随后会出现 Reality 专属配置项:
| 字段 | 值 |
|---|---|
| Dest (Target) | www.microsoft.com:443 |
| Server Names | www.microsoft.com |
| Private Key / Public Key | 点击 Get New Keys 自动生成 |
| Short IDs | 点击 Generate 自动生成 |
| mldsa65 Seed / Verify | 留空(实验性功能,现阶段不填) |
为什么推荐 Reality 而不是普通 TLS?
| 对比 | VLESS + None | VLESS + TLS | VLESS + Reality |
|---|---|---|---|
| 加密 | ❌ | ✅ | ✅ |
| 隐蔽性 | ❌ 明文易识别 | ⚠️ 较好 | ✅ 伪装成正常 HTTPS |
| 需要域名 | 不需要 | 需要 | 不需要 |
| 需要证书 | 不需要 | 需要 | 不需要 |
| 配置难度 | 简单 | 复杂 | 中等 |
| 适用场景 | 仅测试 | 有域名时 | 推荐 |
Reality 的核心优势在于:它让代理流量在网络监测层面看起来像是在访问 www.microsoft.com,而非明显的代理特征。
最后一步,点击 Save。
六、向自己/他人分发配置
6.1 设置面板的对外 IP
由于面板只绑定了 127.0.0.1,它不知道你的真实公网 IP,导出的链接默认包含 127.0.0.1。
需要在面板设置中指定公网 IP:
- 进入 Panel Settings 或 System Settings
- 找到 External Address / Public IP
- 填入你的公网 IP(如
81.123.123.12) - 保存
这样导出的链接会自动包含正确的 IP。
6.2 导出链接
在 Inbounds 列表中找到刚创建的节点,点击:
Export All URLs
会弹出类似格式的链接:
vless://UUID@81.123.123.12:443?type=tcp&security=reality&sni=www.microsoft.com&pbk=...&sid=...#office-vpn
将此链接发送给对应自己/他人。
如果你有多位人,点击具体 Client 行末尾的操作按钮,可以单独导出某个用户的链接。
6.3 连接方设备客户端配置
连接方根据设备安装对应客户端:
| 平台 | 客户端 |
|---|---|
| Windows | v2rayN(推荐最新版) |
| Android | v2rayNG |
| iOS / macOS | Shadowrocket |
导入步骤:
- 复制链接
- 打开客户端 → Import / 从剪贴板导入 / Scan QR
- 选中节点 → 连接
连接成功后,访问 https://ipinfo.io 或 https://ifconfig.me,若显示 IP 变为你的公网 IP,则说明 VPN 已生效。
七、安全建议
按重要性排序:
✅ 必须做
- 修改默认密码:首次登录面板后立即修改用户名和密码
- 面板不对外暴露:使用
127.0.0.1:2053:2053绑定,永远不要改成0.0.0.0:2053:2053 - 每人一个 UUID:便于独立管理和吊销
� 建议做
- 设置流量限制(Total Flow):在 Client 编辑页面设置每人的流量上限,防止滥用
- 设置有效期(Duration / Expiry):为临时用户设置到期时间
- 固定内网 IP:在路由器 DHCP 地址保留中绑定机器 MAC,防止 IP 变化导致端口转发失效
- 定期检查日志:面板 → Logs,观察是否有异常连接
⚠️ 如果 link 泄露了
立即在面板中:
Inbounds → 对应节点 → Edit Client → 选择对应用户 → Regenerate ID(重置 UUID)
新 UUID 生成后,旧链接立即失效。
八、常见问题排查
Q1:启动后 localhost:2053 访问不了
最可能原因:docker-compose.yml 中使用了 network_mode: host(Windows 不支持)。
解决:删除 network_mode: host,改用 ports 映射。
Q2:防火墙和端口转发都配置了,外网还是连不上
按以下顺序排查:
# Step 1: Verify service is listening
netstat -ano | findstr :443
# Expected: 0.0.0.0:443 LISTENING
# Step 2: Verify public IP
curl https://ifconfig.me
# Step 3: Check router WAN IP matches ifconfig.me
# Login to 192.168.1.1 → WAN Status
# Step 4: Test from a non-LAN network (4G phone or remote machine)
# Use https://www.yougetsignal.com/tools/open-ports/
如果 Step 3 发现路由器 WAN IP 与 ifconfig.me 显示的 IP 不一致,说明你在运营商 NAT 后面,需要联系运营商申请公网 IP,或改用云服务器。
Q3:导出的链接里 IP 是 127.0.0.1
需要在面板 Panel Settings → External Address 中填入公网 IP,之后重新导出。
Q4:客户端提示 handshake error 或连接失败
常见原因:
- 客户端版本不支持 Reality(请更新到最新版)
- 链接中的 IP 仍是
127.0.0.1(见 Q3) - 路由器协议选了 ALL 而非 TCP(某些 TP-Link 路由器的 ALL 模式有 bug,请改为 TCP)
Q5:端口测试显示 Closed,但确信路由器已配置
检查以下几点:
- 路由器端口转发的内网 IP 是否与
ipconfig输出的 IPv4 一致 - 协议是否选的是 TCP(不是 UDP 或 ALL)
- 外部端口是否写的是
443(不是433,注意数字) - 是否在同一局域网内测试(内网测试可能因 NAT loopback 不支持而失败)
| *文档版本:v1.0 | 基于 3x-ui v2.8.11 + Xray 26.2.6* |
Enjoy Reading This Article?
Here are some more articles you might like to read next: