files.services

Service name/command to enable

{name} must be a executable command that runs forever.

Optionally could exist a {name}-finish command to stop it properly.

Optionally could exist a {name}-log command to log it properly.

Default log informations goes to $PRJ_SVCS_LOG/{name}/current .

initSvcs is a special name to auto start the process supervisor s6, it control all other services.

If we don't set initSvcs service, we can start it running initSvcs.

stopSvcsd is a special name to auto stop the process supervisor If S6 wont stop by itself, we could run stopSvcs when it's done.

It defines two env vars:

  • PRJ_SVCS_DIR: $PRJ_DATA_DIR/services
  • PRJ_SVCS_LOG: $PRJ_DATA_DIR/log

See S6 documentation.

We can use config.files.alias to help create your services scripts.

examples:

Use some program as service

Configure httplz (http static server) as service

{
  # # Make services start when you enter in shell
  # files.services.initSvcs = true;

  # static http service
  files.cmds.httplz    = true; # Install httplz
  files.services.httpd = true; # Use cmd 'httpd' as service
  files.alias.httpd    = ''
    # This is an alias of httplz
    cd $PRJ_ROOT/gh-pages
    mdbook build

    # IMPORTANT NOTE:
    # if we don't use `exec` it may not stop with stopSvcs
    exec httplz --port 8022 $PRJ_ROOT/gh-pages/book/
  '';

  # greeting service
  files.cmds.notify-desktop = true; # Install notify-desktop
  files.services.greet      = true; # Use cmd 'greet' as service
  files.alias.greet         = ''
    # Greet people
    set +e # ignore errors bacause this service isn't critical
    notify-desktop -i network-server "Welcome"

    # our stdout goes to .data/log/greet
    echo Dornröschen

    # if service ends, it will restarted
    # we sleep emulating some actual service
    exec sleep infinity 
  '';
  files.alias.greet-finish  = ''
    notify-desktop -i network-server "See you later"
  '';

  # This is a service to speedup direnv
  files.direnv.auto-build.enable = true;

  # special service to auto start
  files.services.initSvcs  = true;

  # special service to auto stopSvcs
  files.services.stopSvcsd = true;

  # files.services-opts.tini.enable = true;
  # files.services-opts.namespace.enable = true;

  # # RC (unstable) is another interface it uses s6-rc
  # # http://skarnet.org/software/s6-rc/why.html
  #
  # files.rc.hello.enable  = true;
  # files.rc.hello.oneshot.start    = ''wait 1000000 "hello world"'';
  # files.rc.hello.oneshot.stop     = ''echo "bye bye world"'';
  # files.rc.hello.oneshot.timeout  = 1200;
  #
  # files.rc.olla.enable   = true;
  # files.rc.olla.longrun.start     = ''echo "hello world"'';
  # files.rc.olla.longrun.stop      = ''echo "bye bye world"'';
  # files.rc.olla.longrun.deps      = ["hello"];
  #
  # files.rc.hellos.enable = true;
  # files.rc.hellos.bundle.deps     = ["hello" "olla"];
}

Create your own service with bash

{
  # Make all services start when you enter in shell
  files.services.initSvcs = true;

  # Use hello configured below as service
  files.services.hello    = true;

  # Creates an hello command in terminal
  files.alias.hello       = ''
    while :
    do
      echo "Hello World!"
    	sleep 60
    done
  '';
}

See also:

  • files.services-opts.tini.enable to use Tini as supervisor supervisor
  • files.services-opts.namespace.enable to use namespace

Know bugs:

If we don't use exec in our alias, some necromancer could form an army of undead process, and start a war against our system, since they both may require the most scarse resource of our lands.

You can enable namespace if it is an problem

type

attribute set of boolean

example

{
  files.services = {
    hello = true;
  };
}

default

{
  files.services = { };
}

files.services-opts.namespace.enable

Whether to enable Linux Namespaces.

type

boolean

example

{
  files.services-opts.namespace.enable = true;
}

default

{
  files.services-opts.namespace.enable = false;
}

files.services-opts.namespace.options

type

string

default

{
  files.services-opts.namespace.options = "--pid --fork --map-root-user";
}

files.services-opts.tini.enable

Whether to enable Tini Supervisor.

type

boolean

example

{
  files.services-opts.tini.enable = true;
}

default

{
  files.services-opts.tini.enable = false;
}

files.services-opts.tini.options

type

string

default

{
  files.services-opts.tini.options = "-sp SIGTERM";
}