Skip to content

Feat/desktop in container - #5

Merged
Fazmin merged 3 commits into
Fazmin:mainfrom
user17286439:feat/desktop-in-container
Nov 1, 2026
Merged

Fazmin merged 3 commits into
Fazmin:mainfrom
user17286439:feat/desktop-in-container

Conversation

@user17286439

Copy link
Copy Markdown
Contributor

Summary

Adds Dockerfile.desktop so you can try the desktop app without installing it: it runs in a container and you use it from the browser over noVNC at 127.0.0.1:6080. The builds aren't signed yet, so I wanted to test it in a sandbox first. Also fixes the headless Dockerfile, which wasn't copying xtask and so failed before building anything.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New tool (adds a new MCP tool)
  • New API integration (adds a new external data source)
  • Desktop UI change
  • Local model / agent change
  • AI provider / Settings change (OpenAI, Anthropic, Gemini)
  • Performance improvement
  • Documentation update
  • Dependency update
  • Breaking change

Related issue

Closes #

Testing

  • I have added Rust unit tests for new behaviour (cargo test -p cve-core -p cve-server)
  • I have verified private IP blocking for any new network tools
  • I have run cargo test -p cve-core -p cve-server and cargo check -p cve-intel-desktop
  • I have tested with at least one surface (desktop app, CLI, REST, or an MCP client)

API keys

  • Any new API keys are documented in .env.example with instructions
  • New sources are added to the source catalog (crates/cve-core/src/sources.rs) and README.md
  • The tool degrades gracefully when the key is missing

Checklist

  • Business logic lives in cve-core; adapters (MCP/REST/CLI/Tauri) stay thin
  • Input validation uses the existing validator utilities
  • Private/reserved IPs are blocked for any network lookup tools
  • No API keys or sensitive data appear in logs, cache, or responses
  • Any change to what is sent to a cloud AI provider is disclosed in README.md and SECURITY.md
  • I have read CONTRIBUTING.md
  • README.md tool/source catalog is updated if a new tool or source was added

xtask is a workspace member, so cargo must load its manifest even when
building only cve-server.
Dockerfile.desktop builds the Tauri app on Linux and runs it on Xvfb,
served to the browser through x11vnc + noVNC on 127.0.0.1:6080. Lets
people use the GUI without installing it on the host.

- Own ignore file: the default .dockerignore drops the UI and icons.
- LTO off for this image: the fat-LTO link OOMs a 6 GB Podman VM.

@Fazmin Fazmin left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for putting this together! Being able to try the desktop app in a throwaway container is a really nice option while the builds still aren't signed, and good catch on the headless Dockerfile. It's been broken since xtask joined the workspace, so that fix alone is worth having.

There's one thing I'd like changed before I merge: x11vnc runs with -nopw. Publishing on 127.0.0.1 keeps it off the network, but websockify doesn't check the Origin header. Any web page open in the same browser can open a WebSocket to ws://127.0.0.1:6080 and drive the app, and the app has the API keys from .env loaded. The same is true for anyone on the LAN if someone leaves the 127.0.0.1: off the -p flag. Could the container generate a random VNC password at start-up (or take one from something like VNC_PASSWORD) and print it to the log? noVNC prompts for it, so it's only one extra step for whoever's using it. A line in the README about it would be great too.

One small thing, not blocking: if Xvfb fails to start, the until [ -e /tmp/.X11-unix/X99 ] loop spins forever without saying anything. A timeout with an error message would make that much easier to debug.

Happy to merge once the password is in. Thanks again!

websockify skips Origin checks, so with -nopw any page open in the browser
could drive the app over ws://127.0.0.1:6080. Use VNC_PASSWORD if set,
otherwise generate one and print it to the log.

- Fail after 10s with an error if Xvfb never creates the display.
@user17286439

Copy link
Copy Markdown
Contributor Author

Hello @Fazmin,
Thanks for the careful review, and good catch on the Origin header.

Pushed in d12a16b:

  • VNC password: -nopw is gone. The container uses VNC_PASSWORD if you set it. Otherwise it generates a random 8-character one and prints it to the log. If the one you set is longer than 8 characters, it warns, because VNC only checks the first 8. x11vnc reads the password from a file that's deleted straight after, and the variable is removed from the environment before the app starts. There's also a comment saying why -nopw must not come back.
  • README: two bullets on where to find the password and why to keep 127.0.0.1: in the -p flag.
  • Xvfb timeout: if the display doesn't show up within 10 seconds, it prints an error and exits with code 1 instead of hanging.

I tested it with the full image. Over the WebSocket on 6080, sent with a foreign Origin header, the server only offers password login. A wrong password is rejected and the logged one is accepted. I also made Xvfb fail on purpose, and the container exits after 10 seconds with the error message.

Let me know if you'd like anything else changed.

@Fazmin
Fazmin merged commit 0156df6 into Fazmin:main Nov 1, 2026
5 checks passed
@Fazmin

Fazmin commented Nov 1, 2026

Copy link
Copy Markdown
Owner

Merged! Thank you so much for this, and for testing it so thoroughly with the full image and a foreign Origin. It's a really nice way for people to try the app safely. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants