Skip to content

Commit f3e3cfd

Browse files
committed
fix(docker): single-server all-in-one panel with cores + local node
#2 Docker install now actually serves proxy traffic out of the box. New panel-aio image bundles xray + sing-box; compose runs the panel (and Caddy) with host networking so the in-process local node binds the proxy inbound ports directly on the host — matching the native single-server model. db/redis publish to 127.0.0.1; the installer writes LOCAL_NODE_HOST; Caddy upstream is configurable (PANEL_UPSTREAM) for host mode. The lean panel target remains for multi-node fleets.
1 parent 047dbf4 commit f3e3cfd

15 files changed

Lines changed: 600 additions & 84 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ the offender (reversible).
307307
| Topic | Link |
308308
|-------|------|
309309
| API Reference (OpenAPI 3.0) | [`docs/openapi.yaml`](docs/openapi.yaml) |
310+
| Protocols & Config Examples | [`docs/protocols.md`](docs/protocols.md) |
310311
| Environment Variables | [`.env.example`](.env.example) |
311312
| Docker Deploy | [`deploy/`](deploy/) |
312313
| CI/CD | [`.github/workflows/`](.github/workflows/) |

deploy/Caddyfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@
2020
# /index.html before reverse_proxy runs, breaking the API. reverse_proxy
2121
# upgrades WebSocket/SSE transparently.
2222
handle /api/* {
23-
reverse_proxy panel:8080
23+
reverse_proxy {$PANEL_UPSTREAM:panel:8080}
2424
}
2525
handle /sub/* {
26-
reverse_proxy panel:8080
26+
reverse_proxy {$PANEL_UPSTREAM:panel:8080}
2727
}
2828
handle /health {
29-
reverse_proxy panel:8080
29+
reverse_proxy {$PANEL_UPSTREAM:panel:8080}
3030
}
3131

3232
# Everything else is the SPA, with client-side routing fallback.

deploy/Dockerfile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,26 @@ RUN apk add --no-cache curl tar && \
3737
tar -xzf /tmp/sb.tgz -C /tmp && \
3838
mv /tmp/sing-box-*/sing-box /usr/local/bin/sing-box && chmod +x /usr/local/bin/sing-box
3939

40-
# ---- panel (control plane) ----
40+
# ---- panel (control plane, lean — for multi-node setups) ----
4141
FROM gcr.io/distroless/static-debian12 AS panel
4242
COPY --from=builder /out/panel /usr/local/bin/panel
4343
COPY --from=builder /src/migrations /migrations
4444
EXPOSE 8080
4545
USER nonroot:nonroot
4646
ENTRYPOINT ["/usr/local/bin/panel"]
4747

48+
# ---- panel-aio (all-in-one: panel + xray + sing-box for a single-server,
49+
# in-process local node). Used by the default single-server compose. ----
50+
FROM alpine:3.20 AS panel-aio
51+
RUN apk add --no-cache ca-certificates
52+
COPY --from=builder /out/panel /usr/local/bin/panel
53+
COPY --from=xray /xray/xray /usr/local/bin/xray
54+
COPY --from=singbox /usr/local/bin/sing-box /usr/local/bin/sing-box
55+
COPY --from=xray /xray/*.dat /etc/vortex/assets/
56+
ENV XRAY_LOCATION_ASSET=/etc/vortex/assets
57+
EXPOSE 8080
58+
ENTRYPOINT ["/usr/local/bin/panel"]
59+
4860
# ---- node (agent + xray-core) ----
4961
FROM alpine:3.20 AS node
5062
RUN apk add --no-cache ca-certificates && adduser -D -u 10001 vortex

deploy/compose.yml

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,92 @@
1-
# Full-stack VortexUI deployment: panel + Postgres/TimescaleDB + Redis + one node.
2-
# Generate mTLS certs first (make certs → deploy/certs), then:
1+
# Single-server VortexUI (Docker): an all-in-one panel that runs xray + sing-box
2+
# as an in-process local node, fronted by Caddy, with Postgres/TimescaleDB +
3+
# Redis. The panel and web use host networking so the proxy inbound ports (chosen
4+
# per inbound) bind directly on the host — the same model as a native install.
5+
#
36
# docker compose -f deploy/compose.yml up --build -d
47
# docker compose -f deploy/compose.yml exec panel /usr/local/bin/panel admin create \
58
# --username root --password 'change-me' --sudo
9+
#
10+
# For a multi-node fleet, run the lean `panel` target instead and add nodes in
11+
# the UI (each node a separate `vortex-node` install).
612
services:
713
db:
814
image: timescale/timescaledb:latest-pg16
915
environment:
1016
POSTGRES_USER: vortex
1117
POSTGRES_PASSWORD: ${DB_PASSWORD:-vortex}
1218
POSTGRES_DB: vortex
19+
ports:
20+
- "127.0.0.1:5432:5432" # reachable by the host-networked panel
1321
volumes:
1422
- db-data:/var/lib/postgresql/data
1523
healthcheck:
1624
test: ["CMD-SHELL", "pg_isready -U vortex"]
1725
interval: 5s
1826
timeout: 3s
1927
retries: 10
28+
restart: unless-stopped
2029

2130
redis:
2231
image: redis:7-alpine
2332
command: ["redis-server", "--save", "", "--appendonly", "no"]
33+
ports:
34+
- "127.0.0.1:6379:6379"
2435
healthcheck:
2536
test: ["CMD", "redis-cli", "ping"]
2637
interval: 5s
2738
timeout: 3s
2839
retries: 10
40+
restart: unless-stopped
2941

3042
panel:
3143
build:
3244
context: ..
3345
dockerfile: deploy/Dockerfile
34-
target: panel
46+
target: panel-aio
47+
network_mode: host # bind :8080 + the proxy inbound ports directly on the host
3548
depends_on:
3649
db: {condition: service_healthy}
3750
redis: {condition: service_healthy}
3851
environment:
3952
VORTEX_HTTP_ADDR: ":8080"
40-
VORTEX_DATABASE_URL: "postgres://vortex:${DB_PASSWORD:-vortex}@db:5432/vortex?sslmode=disable"
41-
VORTEX_REDIS_URL: "redis://redis:6379/0"
53+
VORTEX_DATABASE_URL: "postgres://vortex:${DB_PASSWORD:-vortex}@127.0.0.1:5432/vortex?sslmode=disable"
54+
VORTEX_REDIS_URL: "redis://127.0.0.1:6379/0"
4255
VORTEX_JWT_SECRET: ${JWT_SECRET:?set JWT_SECRET (openssl rand -hex 32)}
4356
VORTEX_TLS_CERT: /certs/panel.crt
4457
VORTEX_TLS_KEY: /certs/panel.key
4558
VORTEX_TLS_CA: /certs/ca.crt
59+
# In-process local node (single-server): the panel runs the core itself.
60+
VORTEX_LOCAL_NODE: "true"
61+
VORTEX_LOCAL_NODE_NAME: local
62+
VORTEX_LOCAL_NODE_HOST: ${LOCAL_NODE_HOST:-127.0.0.1}
63+
VORTEX_CORE: ${CORE:-xray}
64+
VORTEX_CORE_BIN: /usr/local/bin/${CORE:-xray}
65+
VORTEX_CORE_CONFIG: /etc/vortex/local-core.json
66+
VORTEX_CORE_API_PORT: "10085"
4667
volumes:
4768
- ./certs:/certs:ro
48-
# The panel is reached through the web reverse proxy; expose it directly only
49-
# if you want to hit the raw API. Uncomment to publish on the host:
50-
# ports:
51-
# - "8080:8080"
52-
expose:
53-
- "8080"
5469
restart: unless-stopped
5570

56-
# Web UI: serves the SPA, reverse-proxies /api + /sub to the panel, and
57-
# terminates TLS. With SITE_ADDRESS set to a domain, Caddy auto-provisions a
58-
# Let's Encrypt certificate; otherwise it serves plain HTTP on WEB_PORT.
71+
# Web UI: serves the SPA, reverse-proxies /api + /sub to the panel on the host,
72+
# and terminates TLS. With SITE_ADDRESS a domain, Caddy auto-provisions a
73+
# Let's Encrypt certificate.
5974
web:
6075
build:
6176
context: ..
6277
dockerfile: deploy/web.Dockerfile
78+
network_mode: host
6379
depends_on:
6480
- panel
6581
environment:
6682
SITE_ADDRESS: ${SITE_ADDRESS:-:80}
6783
ACME_EMAIL: ${ACME_EMAIL:-}
68-
ports:
69-
- "${WEB_PORT:-80}:80"
70-
- "443:443"
84+
PANEL_UPSTREAM: 127.0.0.1:8080
7185
volumes:
7286
- caddy-data:/data
7387
- caddy-config:/config
7488
restart: unless-stopped
7589

76-
node:
77-
build:
78-
context: ..
79-
dockerfile: deploy/Dockerfile
80-
target: node
81-
environment:
82-
VORTEX_NODE_LISTEN: ":50051"
83-
VORTEX_CORE: xray
84-
VORTEX_TLS_CERT: /certs/node.crt
85-
VORTEX_TLS_KEY: /certs/node.key
86-
VORTEX_TLS_CA: /certs/ca.crt
87-
volumes:
88-
- ./certs:/certs:ro
89-
ports:
90-
- "50051:50051"
91-
9290
volumes:
9391
db-data:
9492
caddy-data:

0 commit comments

Comments
 (0)