feat: add Linux server operational delivery assets

This commit is contained in:
2026-09-11 05:52:26 +00:00
parent 409b64a2fb
commit c709b27e5e
12 changed files with 412 additions and 50 deletions
+28
View File
@@ -0,0 +1,28 @@
# Production-shaped RVBox Linux-server Compose deployment
This directory is intentionally separate from the development/toolchain Compose
files. It starts only the Linux server and nginx TLS terminator; Windows clients
connect through nginx at `/v1/agent`.
Before the first start, create `server.toml` from the authoritative example and
prepare writable state directories for the runtime image UID/GID `65532`:
```sh
cp ../../docs/examples/server.toml server.toml
install -d -m 0700 -o 65532 -g 65532 state run
chmod 0640 server.toml
```
Set `RVBOX_SERVER_IMAGE` to an immutable image reference, plus absolute paths
for `RVBOX_TLS_CERT` and `RVBOX_TLS_KEY`. The TLS key must be readable by Docker
but should remain inaccessible to ordinary host users. Validate before start:
```sh
docker compose -f compose.yaml config
docker compose -f compose.yaml up -d
```
Only `state/` and `run/` are persistent/owned deployment data. Back up the
whole `state/` directory while the server is stopped; `run/` contains only the
ephemeral local control socket. Do not publish, proxy, or enable JSON-RPC except
for intentional loopback debugging.
+68
View File
@@ -0,0 +1,68 @@
# Production-shaped Linux server deployment. Copy server.toml from docs/examples/
# and supply the TLS certificate/key as read-only files.
#
# `rvbox-server` stays private to this Compose network: nginx is the only public
# listener. JSON-RPC remains disabled in server.toml by default.
name: rvbox-server
services:
server:
image: "${RVBOX_SERVER_IMAGE:?set RVBOX_SERVER_IMAGE to a pinned rvbox-server image}"
restart: unless-stopped
command: ["--config", "/etc/rvbox/server.toml"]
read_only: true
tmpfs:
- /tmp:mode=1777,size=32m
volumes:
- type: bind
source: ./server.toml
target: /etc/rvbox/server.toml
read_only: true
- type: bind
source: ./state
target: /var/lib/rvbox-server
- type: bind
source: ./run
target: /run/rvbox
expose:
- "6899"
- "6901"
healthcheck:
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:6901/readyz"]
interval: 15s
timeout: 5s
retries: 4
start_period: 20s
security_opt:
- no-new-privileges:true
cap_drop: ["ALL"]
nginx:
image: nginx:1.27.5-alpine
restart: unless-stopped
read_only: true
depends_on:
server:
condition: service_healthy
ports:
- "${RVBOX_HTTPS_PORT:-443}:443"
tmpfs:
- /var/cache/nginx:uid=101,gid=101,mode=0755,size=16m
- /var/run:uid=101,gid=101,mode=0755,size=4m
volumes:
- type: bind
source: ./nginx.conf
target: /etc/nginx/conf.d/default.conf
read_only: true
- type: bind
source: ${RVBOX_TLS_CERT:?set RVBOX_TLS_CERT to the public certificate path}
target: /etc/nginx/tls/server.pem
read_only: true
- type: bind
source: ${RVBOX_TLS_KEY:?set RVBOX_TLS_KEY to the private key path}
target: /etc/nginx/tls/server-key.pem
read_only: true
security_opt:
- no-new-privileges:true
cap_drop: ["ALL"]
cap_add: ["NET_BIND_SERVICE"]
+42
View File
@@ -0,0 +1,42 @@
# TLS terminator for the RVBox agent WebSocket. Do not add a JSON-RPC route:
# its deliberately unauthenticated debug adapter is loopback-only by default.
map $http_upgrade $rvbox_connection_upgrade {
default upgrade;
'' close;
}
upstream rvbox_agent {
server server:6899;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/nginx/tls/server.pem;
ssl_certificate_key /etc/nginx/tls/server-key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location = /v1/agent {
proxy_pass http://rvbox_agent;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $rvbox_connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 75s;
proxy_send_timeout 15s;
proxy_buffering off;
}
location = /livez {
proxy_pass http://server:6901/livez;
}
location = /readyz {
proxy_pass http://server:6901/readyz;
}
location / {
return 404;
}
}
+34
View File
@@ -0,0 +1,34 @@
[Unit]
Description=RVBox server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=rvbox
Group=rvbox
ExecStartPre=/usr/local/bin/rvbox-server --check-config --config /etc/rvbox/server.toml
ExecStart=/usr/local/bin/rvbox-server --config /etc/rvbox/server.toml
Restart=on-failure
RestartSec=5s
TimeoutStopSec=35s
WorkingDirectory=/var/lib/rvbox-server
StateDirectory=rvbox-server
RuntimeDirectory=rvbox
RuntimeDirectoryMode=0750
UMask=0077
LimitNOFILE=65536
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
ReadWritePaths=/var/lib/rvbox-server /run/rvbox
[Install]
WantedBy=multi-user.target