Registry / devops / python-daemon

python-daemon

JSON →
library3.1.2pypypi✓ verified 27d ago

python-daemon is a Python library that implements the well-behaved Unix daemon process specification outlined in PEP 3143. It provides a `DaemonContext` class to manage the process environment for a program becoming a daemon, handling aspects like forking, changing directories, setting umask, and redirecting standard file descriptors. The current version is 3.1.2, and it is actively maintained with releases approximately every few months, though code changes are less frequent.

pip install python-daemon
INSTALL
IMPORT
SIG · PYTHON-DAEMON
P
python-daemon
devopspythonv3.1.2
Install
1.6s avg
Import
12ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v3.1.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.012s · 18MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.012s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

DaemonContext
from daemon import DaemonContext
runner
from daemon import runner
from daemon.runner import DaemonRunner
`DaemonRunner` is deprecated; prefer using `DaemonContext` directly as a context manager. Older examples often show `daemon.runner` which is an older, less flexible API.
FileLock
from lockfile import FileLock
Required if using the optional 'lockfile' package for PID file management.

This quickstart demonstrates how to use `DaemonContext` as a context manager to daemonize a simple Python script. It includes basic logging, optional PID file management using `lockfile.pidlockfile.TimeoutPIDLockFile`, and important configurations like `working_directory`, `umask`, and preserving open file descriptors for logging. Run this script and observe that it detaches from the terminal and continues to run, logging to `/tmp/my_daemon.log`.

import daemon import time import logging import sys import os # Optional: for robust PID file management try: from lockfile import pidlockfile except ImportError: pidlockfile = None LOG_FILE = '/tmp/my_daemon.log' PID_FILE = '/tmp/my_daemon.pid' def do_program_work(): logging.basicConfig( filename=LOG_FILE, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger() logger.info("Daemon started.") # Example: Keep track of open log file descriptor # so daemon does not close it. log_handler_file = None for handler in logger.handlers: if hasattr(handler, 'stream') and hasattr(handler.stream, 'fileno'): log_handler_file = handler.stream.fileno() break while True: logger.info(f"Daemon still running at {time.ctime()}") time.sleep(5) if __name__ == '__main__': # Prepare a PID file object if lockfile is installed pid_file = None if pidlockfile: pid_file = pidlockfile.TimeoutPIDLockFile(PID_FILE) # Open the daemon context # Explicitly keep stdout/stderr for debugging, typically redirect to /dev/null or log file with daemon.DaemonContext( working_directory='/', umask=0o002, # Set umask explicitly; 0o022 or 0o027 are common pidfile=pid_file, stdout=sys.stdout, # For demonstration, usually redirect to a log file or /dev/null stderr=sys.stderr, # For demonstration, usually redirect to a log file or /dev/null files_preserve=[log_handler_file] if log_handler_file else [] # Preserve log file descriptor ): do_program_work()
daemon --version
Debug
Known issues
deprecatedThe `daemon.runner.DaemonRunner` class is deprecated. Many older examples and tutorials might still use it. It's recommended to use `daemon.DaemonContext` directly as a context manager for a more modern and flexible approach.
fix
Rewrite daemon logic to use `with daemon.DaemonContext():` pattern instead of instantiating `DaemonRunner` and calling its methods.
affects: <3.0 (usage still common in 3.x), deprecated in 2.x releases
gotchaBy default, `DaemonContext` closes all open file descriptors and redirects `stdin`, `stdout`, `stderr` to `/dev/null`. This means any `print()` statements or unhandled exceptions will not be visible, leading to silent failures or perceived 'lack of output'.
fix
Explicitly set `stdout` and `stderr` parameters in `DaemonContext` to a log file or `sys.stdout`/`sys.stderr` for debugging. For logging, ensure the file descriptor of your log handler's stream is included in the `files_preserve` list if the log file is opened before entering the daemon context. Example: `DaemonContext(stdout=open('/var/log/mydaemon.log', 'w+'), stderr=open('/var/log/mydaemon_err.log', 'w+'), files_preserve=[my_log_file_descriptor])`.
affects: All versions
gotchaThe library is designed for Unix-like operating systems (Linux, macOS) and will not correctly daemonize a process on Windows. Attempts to use it on Windows will generally not result in a background daemon process.
fix
For Windows, consider alternative approaches for running background services, such as Windows Services or using libraries specifically designed for Windows service management.
affects: All versions
gotchaBy default, `DaemonContext` sets the `umask` to `0` (0o000), which allows maximal file permissions. While this is done to ensure the daemon can create files with desired permissions, it might be too permissive for certain security contexts.
fix
Explicitly set a more restrictive `umask` value (e.g., `0o022` or `0o027`) within the `DaemonContext` constructor: `DaemonContext(umask=0o022, ...)`.
affects: All versions
gotchaPID file management (creating, locking, releasing, and cleaning up the PID file) is crucial for a well-behaved daemon to prevent multiple instances and allow graceful shutdown. Simply creating a file with the PID is not sufficient; a robust locking mechanism is needed.
fix
Utilize the `pidfile` argument of `DaemonContext` with a robust PID file lock implementation, such as `lockfile.pidlockfile.TimeoutPIDLockFile` from the optional `lockfile` package. Ensure that the PID file is automatically cleaned up on normal daemon exit.
affects: All versions
Errors
Common errors & fixes
OSError: [Errno 17] File exists: '/path/to/daemon.pid'
The daemon tried to create a PID file that already exists, typically because a previous instance did not terminate cleanly or is still running.
fix
Ensure no other instance of the daemon is running; if you are certain none is, manually remove the specified PID file, then restart the daemon.
DaemonContextError: open('/path/to/pidfile.pid', 'w') failed: [Errno 13] Permission denied: '/path/to/pidfile.pid'
The user account attempting to run the daemon lacks the necessary write permissions for the directory specified for the PID file, or other redirected file descriptors like stdout/stderr.
fix
Change the `pidfile` path (and `stdout`/`stderr` paths if applicable) to a directory where the daemon process has write permissions, or adjust directory permissions.
TypeError: an integer or file-like object is required
This error occurs when you pass a string filename directly to `stdout`, `stderr`, or `stdin` instead of an opened file-like object.
fix
Open the file using `open()` in the appropriate mode (e.g., 'w+' for stdout/stderr) and pass the resulting file object to the `DaemonContext`.
ModuleNotFoundError: No module named 'daemon'
The `python-daemon` library is not installed in the current Python environment, or there is a typo in the import statement.
fix
Install the library using `pip install python-daemon` and ensure the import statement is `from daemon import DaemonContext`.
Upgrade
Version history
3.1.2latest on PyPI · released Dec 3, 2024
Audit
Dependencies
lockfileoptionalCommonly used for robust PID file management, especially with `TimeoutPIDLockFile`.
Agent activity
24 hits · last 30 days
node
22
Resources
python-daemon — pip install python-daemon · libregistry