5 ms·
Show HN: Servicer, pm2 alternative built on Rust and systemd
Servicer is a CLI to create and manage services on systemd. I have used pm2 in production and find it easy to use. However a lot of its functionality is specific to node.js, and I would prefer not to run my rust server as a fork of a node process. Systemd on the other hand has most of the things I need, but I found it cumbersome to use. There are a bunch of different commands and configurations- the .service file, systemctl to view status, journald to view logs which make systemd more complex to setup. I had to google for the a template and commands every time.
Servicer abstracts this setup behind an easy to use CLI, for instance you can use `ser create index.js --interpreter node --enable --start` to create a `.service` file, enable it on boot and start it. Servicer will also help if you wish to write your own custom `.service` files. Run `ser edit foo --editor vi` to create a service file in Vim. Servicer will provide a starting template so you don't need to google it. There are additional utilities like `ser which index.js` to view the path of the service and unit file.
```
Paths for index.js.ser.service:
+--------------+-----------------------------------------------------------+
| name | path |
+--------------+-----------------------------------------------------------+
| Service file | /etc/systemd/system/index.js.ser.service |
+--------------+-----------------------------------------------------------+
| Unit file | /org/freedesktop/systemd1/unit/index_2ejs_2eser_2eservice |
+--------------+-----------------------------------------------------------+
```
Servicer is daemonless and does not run in the background. It simply sets up systemd and gets out of the way. There are no forked services, everything is natively set up on systemd. You don't need to worry about resource consumption or servicer going down which will cause your app to stop.
Do give it a spin and review the codebase. The code is open source and MIT licensed- https://github.com/servicer-labs/servicer https://github.com/servicer-labs/servicer
- srivmutk 3y agoLooks nice! I always found working directly with systemd to manage persistent services a bit too cumbersome, although I can see how others may not have a problem with this.
- kitanata 3y ago[flagged]
- thomasfromcdnjs 3y agoI like the idea of this, will find something to run it on later.
- shardulaeer 3y agoAwesome, would really appreciate your feedback!
- MuffinFlavored 3y ago> Systemd on the other hand has most of the things I need, but I found it cumbersome to use Could you please expand on this? From what I understand, to use systemd to deploy a microservice is basically one file: # /etc/systemd/system/myservice.service [Unit] Description=My Microservice After=network.target [Service] ExecStart=/path/to/myservice Restart=always User=myuser Group=mygroup Environment=VARIABLE=value WorkingDirectory=/path/to/service/directory StandardOutput=syslog StandardError=syslog SyslogIdentifier=myservice [Install] WantedBy=multi-user.target Then, to "use" it: # reload systemd sudo systemctl daemon-reload # start service sudo systemctl start myservice # enable service at boot sudo systemctl enable myservice # check status sudo systemctl status myservice # check logs journalctl -u myservice What more advanced stuff were you trying to do that you ran into that made systemd seem cumbersome?
- ripley12 3y agoThat's 15 lines of configuration and 3 CLI commands to install a service. I have done this hundreds of times but I still need to keep a template around for unit files, I often forget to run `daemon-reload`, etc. I like systemd but I can see a lot of value in friendlier tools like this. What I really want is a TUI tool like Lazydocker for managing systemd services.
- shardulaeer 3y agoI built the tool simply to improve developer experience. Run `systemctl list-units` and the console is flooded with a wall of services, most of them are not mine. Run `ser status` and I only see the ones that I created. The activity state, CPU and memory usage is displayed so I don't need to run a separate command. hp@hp:~$ ser status +-----+-------------+----------+----------------+-------+--------+ | pid | name | active | enable on boot | cpu % | memory | +-----+-------------+----------+----------------+-------+--------+ | 0 | hello-world | inactive | false | 0 | 0 | +-----+-------------+----------+----------------+-------+--------+ | 0 | index.js | inactive | false | 0 | 0 | +-----+-------------+----------+----------------+-------+--------+ Another UX improvement is the template generation. I found myself googling it everytime. I f there is something more custom (etc sockets) I can use the `ser edit`, this will open nano with a pre-populated template that I can edit. Finally why limit oneself to systemd? pm2 runs on Mac and windows, I aim to do the same. Same set of commands to create services everywhere, with details abstracted away (easier said than done, need to look into their APIs).
- qbasic_forever 3y agoYou might like systemd's run command, it's a hidden little gem that basically does what your tool does--it turns some CLI params into a transient service file: https://www.freedesktop.org/software/systemd/man/systemd-run.html https://www.freedesktop.org/software/systemd/man/systemd-run... I dunno if this was a more recent addition to systemd, but it's pretty slick in my limited use. I use it for exactly the scenarios you mention, like quickly spinning up some local user services during development. It can do stuff like setup a listening socket, timer (cron) or file watcher service all from the CLI too.
- shardulaeer 3y agoThat's interesting! I wasn't aware of this command when I started working on servicer. Anyway, there are a couple of utilities like `ser status` and `ser which` which you might find useful.
- fellerts 3y agoGreat tip. I would also couple it with the —-user flag so the service runs as your user. Stuff like this shouldn’t have root permissions anyway.
- shardulaeer 3y agoThat's a good thought. `sudo` is needed for writing to `/usr/`. The service being set up does not have root access. The value of `User=` is $SUDO_USER (hp- my regular non privileged user who initiatiated sudo) instead of $USER (root). https://github.com/servicer-labs/servicer/blob/762801e3c07b1d1e8bf680efff9ab668afcf909c/src/handlers/handle_create_service.rs#L162 https://github.com/servicer-labs/servicer/blob/762801e3c07b1...
- markstos 3y agoTypically the `User=` directive is used to specify what the user the service runs in. There is still a benefit to requiring root to create the service file though: If the service is compromised when it's running as `User=`, it can't modify the systemd service file itself, which is owned by root.
- 3y ago
- lopkeny12ko 3y agoI don't understand this. Why not just...use systemd? Is there something I'm missing here?
- flemhans 3y agoSystemd is so damn cumbersome. It's like they never tried using servers in real life when they designed it. No commands work as you'd expect them to, and require a lot of very specific cmd line flags to do what should be the default. I think the architecture and design of systemd might be okay but the user experience is horrible. It's the same with git.
- shardulaeer 3y agoI think it's more about ease of use and developer experience. I agree that in the current state servicer is a proxy to systemd, anything you can do here you can do on systemd. Later down the line I will try to support process managers on Mac and Windows. I'm happy see this question "Why not use systemd" finally being asked. Apparently the people on NPM (2 million weekly downloads for pm2) ~~disagree~~ don't care. `pm2 start` just works, not everybody is a system admin. There are a bunch of threads around asking for a pm2 for Rust or golang. This tool tries to address this segment. You can be a linux veteran still benefit with some commands like `ser status` which will only show the services you created, not the wall of text shown by `systemctl list-units`. CPU and Ram usage is thrown in as a bonus so you don't need to run a separate command. It's a neat trick that uses no database. The services end with `.ser.service`, this way we only see the units that servicer created. Run `ser which` and you'll get the unit and service file destination.
- deleted 3y ago[deleted]
- tiborsaas 3y agoWhen I picked up Deno, I couldn't use it with PM2 so I ended up learning systemd which turned out to be quite easy. I like however the added tooling and dev-ux this tool provides. Reading your post here it seems there's more interpreters you support, however the landing page has no reference to it.
- shardulaeer 3y agoThanks for the heads up, I shall update the landing page. The tool tries to detect the interpreter (currently just node and python), but you can provide a custom one with `--interpreter deno`.
- rocket1111 3y ago[flagged]
- hpb42 3y agoKudos for making it daemonless! I think Servicer can be a good starting point for people to learn how to use Systemd services and systemd-run. Systemd is huge and can be scary to learn, so providing a set of steps to get a service running is very instructive. But then, Servicer requires super user priviliges to modify the system, instead of running everything as the non-privileged user, via `--user` flag for systemctl or via systemd-run... There are few commands to learn the basics when setting up a new system wide service: systemctl and journalctl. Some examples: - systemctl daemon-reload: reload all unit files - systemctl start/stop/status/restart <service>: quite intuitive, don't you think? - journalctl -u <service>: to see all logs from that service. I like to also use `-f` flag to follow new log entries. - man systemctl: the manual for systemctl - man journalctl: the manual for journalctl Writing new service units is the "hard" part, but there are plenty of "templates" on the net, or you can browse `/usr/lib/systemd/system/` for examples. But don't let the critics here demotivate you. You made a tool, you published it, congrats!
- markstos 3y ago> Kudos for making it daemonless! It uses the systemd daemon to manage the services. It's not clear what an additional service would do.
- shardulaeer 3y agoThanks for the feedback! I'm certainly add a `--user` flag. One kind note though, the service being set up does not have root access. The value of `User=` is $SUDO_USER (hp- my regular non privileged user that initiatiated sudo mode) instead of $USER (root). Sudo is needed for writing `.service` files to `/usr/` and for start, stop operations with dbus.
- markstos 3y agoAs someone who knows systemd very well, my team of Mac-based devs did appreciate when I made something like this. I used a different framework, a precursor to Tome: https://github.com/toumorokoshi/tome Using this, I was able to create a very focused tool with few commands and simple docs, which supported things like: - my-cli help - my-cli start - my-cli stop - my-cli restart - my-cli status Sometimes the commands were thin wrappers around systemd, sometimes they were a bit more complex because we really had a collection of services, not a single one. So while my first reaction was "why not use systemd?", my second reaction is "Oh yeah, I built something like that and it was helpful". Systemd is great, but it does have a massive amount of a commands and documentation and be overkill and overwhelming.
- moojd 3y agoWow, never seen tome before but I built almost the exact same thing at my current company with the only difference being all the sub-commands run in a nix environment. Being able to share bash scripts in our monorepo by just creating a file at ./scripts/bash/foo.bash and calling it with 'my-cli foo' has been awesome. You can also set up runners so ./scripts/js and ./scripts/python works as you would think. Having everything inside of a nix env means all the tools are there and work across everyone's machines. I don't have a solution for managing services though and that has been the one pain point after moving away from containerized dev envs. The cross platform network and service management you get with docker is pretty ideal. devenv.sh is on to something with their 'services' feature but it doesn't quiet fit the bill for us yet.
- VTimofeenko 3y agoCheck out devshell[1], especially paired with flake-parts and direnv. When a user cds into a flake directory, drenv's "use flake" makes the terminal show all devshell commands in a nice menu [1]: https://flake.parts/options/devshell.html https://flake.parts/options/devshell.html
- _nalply 3y agoTools like yay, an additional package manager on Arch Linux can be started without sudo and if neccessary request the passwort to sudo. This would be a nice feature for servicer, too.
- kristianpaul 3y agoHave you tried pystemd?