Zrok: How Do I Run Multiple Proxies Using as a Linux Service?

I have three different reserved proxy shares that I've created, and while I can run those manually and they function perfectly I cannot figure out how to run them as a linux service that starts up with my machine. zrok frontdoor | Zrok details running zrok-share as a service however it only works for a single share, and doesn't seem to give me an option for running a reserved share, or running multiple shares using the same environment.

Screenshot from 2024-01-02 08-34-01
I want to do what I have in the screenshot - but set up as a Linux service so that my reserved shares will become available as soon as my machine comes online.

Hi @waywardspooky, welcome to zrok, OpenZiti and the community!

At this time you'll need to run multiple instances of zrok, one per proxy you are interested in sharing. The backlog has an entry to make this easier so I expect in the coming year there will be some mechanism to make multiple sharing easier, it's just not developed yet.

Have you seen zrok front door? Since you're running linux, you should be able to easily setup multiple zrok service/shares using that zrok frontdoor | Zrok

That'd be how I'd do it. You'll just need to have 1 service for each proxied service (at this time)

Thank you. Setting up multiple service files was actually the first thing I attempted to do when I originally came across the frontdoor documentation, however the issue is that setting up multiple zrok services - so for example sudo nano /etc/systemd/system/zrok-share-ollama.service, sudo nano /etc/systemd/system/zrok-share-ollama-webui.service, and sudo nano /etc/systemd/system/zrok-share-litellm.service they all share the same environment.json and reserved.json. i don't see any way for me to specify in the zrok-share.env reserved shares or what environment.json or reserved.json to use.

I'm sorry, I see you linked to that doc in the original post! I don't know how i missed that! :confused: I see what you're saying now. I'll poke around a bit and see what I can find out and get back to you in a bit after I go play around with it.

Ok. After playing with zrok-share for a minute, I think it'll be best to get @qrkourier to comment since he developed it. It doesn't appear to support multiple services at this time. At the end of the day though, it's just making a systemd service. When I eanbled the share, I saw:

Created symlink /etc/systemd/system/multi-user.target.wants/zrok-share.service → /lib/systemd/system/zrok-share.service.

So I cracked open that systemd service file and looked at it. In there you'll see something similar to:

cat /lib/systemd/system/zrok-share.service
[Unit]
Description=zrok reserved public share service
After=network-online.target

[Service]
Type=simple
DynamicUser=yes
StateDirectory=zrok-share
UMask=0007
Environment=PFXLOG_NO_JSON=true
ExecStartPre=/opt/openziti/bin/zrok-enable.bash /opt/openziti/etc/zrok/zrok-share.env
ExecStart=/opt/openziti/bin/zrok-share.bash /opt/openziti/etc/zrok/zrok-share.env
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

I tend to like things simple, arguably too simple/manual maybe. If it were me, for now, I would copy that file and just make "n" of them...

If you want I can show you how to do that but it might be obvious to you. Let me know. I'll poke @qrkourier for comment.

You're thinking and trying exactly what I did. Last night I had separate .service files and created separate .env files for them respectively, however unless I was doing something incorrectly it didn't make any difference because nothing in the .service files or .env files for my shares allow me to explicitly specify what environment.json or reserved.json to use - thus each of the 3 services I created ended up sharing the same environment.json and reserved.json and overwrote one another - so only one service ends up running.

Hopefully @qrkourier knows of a way for me to host multiple zrok reserved proxy shares as linux services or can tell me if I'm doing something incorrectly. I like the ease of use of zrok but my particular use case requires the ability to have my zrok reserved proxy shares come online as linux services automatically with my machine.

Ok... After playing around and reading the bash/systemd file and figuring out how it works... I think it's pretty easy to work around it and have a second service. Here's the steps for now if you want to work around it and leverage the same script to make it easy (I prolly would) :slight_smile: :

  1. sudo cp /opt/openziti/etc/zrok/zrok-share.env /opt/openziti/etc/zrok/zrok-share-4.env
  2. sudo vi /opt/openziti/etc/zrok/zrok-share-4.env
    • update the file with ZROK_TARGET and ZROK_UNIQUE_NAME at least
  3. sudo cp /lib/systemd/system/zrok-share.service /etc/systemd/system/zrok-share-4.service
  4. sudo vi /etc/systemd/system/zrok-share-4.service
    • change:
      • StateDirectory=zrok-share-4
      • ExecStartPre=/opt/openziti/bin/zrok-enable.bash /opt/openziti/etc/zrok/zrok-share-4.env
      • ExecStart=/opt/openziti/bin/zrok-share.bash /opt/openziti/etc/zrok/zrok-share-4.env
  5. sudo systemctl daemon-reload
  6. sudo systemctl enable zrok-share-4
  7. sudo systemctl start zrok-share-4

Obviously I've used "zrok-share-4" (and zrok-share-3 prior) but you can call them whatever you like :slight_smile:

I'll leave these running for a while but I've got these running right now if you want "proof":

Screenshot of both:
image

image

One more thing, this ends up making state dirs in /var/lib/private so you can find them at that location. Inside each will be a .zrok folder where the reserved.json resides (among other 'state')

find /var/lib/private -name reserved.json
/var/lib/private/zrok-share-2/.zrok/reserved.json
/var/lib/private/zrok-share-4/.zrok/reserved.json
/var/lib/private/zrok-share-3/.zrok/reserved.json

so that should solve the stomping of the json file issue decently for now, hopefully. :wink:

@TheLumberjack You're wonderful, thank you for experimenting with it! I'll try again with the example you've given! Appreciate you! :smiley:

1 Like

You got me on the right path. StateDirectory with unique names did the trick! Was able to get all three of the reserved proxy shares set up as services that start with my machine. Posting my general set up in the event that anyone else trying to run multiple reserved shares as a linux service finds the details helpful. NOTE TO ANYONE DOING THE SAME - ZROK_UNIQUE_NAME must be alphanumeric. That means NO dashes, otherwise the service will fail to start and you won't know the cause unless you journalctl the service

/opt/openziti/etc/zrok/zrok-share-ollama.env
ZROK_ENABLE_TOKEN="<my token>"
ZROK_ENVIRONMENT_NAME="<environment name for Ollama share>"
ZROK_TARGET="http://0.0.0.0:11434"
ZROK_UNIQUE_NAME="<my unique name for Ollama share>"
ZROK_BACKEND_MODE="proxy"
/etc/systemd/system/zrok-share-ollama.service
[Unit]
Description=Zrok Ollama reserved public share service
After=network-online.target

[Service]
Type=simple
DynamicUser=yes
StateDirectory=zrok-share-ollama
UMask=0007
Environment=PFXLOG_NO_JSON=true
ExecStartPre=/opt/openziti/bin/zrok-enable.bash /opt/openziti/etc/zrok/zrok-share-ollama.env
ExecStart=/opt/openziti/bin/zrok-share.bash /opt/openziti/etc/zrok/zrok-share-ollama.env
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
sudo systemctl stop zrok-share-ollama
sudo systemctl disable zrok-share-ollama
sudo systemctl daemon-reload
sudo systemctl enable zrok-share-ollama
sudo systemctl restart zrok-share-ollama
/opt/openziti/etc/zrok/zrok-share-ollama-webui.env
ZROK_ENABLE_TOKEN="<my token>"
ZROK_ENVIRONMENT_NAME="<environment name for Ollama WebUI share>"
ZROK_TARGET="http://0.0.0.0:11435"
ZROK_UNIQUE_NAME="<my unique name for Ollama WebUI share>"
ZROK_BACKEND_MODE="proxy"
/etc/systemd/system/zrok-share-ollama-webui.service
[Unit]
Description=Zrok Ollama-WebUI reserved public share service
After=network-online.target

[Service]
Type=simple
DynamicUser=yes
StateDirectory=zrok-share-ollama-webui
UMask=0007
Environment=PFXLOG_NO_JSON=true
ExecStartPre=/opt/openziti/bin/zrok-enable.bash /opt/openziti/etc/zrok/zrok-share-ollama-webui.env
ExecStart=/opt/openziti/bin/zrok-share.bash /opt/openziti/etc/zrok/zrok-share-ollama-webui.env
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
sudo systemctl stop zrok-share-ollama-webui
sudo systemctl disable zrok-share-ollama-webui
sudo systemctl daemon-reload
sudo systemctl enable zrok-share-ollama-webui
sudo systemctl restart zrok-share-ollama-webui
/opt/openziti/etc/zrok/zrok-share-litellm.env
ZROK_ENABLE_TOKEN="<my token>"
ZROK_ENVIRONMENT_NAME="<environment name for LiteLLM Proxy share>"
ZROK_TARGET="http://0.0.0.0:8000"
ZROK_UNIQUE_NAME="<my unique name for LiteLLM Proxy share>"
ZROK_BACKEND_MODE="proxy"
/etc/systemd/system/zrok-share-litellm.service
[Unit]
Description=Zrok LiteLLM reserved public share service
After=network-online.target

[Service]
Type=simple
DynamicUser=yes
StateDirectory=zrok-share-litellm
UMask=0007
Environment=PFXLOG_NO_JSON=true
ExecStartPre=/opt/openziti/bin/zrok-enable.bash /opt/openziti/etc/zrok/zrok-share-litellm.env
ExecStart=/opt/openziti/bin/zrok-share.bash /opt/openziti/etc/zrok/zrok-share-litellm.env
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
sudo systemctl stop zrok-share-litellm
sudo systemctl disable zrok-share-litellm
sudo systemctl daemon-reload
sudo systemctl enable zrok-share-litellm
sudo systemctl restart zrok-share-litellm
1 Like

I tried it myself to get the error that journalctl will reveal which is:

Jan 02 20:17:36 ip-172-31-47-200 zrok-share.bash[2075379]: [ERROR] invalid unique name; must be lowercase alphanumeric, between 4 and 32 characters in length, screened for profanity

I had tried cdshare1-aa

1 Like

You're on the best available track, and I hit the same issues, coincidentally, while trying to host Ollama Webui and Ollama REST API with zrok! :llama: :joy:

I'm happy you're finding zrok-share.service so useful that you want concurrent shares. A single share per daemon/zrok environment is one of the major limitations of this first version of the shared service. I'm looking forward to zrok itself having full remote agent capabilities, e.g., multiple shares provided by the same zrok daemon/process. I'm planning to refactor the zrok-share install package when that's available.

Meanwhile, I'd keep doing what you're doing with renaming the zrok-share.service like zrok-share-ollama-webui.service so that each share has a separate state directory and zrok envionment. You might want to give each a meaningful environment name by setting ZROK_ENVIRONMENT_NAME so you can distinguish them in the zrok web console.

1 Like

I've found Zrok to be both versatile and simple to use/fuss free which makes me super glad to have come across it when I started exploring web tunnel proxy options.

Being able to easily and quickly set up a way to share an application or resource with a collaborator is absolutely fantastic. I have to fight enough with the little nuances and peculiarities of/between everything else in my stack - and not having to fight with the proxy share portion has made my day. Looking forward to following the continued progress of Zrok, and appreciate the thought and work that's being put into it.

3 Likes

Did you try the drive mode yet? I had an "aha" moment today when I realized I could use it to receive files from anyone, anywhere, publicly or privately. Pretty cool.

I hadn't gotten to trying drive mode however I have watched quite a few of the zrok youtube videos on the official channel, and read through the documentation - I remember going "oh wow you can do ALL that?!". It's really crazy how much we can do with it with so few commands :grin:

1 Like

Totally. Here's the short version. Drive mode is bi-directional, so something like this creates a temporary file drop for anyone with the link. The drive mode also works with permanent reserved shares and custom/unique names.

zrok share public -b drive /tmp/zrokdrop

This yields a temporary public URL like https://asdf1234.share.zrok.io which can be used in Windows Explorer, macOS Finder, or in GNOME's Nautilus to add a network location/server using WebDAV.

For Nautilus in GNOME I had to change the URI scheme to davs://, but then it works just like any other folder. Neat.

Oh, and you can upload to the share with cURL like this.

curl -T ./some/file https://asdf1234.share.zrok.io
1 Like

See, that right there is exactly what got me into zrok! So much functionality granted in a single simple and concise command. There's so many of my own use cases I can think of off the top of my head just with the drive share implementation.

I know , right? I think I'm gonna use it to receive debug logs from people.

We're just getting warmed up... :muscle:

2 Likes

If anyone comes around and wants a sane alternative to getting multiple zrok services stood up, use the systemd service file below, you'll need to create the configs as previously stated. This service file should actually be used in the package installs..

/usr/lib/systemd/system/zrok-share@.service

[Unit]
Description=zrok reserved public share service
After=network-online.target

[Service]
Type=simple
DynamicUser=yes
StateDirectory=zrok-%i
UMask=0007
Environment=PFXLOG_NO_JSON=true
ExecStartPre=/opt/openziti/bin/zrok-enable.bash /opt/openziti/etc/zrok/zrok-%i.env
ExecStart=/opt/openziti/bin/zrok-share.bash /opt/openziti/etc/zrok/zrok-%i.env
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Then, just start the services like so

systemctl daemon-reload
systemctl enable zrok-share@share1
systemctl enable zrok-share@share2
systemctl start zrok-share@share1
systemctl start zrok-share@share1
1 Like