kurv 0.0.4

A process manager to daemonize commands and programs. Inspired by pm2, but lightweight and not as featureful.
<p align="center"><img src=".github/icon-logo-h64.svg" height="128"></p>

<br>
<br>
<br>

<p align="center">๐ค๐ฎ๐ซ๐ฏ is a process manager, mainly for Node.js and Python applications. It's written in <code>Rust</code>. It daemonizes your apps so that they can run in the background. It also restarts them if they crash.
</p>

<p align="center"><img align="center" alt="Crates.io Version" src="https://img.shields.io/crates/v/kurv?style=flat-square&color=%2318181b&link=https%3A%2F%2Fcrates.io%2Fcrates%2Fkurv"></p>

<p align="center"><a href="https://kurv.lucode.dev" target="_blank">Docs</a> โ€ข <a href="https://crates.io/crates/kurv" target="_blank">Crate</a> โ€ข <a href="https://github.com/lucas-labs/kurv/tree/master?tab=readme-ov-file#readme" target="_blank">Readme</a></p>

<br>
<br>
<br>

> [!WARNING]  
> Heads up, this project is my Rust-learning playground and not production-ready yet:
> 
>   - I built this because my apps needed a process manager, and I had an itch to learn Rust. So, here it is... my first Rust project!
>   - No tests yet (oops!)
>   - Tested only on Windows 11
>   - Rust newbie alert! ๐Ÿšจ
>   - Using it for my own projects, but not on a grand scale


## Why ๐ค๐ฎ๐ซ๐ฏ?



So, why the name ๐ค๐ฎ๐ซ๐ฏ? Well, it means "basket" in many languages I don't speak, like Norwegian (but it sounded cool ๐Ÿ˜„). Think of ๐ค๐ฎ๐ซ๐ฏ as a basket for your apps. In kurv, we call each deployed app as an `egg`. So, let's go and collect some eggs ๐Ÿฅš in your basket ๐Ÿงบ.


## Installation

> [!NOTE] 
> ๐ค๐ฎ๐ซ๐ฏ can run either as a server or as a CLI client, using the same binary. 
>
> The server is responsible for managing the eggs, while the client is used to interact with the server and tell it what to do or ask it for information.

### Download binaries

Download the latest release [from GitHub](https://github.com/lucas-labs/kurv/releases). 

### crates.io

You can also install it from [crates.io](https://crates.io/crates/kurv) using `cargo`:

```bash
cargo install kurv
```

## Usage 

![kurv usage](.github/kurv.gif)


### Start the server

To get the server rolling, type:

```bash
kurv server
```

> [!IMPORTANT]
> - ๐ค๐ฎ๐ซ๐ฏ will create a file called `.kurv` where it will store the current
> state of the server. The file will be created in the same directory where
> the binary is located or in the path specified by the `KURV_HOME_KEY`
> environment variable.
>
> - since ๐ค๐ฎ๐ซ๐ฏ can be used both as a server and as a client, if you want
> to run it as a server, you need to set the `KURV_SERVER` environment
> to `true`. This is just a safety measure to prevent you from running
> the server when you actually want to run the client.
> To bypass this, you can use the `--force` flag (`kurv server --force`)

### Collect some ๐Ÿฅš
To deploy/start/daemonize an app (collect an egg), do:

```bash
kurv collect <egg-cfg-path>
```

The path should point to a YAML file that contains the configuration for the egg. 

It should look something like this:

```yaml title="myegg.kurv"
name: fastapi # the name of the egg / should be unique
command: poetry # the command/program to run
args: # the arguments to pass to the command
  - run
  - serve
cwd: /home/user/my-fastapi-app # the working directory in which the command will be run
env: # the environment variables to pass to the command
  FASTAPI_PORT: 8080
```

This will run the command `poetry run serve` in `/home/user/my-fastapi-app` with the environment variable `FASTAPI_PORT` set to `8080`.

If for some reason, the command/program crashes or exits, ๐ค๐ฎ๐ซ๐ฏ will revive it!

### Show me my eggs

If you want a summary of the current state of your eggs, run:

```zsh
$ kurv list

๐Ÿฅš eggs snapshot

โ•ญโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ # โ”‚ pid   โ”‚ name      โ”‚ status  โ”‚ โ†บ โ”‚ uptime โ”‚
โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1 โ”‚ 35824 โ”‚ fastapi   โ”‚ running โ”‚ 0 โ”‚   1s   โ”‚
โ”‚ 2 โ”‚ 0     โ”‚ fastapi-2 โ”‚ stopped โ”‚ 0 โ”‚   -    โ”‚
โ•ฐโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
```

For details on a specific egg:

``` sh
$ kurv egg <egg:name|id|pid>
```

This will show you the egg's configuration, process details, etc.

### Stop an egg

To halt an egg without removing it:

``` sh
$ kurv stop <egg:name|id|pid>
```

This will stop the process but keep its configuration in the basket in case
you want to start it again later.

### Remove an egg

To actually remove an egg, run:

``` sh
$ kurv remove <egg:name|id|pid>
```

It will stop the process and remove the egg from the basket.

### Restart

If you need the process to be restarted, run:

``` sh
$ kurv restart <egg:name|id|pid>
```

### To do list

๐ค๐ฎ๐ซ๐ฏ is still under development. Here are some of the things I'm planning to add:

- [ ] Simple password protection
- [ ] Remotely manage eggs
- [ ] SSL support
- [ ] Handle cors correctly

And last but not least:

- [ ] Tests (I know, I know... ๐Ÿคญ)

#### Plugins / extensions

Since ๐ค๐ฎ๐ซ๐ฏ is a process manager, we can easily extend its functionality by adding 
plugin eggs (simple eggs managed by ๐ค๐ฎ๐ซ๐ฏ itself that provide additional functionality). 

Here are some ideas I have for plugins:

- [ ] Web UI
- [ ] Log Viewer 
- [ ] Log Rotation

### Inspiration

#### pm2
Inspired by the robust process manager, [pm2](https://pm2.keymetrics.io/), my goal with ๐ค๐ฎ๐ซ๐ฏ was to create a lightweight alternative. Not that pm2 is a resource hog, but I found myself in a server with extremely limited resources. Plus, I was itching for an excuse to dive into Rust, and voila, ๐ค๐ฎ๐ซ๐ฏ was born.

#### eggsecutor
Derived from [eggsecutor](https://github.com/lucas-labs/kurv), ๐ค๐ฎ๐ซ๐ฏ adopted the whimsical term "eggs" to represent deployed applications.

#### pueue
Insights from [pueue](https://github.com/Nukesor/pueue) were instrumental in helping me understand how to manage processes in Rust.


<br><br>

-------
With ๐Ÿง‰ from Argentina ๐Ÿ‡ฆ๐Ÿ‡ท