{"library":"python-daemon","title":"python-daemon","description":"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.","status":"active","version":"3.1.2","language":"en","source_language":"en","source_url":"https://github.com/python-daemon/python-daemon","tags":["daemon","unix","process","background","pep3143"],"install":[{"cmd":"pip install python-daemon","lang":"bash","label":"Install stable release"}],"dependencies":[{"reason":"Commonly used for robust PID file management, especially with `TimeoutPIDLockFile`.","package":"lockfile","optional":true}],"imports":[{"symbol":"DaemonContext","correct":"from daemon import DaemonContext"},{"note":"`DaemonRunner` is deprecated; prefer using `DaemonContext` directly as a context manager. Older examples often show `daemon.runner` which is an older, less flexible API.","wrong":"from daemon.runner import DaemonRunner","symbol":"runner","correct":"from daemon import runner"},{"note":"Required if using the optional 'lockfile' package for PID file management.","symbol":"FileLock","correct":"from lockfile import FileLock"}],"quickstart":{"code":"import daemon\nimport time\nimport logging\nimport sys\nimport os\n\n# Optional: for robust PID file management\ntry:\n    from lockfile import pidlockfile\nexcept ImportError:\n    pidlockfile = None\n\nLOG_FILE = '/tmp/my_daemon.log'\nPID_FILE = '/tmp/my_daemon.pid'\n\ndef do_program_work():\n    logging.basicConfig(\n        filename=LOG_FILE,\n        level=logging.INFO,\n        format='%(asctime)s - %(levelname)s - %(message)s'\n    )\n    logger = logging.getLogger()\n    logger.info(\"Daemon started.\")\n\n    # Example: Keep track of open log file descriptor\n    # so daemon does not close it.\n    log_handler_file = None\n    for handler in logger.handlers:\n        if hasattr(handler, 'stream') and hasattr(handler.stream, 'fileno'):\n            log_handler_file = handler.stream.fileno()\n            break\n\n    while True:\n        logger.info(f\"Daemon still running at {time.ctime()}\")\n        time.sleep(5)\n\n\nif __name__ == '__main__':\n    # Prepare a PID file object if lockfile is installed\n    pid_file = None\n    if pidlockfile:\n        pid_file = pidlockfile.TimeoutPIDLockFile(PID_FILE)\n\n    # Open the daemon context\n    # Explicitly keep stdout/stderr for debugging, typically redirect to /dev/null or log file\n    with daemon.DaemonContext(\n        working_directory='/',\n        umask=0o002, # Set umask explicitly; 0o022 or 0o027 are common\n        pidfile=pid_file,\n        stdout=sys.stdout, # For demonstration, usually redirect to a log file or /dev/null\n        stderr=sys.stderr, # For demonstration, usually redirect to a log file or /dev/null\n        files_preserve=[log_handler_file] if log_handler_file else [] # Preserve log file descriptor\n    ):\n        do_program_work()\n","lang":"python","description":"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`."},"warnings":[{"fix":"Rewrite daemon logic to use `with daemon.DaemonContext():` pattern instead of instantiating `DaemonRunner` and calling its methods.","message":"The `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.","severity":"deprecated","affected_versions":"<3.0 (usage still common in 3.x), deprecated in 2.x releases"},{"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])`.","message":"By 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'.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For Windows, consider alternative approaches for running background services, such as Windows Services or using libraries specifically designed for Windows service management.","message":"The 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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Explicitly set a more restrictive `umask` value (e.g., `0o022` or `0o027`) within the `DaemonContext` constructor: `DaemonContext(umask=0o022, ...)`.","message":"By 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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"PID 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-05T00:00:00.000Z","next_check":"2026-07-04T00:00:00.000Z"}