If you want to start some daemon in the background you can install daemontools and user supervise, but i like to use screen to start daemons in the background, so that i can easily see the output.

  # check screen
  if ! /usr/bin/screen -ls | awk '{print $1}' | grep "\.${SCREEN_NAME}$" >/dev/null; then
      echo "starting $SCREEN_NAME"
      screen -S "${SCREEN_NAME}" -d -m "$COMMAND_SCRIPT"
  fi

I use this snippet, to check of a screen with a given name exists and if not start it up, i run a script i call screen-ls.sh from cron every few minutes or every minute to check is the screen is still up and running

#!/bin/bash

# this is a bigger example.

export PATH="/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin"

# get seconds from input like
# 1w  = 604800    or
# 2h  = 7200
function get_seconds_from_input
(
  TS="$1"

  i="$((${#TS}-1))"
  TS_LAST="${TS:$i:1}"
  TS_BEFORE="${TS:0:$i}"

  MAX_SECONDS="0"

  case "$TS_LAST" in
    "m"|"M")
      MAX_SECONDS=$((TS_BEFORE*60))
      ;;
    "h"|"H")
      MAX_SECONDS=$((TS_BEFORE*3600))
      ;;
    "d"|"D")
      MAX_SECONDS=$((TS_BEFORE*86400))
      ;;
    "w"|"W")
      MAX_SECONDS=$((TS_BEFORE*604800))
      ;;
    *)
      MAX_SECONDS=$TS
      ;;
  esac

  if [ -n "$MAX_SECONDS" ] && [ "$MAX_SECONDS" -eq "$MAX_SECONDS" ] 2>/dev/null; then
    if [ $MAX_SECONDS -gt 0 ]; then
      echo $MAX_SECONDS
      return
    fi
  fi

  return
)
export UPTIME="$(cat /proc/uptime | cut -d ' ' -f 1 | cut -d '.' -f 1)"
# functie voor screen
function check_screen
(
  export SCREEN_NAME="$1"
  export COMMAND_SCRIPT="$2"
  export COMMAND_UPTIME="$3"
  if test -n "$COMMAND_UPTIME"; then
    export MINIMAL_UPTIME="$(get_seconds_from_input "$COMMAND_UPTIME")"
    if test -z "$MINIMAL_UPTIME"; then
      echo "error: $SCREEN_NAME uptime $COMMAND_UPTIME, not valid, skipping"
      return
    fi
    if test $UPTIME -le $MINIMAL_UPTIME; then
      echo "skipping $SCREEN_NAME: uptime is $UPTIME, waiting until $MINIMAL_UPTIME ($COMMAND_UPTIME)"
      return
    fi
  fi

# check screen
  if ! /usr/bin/screen -ls | awk '{print $1}' | grep "\.${SCREEN_NAME}$" >/dev/null; then
      echo "starting $SCREEN_NAME"
      screen -S "${SCREEN_NAME}" -d -m "$COMMAND_SCRIPT"
  fi
)
# functie voor screen time runs
function check_screen_runs_once_every_x
(
  if test "$1" = "--exclusive"; then
    export SCREEN_EXCLUSIVE="$2"
    shift
    shift
    if screen -ls | grep -v "There is a screen" | grep -v "Socket in" | grep -v "No Sockets found" | awk '{print $1}' | cut -d '.' -f 2- | grep -q -F -x -f <(echo "$SCREEN_EXCLUSIVE" | tr "," "\n"); then
    echo "skipping $1: not starting, still exclusive in use: $SCREEN_EXCLUSIVE"
    return
    fi
  fi
  export SCREEN_NAME="$1"
  export EVERY_X_TIME="$(get_seconds_from_input "$2")"
  export COMMAND_SCRIPT="$3"
  export COMMAND_UPTIME="$4"
  if test -n "$COMMAND_UPTIME"; then
    export MINIMAL_UPTIME="$(get_seconds_from_input "$COMMAND_UPTIME")"
    if test -z "$MINIMAL_UPTIME"; then
      echo "error: $SCREEN_NAME uptime $COMMAND_UPTIME, not valid, skipping"
      return
    fi
    if test $UPTIME -le $MINIMAL_UPTIME; then
      echo "skipping $SCREEN_NAME: uptime is $UPTIME, waiting until $MINIMAL_UPTIME ($COMMAND_UPTIME)"
      return
    fi
  fi

  if test -z "$EVERY_X_TIME"; then
   echo "FAILED: $*" >&2 
   return
  fi

  TIMEDIR="$HOME/.screen-ls.lastrun"
  test -d "$TIMEDIR" || mkdir "$TIMEDIR"

  export TIMEFILE="${TIMEDIR}/${SCREEN_NAME}.lastrun"
  if test -f "$TIMEFILE"; then
    cur_epoch="$(date +%s)"
    stat_file="$(stat -c "%Z" "$TIMEFILE")"
    diff_time="$((cur_epoch - stat_file))"
    if test $diff_time -lt $EVERY_X_TIME; then
      echo "$SCREEN_NAME: not starting, $diff_time < $EVERY_X_TIME"
      return
    fi
  fi

  # screen screen
  if ! /usr/bin/screen -ls | awk '{print $1}' | grep "\.${SCREEN_NAME}$" >/dev/null; then
    echo "starting $SCREEN_NAME (once every $2)"
    screen -S "${SCREEN_NAME}" -d -m "$COMMAND_SCRIPT"
    touch "$TIMEFILE"
  fi
)
/usr/bin/screen -wipe >/dev/null 2>&1

screen -ls | grep -f <(screen -ls | cut -d '.' -f 2| grep "Detached" | awk '{print $1}' | sort | uniq -c | awk '$1!="1"{print "\\." $2 "[[:space:]]"}') | grep Detached | cut -d '.' -f 1 | xargs -r -t kill

# this will start_daemon.sh, but only if the system has been up for minimal 90 seconds
# if the start_daemon.sh script failed directly the screen is only restarted every 5 minute
check_screen_runs_once_every_x  my_name 5m /root/bin/start_daemon.sh 90
check_screen my_name2 /root/bin/start_daemon.sh

export -f get_seconds_from_input
export -f check_screen
export -f check_screen_runs_once_every_x

# starting screens from /root/.screen-ls.d
for f in /root/.screen-ls.d/*.screen; do source "$f"; done

# for easy adding extra jobs just add them to /root/.screen-ls.d

I work a lot with puppet for my work and i liked that a lot better for system configurations than something like ansible. But because i do want to know how it works i do my home configuration with ansible.

I have created a ansible role, that you can use to create a screen-ls.sh and the cron. You can find it on my github

You can use it like this

- name: create screenls
  include_role:
    name: foxhunt72_screen_ls
  vars:
    screen_username: root
    screen_filename: /root/screen-ls.sh
    screen_cron_minute: "*/3"
    screen_uptime_min: 10
    screen_program:
      - name: start_daemon
        script: /root/start_daemon.sh