Goal
Our goal is to write an rc.d file that allows us to start anything as a daemon, and an accompanying settings file, and to get to know the commands to use for automated deploy.
Settings File
We will start with the settings file. Technically you can do in there whatever you want; if you have any sanity left, you will simply use it to set environment variables. This makes it easy to follow the third rule of the Twelve-Factor App. And it really is that simple, you just add export statements, and make "dummy values" you will replace in your CI/CD script using sed:
export HTTP_PORT=3000
export POSTGRES_IP=SED_PGSQL_IP
export POSTGRES_USERNAME=SED_PGSQL_USER
export POSTGRES_PASSWORD=SED_PGSQL_PASS
This file has to be stored with the same name as your actual service file, but under /usr/local/etc/rc.conf.d/
. The RC system will auto-detect it.
Daemon file
This one is going to be a little bit longer. Let's first take a look at the whole script:
#!/bin/sh
# PROVIDE: location_service
# REQUIRE: LOGIN DAEMON NETWORKING
# KEYWORD: shutdown
. /etc/rc.subr
name=location_service
rcvar=${name}_enable
pidfile="/var/run/${name}.pid"
pidfile_child="/var/run/${name}_jvm.pid"
logfile="/var/log/${name}.log"
location_service_chdir="/usr/local/share/location-service"
command="/usr/sbin/daemon"
start_cmd="location_service_start"
procname="daemon"
load_rc_config ${name}
: ${location_service_enable:=no}
location_service_start() {
/usr/sbin/daemon -r -f -P ${pidfile} -p ${pidfile_child} -t ${name} -o ${logfile} /usr/local/bin/java -jar location-service.jar
}
run_rc_command "$1"
Main variables
There is some magic going on with the variable names, but that aside, it is a pretty standard shell script file. In this case, we are working with a location service that is to be run by the JVM, but it really doesn't matter - you can run literally anything as a service this way.
-
. /etc/rc.subr
loads subroutines that enable the "magic" to run the service. -
rcvar
is the flag that you can set to enable or disable your service in the rc.conf file. - The two pidfiles are holding the process id of the daemon and the actual process, so the system can keep track of it.
- and the
location_service_chdir
(orwhatever_you_name_it_chdir
) sets the working directory.
The Daemon command
FreeBSD ships with a program aptly called daemon, and we are using it to run our normal program as one. We thus tell the rc system to use /usr/sbin/daemon as the main command
, and tell it that the process started by it - procname
- will be called "daemon". We also tell it to run a custom starting function, start_cmd
, which in this case is called "location_service_start".
Configure the daemon
We configure the daemon by setting the flags when starting it. We have the following flags:
-
-r
: Restarts the process if it dies -
-f
: Redirects standard input/output and standard error to /dev/null -
-p
: the pidfile for the process you want to have daemonized -
-P
: the pidfile of the daemon process itself - that is what the rc system needs -
-o
: the log file to log to -
-t
: gives the process a name (optional) -
-u
: (not used here): the user to run the process as
This service file has to be stored under /usr/local/etc/rc.d
and be made executable.
Automatic deployment
We almost have it - the only thing missing are the commands for your CI/CD. It is really simple once you have both files at their respective locations.
You can set the config variables using sed -i.bak "s/SED_PGSQL_IP/${your_ci_var}/g" /usr/local/etc/rc.conf.d/location_service
. Remember, if your variable contains the "/" character, you can use something else for sed, whatever character follows the "s" will be the separator.
Enable the service using sysrc -f /etc/rc.conf "location_service_enable=YES"
.
And finally, don't forget to actually (re-)start it using service location_service restart
.
Have fun!
Top comments (0)