Give Others Easy Access to Your VMs with Unraid VM CP

Recommended Posts

Hi everyone,

I'm excited to share with you a plug-in I'm currently developing called Unraid VM CP (Unraid Virtual Machine Control Panel). The plug-in will allow you to easily control your VMs from a simple, intuitive interface. I'm building this plug-in because I've encountered some issues with the Unraid interface and want to make it more accessible for non-techy users.

You can find the design of the project here: The interface is designed to be simple and easy to use, even for those who are not technically inclined.

My goal is to make Unraid VM CP the go-to plug-in for anyone looking to control their VMs with ease. As a gamer, I use Unraid to run two gaming VMs, and I wanted to create a solution that would allow my GF to turn on and off her VM without using the Unraid interface, which can be complex and difficult to navigate.

Unraid VM CP is built on NodeJS, Solidjs, and Docker, and is open source. I'm currently the sole developer working on this project, and I'm making steady progress. The backend is nearly complete, and I'm starting work on the frontend.

I'm reaching out to the Unraid community for feedback and suggestions. If you have any thoughts or ideas, please don't hesitate to let me know. You can find the project on GitHub here:

Edited by StevenRafferty
Fixed mistake
  • Like 4
Link to comment
21 minutes ago, GRRRRRRR said:

I disagree with everything which is not pure Rust and WebAssembly.


Can you explain to me right now, why TF you need all that overhead, to flip a switch a push a button, that in it's nature is either 0 or a 1.


We must fight for minimalism in the control plane.


If I see you bloating the control plane, I kick your ass back to abacus times.


What are your current challenges with the whole thing, maybe I can help with something?


I’ll address each question.

Q: I disagree with everything which is not pure Rust and WebAssembly

A: I hope this is sarcasm 😂


Q: Can you explain to me right now, why TF you need all that overhead, to flip a switch a push a button, that in it's nature is either 0 or a 1.

A: I don’t think you’ve properly read this post or looked at the relevant links. 

Q: We must fight for minimalism in the control plane.

A: This is a plug-in addressed in the post, you can install it or don’t.


Q: If I see you bloating the control plane, I kick your ass back to abacus times.

A: Again read the post


Q: What are your current challenges with the whole thing, maybe I can help with something?

A: As I stated in the post, I want suggestions and feedback, so if you have any ideas just let me know and ensure it is constructive. 

next time please go through the post before commenting loads of stuff that has already been answered, thanks.

Link to comment

Well for one I see many of you are younger and susceptible to doing things in a trendy but less functional way, which will bite us all in the ass later, in terms of who knows what unforeseen edge cases and security swiss cheezing the entire system.


This is why I am shouting at you about how it should be better. Such as not using JavaScript.


Redirecting back to an unstable reasoning for doing things is not an answer to my fundamental questions to you.


State the facts truthful as they are or be destroyed in seconds in any argument.


I do not think that you or the function need my "constructive" observations. I think you all need you ass kicked back to the root of things for you to realize to do things properly.


I am not saying you are a bad person, or have done anything very wrong.


If there is not yet an easy to use optimized 'framework' for what you wanted to do then do it in the bloated framework, however when I ask you WHY TF you say the truth and no BS.


The constructive you are looking for is - good job, Excellent job. But when you are done with the function, I still ask you uncomfortable questions.


What kind of CI/CD security practices are going on with the community plugins anyway?



Link to comment
  • 2 weeks later...
10 hours ago, gsumpster said:

I really like this idea, I share my VMs with family but have them text me to spin something up at the moment, hoping this can replace that manual work.


I'd love to spend some time contributing if you have any todos that you'd like another pair of hands on!

I am glad this project makes your life simpler, I'll create some issues in the near future so please keep posted either on Github repo or Unraid forum :)

Link to comment
7 hours ago, Kilrah said:

One thing that is sketch is having to give the unraid password in the template, that means it's stored in cleartext on the flash.

Would be good to find a way to log in to unraid in the webui and store a login cookie in appdata or such.

I agree with you, I am open to any suggestions to make this app more secure and safe.
I did have an idea to solve this, the idea would be when you setup the app you must first create an admin user (just for the app) then you'd be able to add your unraid login details on to my app where I'd store them in the db.

Link to comment
  • 4 months later...

 1st a note about UI - the notifications cover the log out. Please move them somewhere


Really liked the idea but it did not work... Maybe it is due to self signed SSL certificate used for unraid connect but yea I have no idea atm xD


Here is the log hope you can help. I really need an easy way let users start their own VMs

[0]       [Symbol(res)]: [TLSWrap],
[0]       [Symbol(verified)]: false,
[0]       [Symbol(pendingSession)]: null,
[0]       [Symbol(async_id_symbol)]: 777,
[0]       [Symbol(kHandle)]: null,
[0]       [Symbol(lastWriteQueueSize)]: 248,
[0]       [Symbol(timeout)]: null,
[0]       [Symbol(kBuffer)]: null,
[0]       [Symbol(kBufferCb)]: null,
[0]       [Symbol(kBufferGen)]: null,
[0]       [Symbol(kCapture)]: false,
[0]       [Symbol(kSetNoDelay)]: false,
[0]       [Symbol(kSetKeepAlive)]: true,
[0]       [Symbol(kSetKeepAliveInitialDelay)]: 60,
[0]       [Symbol(kBytesRead)]: 0,
[0]       [Symbol(kBytesWritten)]: 248,
[0]       [Symbol(connect-options)]: [Object]
[0]     },
[0]     _header: 'POST /login HTTP/1.1\r\n' +
[0]       'Accept: */*\r\n' +
[0]       'Content-Type: application/x-www-form-urlencoded\r\n' +
[0]       'User-Agent: axios/1.3.3\r\n' +
[0]       'Content-Length: 32\r\n' +
[0]       'Accept-Encoding: gzip, compress, deflate, br\r\n' +
[0]       'Host:\r\n' +
[0]       'Connection: close\r\n' +
[0]       '\r\n',
[0]     _keepAliveTimeout: 0,
[0]     _onPendingData: [Function: nop],
[0]     agent: Agent {
[0]       _events: [Object: null prototype],
[0]       _eventsCount: 2,
[0]       _maxListeners: undefined,
[0]       defaultPort: 443,
[0]       protocol: 'https:',
[0]       options: [Object: null prototype],
[0]       requests: [Object: null prototype] {},
[0]       sockets: [Object: null prototype],
[0]       freeSockets: [Object: null prototype] {},
[0]       keepAliveMsecs: 1000,
[0]       keepAlive: false,
[0]       maxSockets: Infinity,
[0]       maxFreeSockets: 256,
[0]       scheduling: 'lifo',
[0]       maxTotalSockets: Infinity,
[0]       totalSocketCount: 1,
[0]       maxCachedSessions: 100,
[0]       _sessionCache: [Object],
[0]       [Symbol(kCapture)]: false
[0]     },
[0]     socketPath: undefined,
[0]     method: 'POST',
[0]     maxHeaderSize: undefined,
[0]     insecureHTTPParser: undefined,
[0]     path: '/login',
[0]     _ended: false,
[0]     res: null,
[0]     aborted: false,
[0]     timeoutCb: null,
[0]     upgradeOrConnect: false,
[0]     parser: null,
[0]     maxHeadersCount: null,
[0]     reusedSocket: false,
[0]     host: '',
[0]     protocol: 'https:',
[0]     [Symbol(kCapture)]: false,
[0]     [Symbol(kBytesWritten)]: 0,
[0]     [Symbol(kEndCalled)]: true,
[0]     [Symbol(kNeedDrain)]: false,
[0]     [Symbol(corked)]: 0,
[0]     [Symbol(kOutHeaders)]: [Object: null prototype] {
[0]       accept: [Array],
[0]       'content-type': [Array],
[0]       'user-agent': [Array],
[0]       'content-length': [Array],
[0]       'accept-encoding': [Array],
[0]       host: [Array]
[0]     },
[0]     [Symbol(kUniqueHeaders)]: null
[0]   },
[0]   cause: Error: self signed certificate
[0]       at TLSSocket.onConnectSecure (node:_tls_wrap:1539:34)
[0]       at TLSSocket.emit (node:events:513:28)
[0]       at TLSSocket._finishInit (node:_tls_wrap:953:8)
[0]       at TLSWrap.ssl.onhandshakedone (node:_tls_wrap:734:12) {
[0]   }
[0] }
[1]  HTTP  7/25/2023 1:26:20 AM GET /src/assets/favicon.ico
[1]  HTTP  7/25/2023 1:26:20 AM Returned 304 in 1 ms


Link to comment

Actually scratch that It worked. Just had to put the full string instead of IP


Also perhaps you can expand this to work with dockers as well.

Edited by Laov
Link to comment
  • 4 weeks later...

This is Almost exactly what I needed.
Any Plans to add the Start VNC option to other users apart from root. That would be exactly what I need in my specific use case.

I'm also having some issues when I try to access this docker from outside of my local network (using Kemp Loadmaster as my reverse Proxy). I can reach the login page, but when I enter my creds and hit login, nothing happens.

Link to comment
  • 3 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.