Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dev-server-provision/configurator/tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def _full_config(self, **overrides):
"email": "admin@example.com",
"cloudflare_api_token": "a" * 40,
"cloudflare_zone_id": "a" * 32,
"coder_admin_password": "TestPass123",
"enable_agent_copilot": False,
"enable_agent_claude": False,
"enable_agent_gemini": False,
Expand Down
2 changes: 1 addition & 1 deletion dev-server-provision/configurator/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def validate_coder_password(value: str) -> str | bool:
return True



def validate_api_key_optional(value: str) -> str | bool:
"""Accept empty or any non-whitespace string."""

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate_api_key_optional() claims to accept “empty or any non-whitespace string”, but it currently returns True for whitespace-only inputs as well. Either update the docstring to match behavior or implement the intended value.strip() check so whitespace-only isn’t treated as a valid key.

Suggested change
"""Accept empty or any non-whitespace string."""
"""Accept empty or any non-whitespace string."""
if value == "":
return True
if not value.strip():
return "API key cannot be whitespace-only."

Copilot uses AI. Check for mistakes.
return True

Expand Down
65 changes: 58 additions & 7 deletions dev-server-provision/docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,66 @@ hcloud server create \
If your server does **not** support cloud-init (e.g. a dedicated/bare-metal
machine), use the one-liner installer instead:

1. Run the configurator and let it generate `RVSconfig.yml` (offered after
`cloud-init.yaml`).
2. SSH into the server and run:
```bash
curl -fsSL https://raw.githubusercontent.com/PhilippWu/RemoteVibeServer/main/install.sh | sudo bash
```

```bash
curl -fsSL https://raw.githubusercontent.com/PhilippWu/RemoteVibeServer/main/install.sh | sudo bash
```
The installer detects your config automatically through a smart priority chain —
no flags or arguments required:

#### Path 1 — Config already on disk *(zero prompts)*

If `/etc/dev-server/RVSconfig.yml` or `./RVSconfig.yml` already exists
(e.g. copied via SCP, or from a previous run), it is used directly.

```bash
scp RVSconfig.yml root@<SERVER_IP>:/etc/dev-server/
curl -fsSL .../install.sh | sudo bash # no prompts
```

Covers: re-runs, partial installs, pre-baked images.

#### Path 2 — Download from a URL

At the prompt, enter an `https://` URL pointing to your config (private Gist,
object-storage bucket, internal file server):

```
> https://gist.githubusercontent.com/you/abc.../raw/RVSconfig.yml
```

#### Path 3 — Paste YAML content *(previous default behavior)*

At the prompt, paste the full contents of your `RVSconfig.yml`, then press
**Ctrl-D** on an empty line.

```
> [paste YAML here, then Ctrl-D]
```

Generate the file locally first:

```bash
cd dev-server-provision && python -m configurator
```

#### Path 4 — Interactive wizard *(no prior config needed)*

Press **Enter** (empty line) at the prompt to launch the embedded setup wizard
— no local Python or configurator needed:

```
> [Enter]

RVS Setup Wizard
─────────────────
Step 1/4 — Network
Do you have a domain name? [y/N]: …
```

3. Paste the contents of `RVSconfig.yml` when prompted, then press **Ctrl-D**.
The wizard covers: domain/IP-only mode, Cloudflare DNS, admin password, and AI
agent selection. It writes `RVSconfig.yml` to disk before proceeding, so future
re-runs use **Path 1** automatically.

The script parses the YAML into `/etc/dev-server/env`, installs Docker, UFW,
fail2ban, and downloads the provisioning scripts — then runs `setup.sh`
Expand Down
Loading