FreeBSD uses the init system, and system services must be made as rc.d scripts.
You can find more detailed information and examples in the handbook: Practical rc.d scripting in FreeBSD.
Find below the options we normally use for any /etc/rc.d
script as daemon. See more options by
in the terminal issuing:
man daemon
-f
: Redirect standard input, standard
output and standard error to /dev/null
.
When this option is used together with any of the options related to
file or syslog output, the standard file descriptors are first
redirected to /dev/null
, then stdout
and/or stderr is redirected to a file or to syslog as specified by the
other options.
-S
: Enable syslog output. This is
implicitly applied if other syslog parameters are provided. The default
values are daemon
, notice
, and daemon
for facility, priority, and tag, respectively.
-P <supervisor pid file>
: Write
the ID of the daemon process into the file with given name using the
pidfile
functionality. The program is
executed in a spawned child process while the daemon waits until it
terminates to keep the supervisor_pidfile
locked and removes it after the process exits. The supervisor_pidfile
owner is the user who runs
the daemon regardless of whether the -u
option is used or not.
-r
: Supervise and restart the program
after a one-second delay if it has been terminated.
In a nutshell, rcorder takes a set of files, examines their contents, and prints a dependency-ordered list of files from the set to stdout. The point is to keep dependency information inside the files so that each file can speak for itself only. A file can specify the following information:
# KEYWORD
:# REQUIRE
:# BEFORE
:# KEYWORD
:As a rule of thumb, every custom made rc.d script should provide 1
daemon, and require DAEMON
and networking
to be initialized. Thus the first
lines of your rc.d script will generally look something like:
#!/bin/sh
#
# PROVIDE: <name of this rc.d script>
# REQUIRE: DAEMON networking
# KEYWORD:
The order in which the daemons load is highly important. For this
example, imagine you have an API application running with an rc.d script
called my_api_service
. It should run as a
daemon and should be able to access the network.
This means that it should only load after DAEMON
and networking
are loaded and running.
You can verify the load order with:
service -e
The correct load order in this case then would be :
service -e
/etc/rc.d/cleanvar
/etc/rc.d/ip6addrctl
/etc/rc.d/netif
/etc/rc.d/virecover
/etc/rc.d/motd
/etc/rc.d/os-release
/etc/rc.d/newsyslog
/etc/rc.d/syslogd
/etc/rc.d/my_api_service
/etc/rc.d/cron
In the case of binaries, we will use the daemon in a straightforward
manner. We will run our service as root
user since this will be running inside a jail, where root
is the only existing user. Feel free to
adjust to your use case. By convention I always create a folder called
internalApplications
inside any jail, and
place my binaries inside there. See the example below for my_api_service
:
#!/bin/sh
#
# PROVIDE: my_api_service
# REQUIRE: DAEMON networking
# KEYWORD:
. /etc/rc.subr
name="my_api_service"
rcvar="my_api_service_enable"
my_api_service_chdir="/root/internalApplications/myAPIWorkingDirectory/"
my_api_service_user="root"
my_api_service_command="/root/internalApplications/myAPIWorkingDirectory/app"
pidfile="/var/run/${name}.pid"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -r -f -S ${my_api_service_command}"
load_rc_config $name
: ${my_api_service_enable:=no}
run_rc_command "$1"
Shell scripts that run utilities can also be daemonized. See the example below:
#!/bin/sh
# PROVIDE: my_script_service
# REQUIRE: DAEMON networking
# KEYWORD:
. /etc/rc.subr
name="my_script_service"
rcvar="my_script_service_enable"
my_script_service_user="root"
pidfile="/var/run/${name}.pid"
my_script_service_command="/root/internalApplications/my-script.sh"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} -r -f -S ${my_script_service_command}"
load_rc_config $name
: ${my_script_service_enable:=no}
run_rc_command "$1"
Hopefully you have become a little wiser about rc.d scripting and can "daemonize" anything that comes your way :)