feat: 3X-UI(3.0.0) Multi-Node Architecture, Client Management, HWID Tracking, Host Management, Glass Morphism UI & Redis Cache#3635
Conversation
|
@MHSanaei I’d really appreciate help from the community to test different setups, edge cases, and give feedback before moving toward stable. |
|
wow |
|
@alireza0 please see) I need approval to remove local package sub-substitions |
There was a problem hiding this comment.
There are mandatory primary needs for this change which requested to have a solution for.
Some other optional points which could be done after this MR as well:
- Define outbound specific for each node (optional-good to have)
- Define separate DNS+rules for each node
- Stop working node when Manager is not available.
- Auto build pipeline for node and use script/docker for installation
- Node script to control and check the status as asme as x-ui.sh
- Change port possibility
| RUN echo "Contents of /app/bin after COPY:" && \ | ||
| ls -la ./bin/ && \ | ||
| echo "Looking for xray binary..." && \ | ||
| if [ -f ./bin/xray-linux-amd64 ]; then \ | ||
| chmod +x ./bin/xray-linux-amd64 && \ | ||
| echo "✓ Found and made executable: xray-linux-amd64"; \ | ||
| elif [ -f ./bin/xray ]; then \ | ||
| chmod +x ./bin/xray && \ | ||
| mv ./bin/xray ./bin/xray-linux-amd64 && \ | ||
| echo "✓ Found xray, renamed to xray-linux-amd64"; \ | ||
| else \ | ||
| echo "✗ ERROR: No xray binary found!" && \ | ||
| echo "All files in bin directory:" && \ | ||
| find ./bin -type f -o -type l && \ | ||
| exit 1; \ | ||
| fi |
There was a problem hiding this comment.
It makes docekr file too big but not needed to be
| # Copy XRAY binary and data files | ||
| # Use wildcard to copy all files from bin directory | ||
| COPY --from=builder /build/bin/ ./bin/ | ||
|
|
There was a problem hiding this comment.
No need to download xray-core in build time.
Move it here
| RUN mkdir -p bin && \ | ||
| cd bin && \ | ||
| case ${TARGETARCH} in \ | ||
| amd64) \ | ||
| ARCH="64" \ | ||
| FNAME="amd64" \ | ||
| ;; \ | ||
| arm64) \ | ||
| ARCH="arm64-v8a" \ | ||
| FNAME="arm64" \ | ||
| ;; \ | ||
| arm) \ | ||
| ARCH="arm32-v7a" \ | ||
| FNAME="arm32" \ | ||
| ;; \ | ||
| armv6) \ | ||
| ARCH="arm32-v6" \ | ||
| FNAME="armv6" \ | ||
| ;; \ | ||
| 386) \ | ||
| ARCH="32" \ | ||
| FNAME="i386" \ | ||
| ;; \ | ||
| *) \ | ||
| ARCH="64" \ | ||
| FNAME="amd64" \ | ||
| ;; \ | ||
| esac && \ | ||
| echo "Downloading Xray for ${TARGETARCH} (ARCH=${ARCH}, FNAME=${FNAME})" && \ | ||
| curl -sfLRO "https://github.com/XTLS/Xray-core/releases/download/v25.12.8/Xray-linux-${ARCH}.zip" && \ | ||
| echo "Unzipping..." && \ | ||
| unzip -q "Xray-linux-${ARCH}.zip" && \ | ||
| echo "Files after unzip:" && \ | ||
| ls -la && \ | ||
| echo "Removing zip and old data files..." && \ | ||
| rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat && \ | ||
| echo "Renaming xray to xray-linux-${FNAME}..." && \ | ||
| mv xray "xray-linux-${FNAME}" && \ | ||
| chmod +x "xray-linux-${FNAME}" && \ | ||
| echo "Verifying xray binary:" && \ | ||
| ls -lh "xray-linux-${FNAME}" && \ | ||
| test -f "xray-linux-${FNAME}" && echo "✓ xray-linux-${FNAME} exists" && \ | ||
| echo "Downloading geo files..." && \ | ||
| curl -sfLRO https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat && \ | ||
| curl -sfLRO https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat && \ | ||
| curl -sfLRo geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat && \ | ||
| curl -sfLRo geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat && \ | ||
| curl -sfLRo geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat && \ | ||
| curl -sfLRo geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat && \ | ||
| echo "Final files in bin:" && \ | ||
| ls -lah && \ | ||
| echo "File sizes:" && \ | ||
| du -h * && \ | ||
| cd .. && \ | ||
| echo "Verifying files in /build/bin:" && \ | ||
| ls -lah /build/bin/ |
There was a problem hiding this comment.
Big line make no sense!
Please convert it to a script and use it. in runtime stage instead of build stage
| s.httpServer = &http.Server{ | ||
| Addr: fmt.Sprintf(":%d", s.port), | ||
| Handler: router, | ||
| ReadTimeout: 10 * time.Second, | ||
| WriteTimeout: 10 * time.Second, | ||
| } |
There was a problem hiding this comment.
It is not enough!
Security for this kind of usage is mandatory.
Plain HTTP test is dangerous
| api.POST("/force-reload", s.forceReload) | ||
| api.GET("/status", s.status) | ||
| api.GET("/stats", s.stats) | ||
| } |
There was a problem hiding this comment.
It is better to have /logs endpoint to get core's log available in manager
feat: 3X-UI(3.0.0) Multi-Node Architecture, Client Management, HWID Tracking, Host Management, Glass Morphism UI & Redis Cache
|
This is a very large update with a major panel refactor. I think involving the dev community would be the best way to validate this change before moving forward. Here is the demo version of the panel: Credentials: admin | admin Thanks a lot for your time and support 🙌 |
|
I understand that this is a very large update, and that’s exactly why I’m asking for your help. |
feat: add instruction and upd docker-compose file
|
Does this architecture really fits 3x-ui? It's great to have multi node capability, but seems it's too much of a refactor. Why does it impossible to use current subID as a somewhat pseudo-unique ID (no duplicates on generation). |
We discussed this architecture in detail together with the original author and came to the conclusion that yes — these changes are indeed critical and go far beyond a small refactor of the current 3x-ui design. At the same time, I’m not abandoning the original panel — I’ll continue supporting it with bug fixes and small improvements that fit its existing architecture. Regarding using the current subID as a pseudo-unique identifier: this approach works fine in a single-core / single-node setup, but it doesn’t scale to the scenario we’re targeting. So the fork is not about “making things more complex for no reason”, but about enabling a clean and predictable multi-node model that the current design was not built for. |
|
@konstpic do you know when the code will be opened for beta testing? Is there a build guide for the project? I could post about it on my end.
unavailable |
|
Hello! Please see my repo https://github.com/konstpic/3x-ui-new I periodic update images Now final stage beta testing |
0dc4df2 to
f0f98c7
Compare
Multi-Node Architecture, Client Management, HWID Tracking, Host Management, Glass Morphism UI & Redis Cache
Description
This pull request introduces a comprehensive architectural overhaul of the 3x-ui panel, adding support for distributed multi-node architecture, independent client management with many-to-many relationships, hardware ID tracking, host management for load balancing, a modern Glass Morphism UI theme, and Redis caching for improved performance.
What Changed?
1. Node Mechanism (Multi-Node Architecture)
Overview
The panel now supports distributed architecture with multiple worker nodes. Instead of running XRAY Core locally, the panel can manage multiple remote nodes running XRAY Core instances.
Node Registration and Interaction
Node Registration Process:
Adding a Node: Users can add nodes through the UI by providing:
Automatic API Key Validation: When adding or updating a node, the system:
Node Health Monitoring:
CheckNodeHealthJob)online(green),offline(orange),unknown(gray)Node Interaction
API Endpoints on Panel:
GET /panel/node/list- Get list of all nodesGET /panel/node/get/:id- Get information about a specific nodePOST /panel/node/add- Add a new node (with validation)POST /panel/node/update/:id- Update a node (supports partial updates)POST /panel/node/del/:id- Delete a nodePOST /panel/node/check/:id- Check health of a specific nodePOST /panel/node/checkAll- Check health of all nodesPOST /panel/node/reload/:id- Reload XRAY on a nodePOST /panel/node/reloadAll- Reload XRAY on all nodesGET /panel/node/status/:id- Get detailed status of a nodeNode Service API (on Worker Nodes):
POST /api/v1/apply- Apply XRAY configurationPOST /api/v1/reload- Reload XRAYPOST /api/v1/force-reload- Force reload XRAYGET /api/v1/status- Get XRAY statusGET /api/v1/stats- Get traffic statistics and online clientsGET /health- Health check endpoint (no authentication required)Configuration Synchronization:
Statistics Collection:
CollectNodeStatsJob)ClientEntitytable2. Client Entities (Many-to-Many with Inbounds)
Overview
Clients are now independent entities stored in a separate
client_entitiestable. A single client can be assigned to multiple inbounds, enabling flexible configuration management.Client Entity Structure
Many-to-Many Relationship
ClientInboundMapping Table:
How It Works:
ClientInboundMappingrecords are created/updatedInbound.Settingsis automatically regenerated from all assignedClientEntityrecordsBenefits:
API Endpoints
GET /panel/client/list- Get all clients for userGET /panel/client/get/:id- Get client by IDPOST /panel/client/add- Add new client (with inbound assignments)POST /panel/client/update/:id- Update client (updates all related inbounds)POST /panel/client/del/:id- Delete client (removes from all inbounds)3. Inbound Entities (Many-to-Many with Nodes)
Overview
Inbounds can now be assigned to multiple nodes, enabling load distribution and redundancy.
Inbound Structure
Many-to-Many Relationship
InboundNodeMapping Table:
How It Works:
NodeIdsarrayExample:
Work Modes
Single-Mode (Default):
Multi-Mode:
4. Host Management (Address Override for Load Balancing)
Overview
Hosts allow overriding the endpoint address in subscription links, useful for load balancing, CDN integration, or custom routing.
Host Structure
Many-to-Many Relationship
HostInboundMapping Table:
How It Works:
Example:
cdn.example.cominstead of192.168.1.100API Endpoints
GET /panel/host/list- Get all hosts for userGET /panel/host/get/:id- Get host by IDPOST /panel/host/add- Add new host (with inbound assignments)POST /panel/host/update/:id- Update hostPOST /panel/host/del/:id- Delete host5. HWID Tracking (Hardware ID Tracking)
Overview
HWID tracking allows limiting the number of devices that can simultaneously use a client account, preventing unauthorized credential sharing and controlling resource usage.
HWID Structure
How It Works
Registration Process:
x-hwidheader when requesting subscriptionHWIDEnabledis true andMaxHWIDis set, device limit is checkedclient_hw_idstableModes:
off- HWID tracking disabledclient_header- Explicit registration via header (recommended)ip_based- Generate HWID from IP (deprecated)Features:
API Endpoints
GET /panel/client/hwid/list/:clientId- Get all HWIDs for clientPOST /panel/client/hwid/register- Register HWID (via subscription request)POST /panel/client/hwid/del/:id- Delete HWIDPOST /panel/client/hwid/block/:id- Block HWIDPOST /panel/client/hwid/unblock/:id- Unblock HWIDBackground Jobs
CheckClientHWIDJob- Periodic check of HWID limits and status updates6. Glass Morphism UI Theme
Overview
A modern Glass Morphism design theme has been added to the panel, providing a sleek, translucent glass-like appearance with backdrop blur effects.
Features
Visual Design:
Theme Switching:
Implementation:
UI Components Updated:
Pages with Glass Morphism:
7. Redis Cache Integration
Overview
Redis caching has been integrated to significantly improve panel performance by caching frequently accessed data.
Cache Implementation
Cache Layer:
web/cache/cache.go- Cache interfaceweb/cache/redis.go- Redis implementationweb/cache/redisstore.go- Redis store for sessionsCached Data:
Cache Invalidation:
Middleware:
web/middleware/cache.go- Cache middleware for HTTP requestsPerformance Benefits
Configuration
Redis connection configured via environment variables or settings:
Database Changes
New Tables
client_entities- Client tableuser_id,email(unique per user),sub_idclient_inbound_mappings- Client-Inbound mapping(client_id, inbound_id)nodes- Node tableinbound_node_mappings- Inbound-Node mapping(inbound_id, node_id)client_hw_ids- HWID table(client_id, hwid)hosts- Host tablehost_inbound_mappings- Host-Inbound mapping(host_id, inbound_id)Updated Tables
inbounds- Settings now auto-generated from ClientEntityBackend (Go)
New Services
NodeService: Node management, health checks, API validationClientService: Client CRUD operations, inbound assignmentsClientHWIDService: HWID tracking and managementClientTrafficService: Client traffic statisticsHostService: Host management and subscription address overrideNew Controllers
NodeController: Node API endpointsClientController: Client API endpointsClientHWIDController: HWID API endpointsHostController: Host API endpointsNew Background Jobs
CheckNodeHealthJob: Health checks every 5 minutesCollectNodeStatsJob: Statistics collection every 30 secondsCheckClientHWIDJob: HWID limit checksUpdated Services
InboundService: Updated for multi-node and client entity supportXrayService: Multi-node configuration distributionSubService: Node address and host override supportServerService: Node availability in system statusFrontend (Vue.js/HTML)
New Pages
nodes.html: Node management interfaceclients.html: Client management interfacehosts.html: Host management interfaceNew Modals
node_modal.html: Node add/edit modalclient_entity_modal.html: Client add/edit modalhost_modal.html: Host add/edit modalUpdated Pages
inbounds.html: Multi-node selection, client entity integrationindex.html: Nodes availability speedometer, Glass Morphismsettings.html: Multi-Node mode toggle, Glass Morphism settingsUpdated Components
aThemeSwitch.html: Glass Morphism toggleaSidebar.html: Glass Morphism stylingaClientTable.html: Client entity displayNode Service (New Component)
Structure
Features
Localization
Technical Details
Architecture
nodeIdfieldSecurity
Performance
Type of Changes
Affected Parts of Application
Testing
Migration
When updating an existing installation:
Notes