The Daemon Extension enables applications to easily perform standard daemonization operations.
  • Configurable runtime user and group
  • Adds the --daemon command line option
  • Add app.daemonize() function to trigger daemon functionality where necessary (either in a cement pre_run hook or an application controller sub-command, etc)
  • Manages a PID file including cleanup on app.close()
API References:


  • No external dependencies

Platform Support

  • Unix/Linux
  • macOS


The daemon extension is configurable with the following settings under a [daemon] section in the application configuration:
The user name the process runs as. Default: os.getlogin()
The group name the process runs as. Default: the primary group of the user
The directory that the process runs in. Default: /
The filesystem path to store the PID (Process ID) file. Default: None
The UMASK value to pass to os.umask(). Default: 0
Configurations can be passed as defaults to App:
from cement import App, init_defaults
DEFAULTS = init_defaults('myapp', 'daemon')
DEFAULTS['daemon']['user'] = 'myuser'
DEFAULTS['daemon']['group'] = 'mygroup'
DEFAULTS['daemon']['dir'] = '/var/lib/myapp/'
DEFAULTS['daemon']['pid_file'] = '/var/run/myapp/'
DEFAULTS['daemon']['umask'] = 0
class MyApp(App):
class Meta:
label = 'myapp'
config_defaults = DEFAULTS
Application defaults are then overridden by configurations parsed via a [demon] config section in any of the applications configuration paths. An example configuration block would look like:
user = myuser
group = mygroup
dir = /var/lib/myapp/
pid_file = /var/run/myapp/
umask = 0


The following example shows how to add the daemon extension, as well as trigger daemon functionality before is called.
from time import sleep
from cement import App
class MyApp(App):
class Meta:
label = 'myapp'
extensions = ['daemon']
with MyApp() as app:
count = 0
while True:
count = count + 1
print('Iteration: %s' % count)
Some applications may prefer to only daemonize certain sub-commands rather than the entire parent application. For example:
from cement import App, Controller, ex
class Base(Controller):
class Meta:
label = 'base'
@ex(help="run the daemon command.")
def run_forever(self):
from time import sleep
count = 0
while True:
count = count + 1
class MyApp(App):
class Meta:
label = 'myapp'
handlers = [Base]
extensions = ['daemon']
with MyApp() as app:
By default, even after app.daemonize() is called… the application will continue to run in the foreground, but will still manage the pid and user/group switching. To detach a process and send it to the background you simply pass the --daemon option at command line.
$ python --daemon
$ ps -x | grep example
37421 ?? 0:00.01 python --daemon
37452 ttys000 0:00.00 grep example

Daemonizing Without Commandline Option

Some use cases might require daemonizing the process without having to always pass the --daemon option, or where passing the option might be redundant. You can work around that programatically by simply overriding the daemon argument value in order to force daemonization even if --daemon wasn’t passed.
app.pargs.daemon = True
Note that this would only work after arguments have been parsed (i.e. after is called).
Last modified 7mo ago