How to run a service as a non-root user

I'd like my machine to kick off a Jupyter notebook server on boot. Python being what it is, this has to happen inside a virtual environment, and Jupyter being what it is none of this should be run as root. So I want to do the simplest thing and have it activate a virtual environment and then run the server instance as me. I can't for the life of me get it to actually start the service when I reboot.

When I try it this way:

#!/bin/sh

# PROVIDE: jupyter

. /etc/rc.subr

name="jupyter"
rcvar="${name}_enable"

jupyter_user="glen"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

jupyter_start() {
# Activate the virtual environment and start Jupyter
. /home/glen/jupyter-venv/bin/activate && jupyter-lab --no-browser --port=8888 --ip=0.0.0.0
}

jupyter_stop() {
# Find and kill the Jupyter process
pkill -f "jupyter-lab"
}

load_rc_config $name
run_rc_command "$@"

...it won't start, even when I start it manually, giving the error "Running as root is not recommended. Use --allow-root to bypass." which indicates that me setting the jupyter_user variable to "glen" isn't working as I expect. But when I replace the line that starts the service with

su -l glen -c ". /home/glen/jupyter-venv/bin/activate && jupyter-lab --no-browser --port=8888 --ip=0.0.0.0"

the service starts fine when I do it manually; however, it doesn't start on boot, and in /var/log/messages I get a "Bad su to glen".
 
sudo -u glen sh -c '...'

works from /etc/rc.local

Doesn't seem to work as a service. My /usr/local/etc/rc.d/jupyter:


#!/bin/sh

# PROVIDE: jupyter

. /etc/rc.subr

name="jupyter"
rcvar="${name}_enable"

jupyter_user="glen"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

jupyter_start() {
# Activate the virtual environment and start Jupyter
sudo -u glen sh -c ". /home/glen/jupyter-venv/bin/activate && jupyter-lab --no-browser --port=8888 --ip=0.0.0.0" &
}

jupyter_stop() {
# Find and kill the Jupyter process
pkill -f "jupyter-lab"
}

load_rc_config $name
run_rc_command "$@"

# sudo service jupyter start
eval: sudo: not found
 
sudo -u glen sh -c '...'

works from /etc/rc.local

This does work when done from the command line:

#!/bin/sh

# PROVIDE: jupyter

. /etc/rc.subr

name="jupyter"
rcvar="${name}_enable"

jupyter_user="glen"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

jupyter_start() {
# Activate the virtual environment and start Jupyter
/usr/local/bin/sudo -u glen sh -c ". /home/glen/jupyter-venv/bin/activate && jupyter-lab --no-browser --port=8888 --ip=0.0.0.0" &
}

jupyter_stop() {
# Find and kill the Jupyter process
pkill -f "jupyter-lab"
}

load_rc_config $name
run_rc_command "$@"

But not during boot. I get a message that shows up on the boot screen but I can't find in any log. Something about libintl not being found but needed by sudo. I have verified that I do indeed have get text installed, and soda works just fine after boot finishes. So something about load order won't let sudo work at that point in the boot process?
 
You need to install devel/py-jupyter-server, that will provide all the proper scripts for starting the service.

I'd suggest not worrying too much about whether you're root or not for this, especially if you want to start the server on boot, via /etc/rc.conf.

Just start the service as instructed in the pkg-message and official documentation. Then things will start showing up in the logs.
 
You need to install devel/py-jupyter-server, that will provide all the proper scripts for starting the service.

I'd suggest not worrying too much about whether you're root or not for this, especially if you want to start the server on boot, via /etc/rc.conf.

Just start the service as instructed in the pkg-message and official documentation. Then things will start showing up in the logs.

I installed it, but the only pkg-message is

Message from py311-Automat-25.4.16:

--
Install graphics/py-graphviz and devel/py-twisted to enable state
machine visualization (`automat-visualize`).

which isn't helpful, and it doesn't look like it installed anything in /usr/local/etc/rc.d or /etc/rc.d
 
Code:
PATH=/usr/local/bin:$PATH
LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
sudo -u glen sh -c '...'
This still doesn't start the service at boot. Works great from the command line. I taped the boot messages; the error message still says

Feeding entropy: ld-elf.so.1: Shared object "libintl.so.8" not found, required by "sudo"

The very next reported line is the ELF ldconfig path, which includes the usual suspects, including /usr/local/lib, and there is a libintl.so.8 present there.
 
The very next reported line is the ELF ldconfig path, which includes the usual suspects, including /usr/local/lib, and there is a libintl.so.8 present there.

Ah. So the problem is that you run before ldconfig.

I intended for what I posted to go into /etc/rc.local, which runs last-ish.

Also try `export LD_LIBRARY_PATH` just in case.
 
Ah. So the problem is that you run before ldconfig.

I intended for what I posted to go into /etc/rc.local, which runs last-ish.

Also try `export LD_LIBRARY_PATH` just in case.

Yeah, I'm trying to figure out how to get it to run as a service, with jupyter_enable="YES" in /etc/rc.conf

According to the handbook this should be possible. Somehow.
 
OK, I seem to have found a combination that works!

The rc.d/jupyter file:

#!/bin/sh

# PROVIDE: jupyter
# REQUIRE: LOGIN LDCONFIG

. /etc/rc.subr

name="jupyter"
rcvar="${name}_enable"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

jupyter_start() {
# Activate the virtual environment and start Jupyter
su -l ${jupyter_user} -c ". /home/${jupyter_user}/jupyter-venv/bin/activate && jupyter-lab --no-browser --port=8888 --ip=0.0.0.0" &
}

jupyter_stop() {
# Find and kill the Jupyter process
pkill -f "jupyter-lab"
}

load_rc_config $name
run_rc_command "$@"

The major fix being that REQUIRE makes sure the service starts after ldconfig runs.

I *also* defined jupyter_user="glen" in /etc/rc.conf, and I now get a "sudo glen to glen" message during boot, so I'm not 100% sure that I actually need the su here, but it works and the message doesn't bother me.
 
Back
Top