> ## Content Index
> Fetch the complete content index at: https://tbbbk.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Remnawave 面板搭建记录 (Docker + CF Tunnel + XHTTP)
- URL: https://tbbbk.com/setup-remnawave-panel-docker-xhttp-reality/
- Published: 2025-12-31T03:49:26.000Z
- Updated: 2026-01-30T05:31:38.000Z
- Author: TuBaiBai
- Tags: 折腾日记, #Import 2026-07-20 07:13

网上关于 Remnawave 的教程不多，官方文档看着也累。折腾了一套 Docker Compose 方案，顺手优化了一下：把不必要的端口映射全去掉了，改走 Cloudflare Tunnel 内网穿透，安全性比直连高不少。

如果你是单机，还是建议用 X-UI；如果手里机器多，或者想玩 XHTTP/Reality 上下行分离，这个面板确实顺手。

## 1\. 准备工作

- **面板机**：Debian/Ubuntu，内存 2G+（主要是 Java 和 PG 数据库吃点内存）。
- **节点机**：随便啥能装 Docker 的机器。
- **域名**：托管在 Cloudflare。

## 2\. 面板端部署

直接用 Docker 梭哈，不用配 Nginx。

### 初始化环境 & 生成密钥

连上 SSH，一把梭：

```
# 装 Docker
curl -fsSL https://get.docker.com | sh
准备目录和环境变量
mkdir -p /opt/remnawave && cd /opt/remnawave
curl -o .env https://raw.githubusercontent.com/remnawave/backend/refs/heads/main/.env.sample
生成一堆随机密钥填进 .env，省得手动改
sed -i "s/^JWT_AUTH_SECRET=./JWT_AUTH_SECRET=$(openssl rand -hex 64)/" .env
sed -i "s/^JWT_API_TOKENS_SECRET=./JWT_API_TOKENS_SECRET=$(openssl rand -hex 64)/" .env
sed -i "s/^METRICS_PASS=./METRICS_PASS=$(openssl rand -hex 64)/" .env
sed -i "s/^WEBHOOK_SECRET_HEADER=./WEBHOOK_SECRET_HEADER=$(openssl rand -hex 64)/" .env
设置数据库密码

```

### 配置文件 (docker-compose.yml)

在 `/opt/remnawave` 下新建文件。 **注意**：为了安全，这里数据库端口只开了本地 127.0.0.1，面板端口也没映射，全靠最后那个 Tunnel 容器往外透。

```
services:
remnawave-db:
image: postgres:17.6
restart: always
env_file: .env
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
- TZ=UTC
ports:
- '127.0.0.1:6767:5432'
volumes:
- remnawave-db-data:/var/lib/postgresql/data
networks:
- remnawave-network
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}']
interval: 3s
timeout: 10s
retries: 3
remnawave-redis:
image: valkey/valkey:8.1-alpine
restart: always
networks:
- remnawave-network
volumes:
- remnawave-redis-data:/data
healthcheck:
test: ['CMD', 'valkey-cli', 'ping']
interval: 3s
timeout: 10s
retries: 3
remnawave:
image: remnawave/backend:2
container_name: 'remnawave'
restart: always
env_file: .env
networks:
- remnawave-network
depends_on:
remnawave-db:
condition: service_healthy
remnawave-redis:
condition: service_healthy
healthcheck:
test: ['CMD-SHELL', 'curl -f http://localhost:${METRICS_PORT:-3001}/health']
interval: 30s
timeout: 5s
retries: 3
remnawave-subscription-page:
image: remnawave/subscription-page:latest
restart: always
environment:
- REMNAWAVE_PANEL_URL=http://remnawave:3000
- META_TITLE=Subscription
- SUBSCRIPTION_UI_DISPLAY_RAW_KEYS=true
networks:
- remnawave-network
depends_on:
- remnawave
Cloudflare Tunnel
remnawave-cloudflared:
image: cloudflare/cloudflared:latest
env_file: .env
networks:
- remnawave-network
restart: always
command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TOKEN}
depends_on:
- remnawave
- remnawave-subscription-page
networks:
remnawave-network:
enable_ipv6: true

```

### 配置 CF Tunnel & 环境变量

1. 去 Cloudflare 后台 -> Zero Trust -> Tunnels -> Create a tunnel。
2. 拿到那个以 `ey` 开头的 **Token**。
3. 配置 Public Hostnames（把域名指过来）：

  - 面板域名 -> `http://remnawave:3000`
  - 订阅域名 -> `http://remnawave-subscription-page:3010`
4. 找 `@BotFather` 要个 TG Bot Token，找 `@userinfobot` 拿你自己的 ID。

编辑 `.env` 文件，把最后这几项补齐：

Bash

```
IS_TELEGRAM_NOTIFICATIONS_ENABLED=true
TELEGRAM_BOT_TOKEN=你的BotToken
TELEGRAM_NOTIFY_USERS_CHAT_ID=你的TG_ID
TELEGRAM_NOTIFY_NODES_CHAT_ID=你的TG_ID
TELEGRAM_NOTIFY_CRM_CHAT_ID=你的TG_ID
CLOUDFLARE_TOKEN=你的CF_Tunnel_Token
SUB_PUBLIC_DOMAIN=你的订阅域名
FRONT_END_DOMAIN=你的面板域名
```

启动： `docker compose up -d`

## 3\. 核心配置：Xray 模板

Remnawave 的核心就是这个配置模板。下面这个是我自己在用的，含 **VLESS-Reality** 和 **XHTTP**，直接复制进面板的“配置文件”里就行。

*记得把 `privateKey` 换成你自己生成的。*

JSON

```
{
"log": { "loglevel": "error" },
"dns": { "servers": ["1.1.1.1"], "queryStrategy": "UseIP" },
"inbounds": [
{
"tag": "SS-IN",
"port": 1145,
"protocol": "shadowsocks",
"settings": { "clients": [], "network": "tcp,udp" }
},
{
"tag": "REALITY-TCP",
"port": 8443,
"listen": "0.0.0.0",
"protocol": "vless",
"settings": { "clients": [], "decryption": "none" },
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
"streamSettings": {
"network": "raw",
"security": "reality",
"realitySettings": {
"target": "osxapps.itunes.apple.com:443",
"shortIds": ["b2c86d5449d237fa"],
"privateKey": "替换这里！！！",
"serverNames": ["osxapps.itunes.apple.com"]
}
}
},
{
"tag": "REALITY-XHTTP",
"port": 80,
"listen": "0.0.0.0",
"protocol": "vless",
"settings": { "clients": [], "decryption": "none" },
"sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
"streamSettings": {
"network": "xhttp",
"security": "reality",
"xhttpSettings": { "host": "", "mode": "auto", "path": "/pandl_ul_api" },
"realitySettings": {
"target": "osxapps.itunes.apple.com:443",
"shortIds": ["b2c86d5449d237fa"],
"privateKey": "替换这里！！！",
"serverNames": ["osxapps.itunes.apple.com"]
}
}
}
],
"outbounds": [
{ "tag": "direct", "protocol": "freedom" },
{ "tag": "block", "protocol": "blackhole" }
],
"routing": {
"rules": [
{ "sourceIP": ["geoip:cn"], "inboundTag": ["SS-IN"], "outboundTag": "block" },
{ "ip": ["geoip:private"], "outboundTag": "block" }
],
"domainStrategy": "IPIfNonMatch"
}
}
```

## 4\. 节点接入

面板添加节点拿到 Key，然后在节点机上跑个 Docker 完事。

**节点端 docker-compose.yml**：

```
services:
remnanode:
image: remnawave/node:latest
network_mode: host
restart: always
volumes:
- './ssl:/var/lib/remnawave/configs/xray/ssl'
environment:
- NODE_PORT=11451 # 填你在面板设的端口
- SECRET_KEY=面板给的Key
```

`docker compose up -d` 跑起来就行。

## 5\. 避坑指南

1. **逻辑顺序**：先去“内部分组”建个组，绑定上面的 `Inbound Tag` (比如 `REALITY-TCP`)，再去“主机”里添加节点 IP，最后去“用户”里开号。
2. **XHTTP**：如果用 XHTTP，可以在“主机”的高级设置里把 Xray 配置覆盖一下，做下载流量分离。
3. **安全性**：面板反代千万别把 3000 端口直接露给公网，被扫了就是送人头，用 Tunnel 最稳。