# python-dmon
[](https://github.com/atomiechen/python-dmon)
[](https://pypi.org/project/python-dmon/)
A lightweight, cross-platform daemon manager that runs any command — called a *task* — as a background process.
It also supports logging and log rotation out of the box.
**No Docker or extra dependencies required**.
Shipped as the CLI tool `dmon`.
It is a Python-based and more powerful successor to the [handy-backend shell scripts](https://github.com/atomiechen/handy-backend).
## Features
- 🖥️ **Cross-platform:** Works on Linux, macOS, and Windows.
- ⚡ **Lightweight:** Pure Python, no Docker or external dependencies needed.
- 🧩 **Flexible tasks:** Tasks can be configured in `pyproject.toml` or `dmon.yaml`; or run ad-hoc commands directly.
- 🪵 **Logging & log rotation:** Automatically manage log files to prevent uncontrolled growth.
## Installation
`python-dmon` is available on [PyPI](https://pypi.org/project/python-dmon/):
```sh
pip install python-dmon
```
We recommend installing into an isolated environment, e.g., with `uv` / `pipx`:
```sh
# Install globally with uv tool
uv tool install python-dmon
# Or with pipx
pipx install python-dmon
# Add as a dev dependency in your project
uv add --dev python-dmon
```
You can also invoke without installing:
```sh
# With uvx (uv tool run)
uvx python-dmon
# Or with pipx
pipx run python-dmon
```
To get the latest features, install from source:
```sh
pip install git+https://github.com/atomiechen/python-dmon.git
```
## Getting Started
### Prepare Configuration
Create a `dmon.yaml` file:
```yaml
tasks:
app: ["python", "-u", "server.py"]
```
Or add to your `pyproject.toml`:
```toml
[tool.dmon.tasks]
app = ["python", "-u", "server.py"]
```
Commands can be a single string (run in shell), or list of strings (exec form).
See [Example Configuration](#example-configuration) for more configuration options.
### Run tasks
Run a configured task by its name:
```sh
# Start a task
dmon start app
# Stop a running task
dmon stop app
# Check task status
dmon status app
# Execute a task in the foreground (useful for debugging)
dmon exec app
```
If you have defined `default_task`, or only one task is defined in the config file, you can omit the task name:
```sh
dmon start
dmon stop
dmon status
dmon exec
```
You can use `--config` to specify a custom config file or the directory containing it:
```sh
dmon start --config /path/to/dmon.yaml app # YAML
dmon start --config /path/to/pyproject.toml app # or TOML
dmon start --config /path/to/dir app # dir with `dmon.y(a)ml` or `pyproject.toml`
```
And yes, you can use `dmon` to run in a nested manner:
```yaml
tasks:
app: ["python", "-u", "server.py"]
nested: pwd && dmon exec app # nest `dmon exec`
subdir_task1:
cwd: /path/to/dir
cmd: ["dmon", "exec", "app"] # run task defined in another folder
subdir_task2: dmon exec app --config /path/to/dir/dmon.yaml # like above
```
### Run an ad-hoc command
```sh
# Run a command with arguments in the background
dmon run --name myserver python -u server.py
# Run a shell command in the background
dmon run --shell echo "Hello World"
# Run a shell script in the background
dmon run --cwd /path/to/script bash myscript.sh
```
> [!NOTE]
> If no name is provided, `dmon` automatically assigns a fixed task name `default_run` to prevent duplicate runs.
### List all running tasks
```sh
dmon list
```
## Example Configuration
A task can be a **string**, **list**, or **dictionary**.
Here is a more complete example with default values:
```yaml
tasks:
your_task_name:
# Command to run; can be a string (run in shell) or list of strings (exec form)
cmd: ["python", "server.py"] # required
cwd: "/path/to/working/dir" # (default: current dir)
env: # (default: inherit from parent process)
PYTHONUNBUFFERED: "1"
override_env: false # override parent env and only use env defined here
log_path: "logs/<task>.log" # path to log file
log_rotate: false # enable log rotation
log_max_size: 5 # max log file size before rotation in MB
rotate_log_path: "logs/<task>.rotate.log" # path to rotation log
rotate_log_max_size: 5 # max rotation log file size in MB
meta_path: ".dmon/<task>.meta.json" # path to meta file
default_task: your_task_name # the default task name
```
In TOML, write like this:
```toml
[tool.dmon.tasks]
your_task_name = { cmd = [
"python", "-u", "server.py"
], ... }
another_task = "cd subdir && ls && bash start.sh"
[tool.dmon]
default_task = "your_task_name"
```
## Under the Hood
Each task is associated with a meta file (e.g. `.dmon/<task>.meta.json`) stored in the current working directory.
The file contains details such as the command, PID, log path, and more.
**Do not** modify or delete these files manually.
## License
[python-dmon](https://github.com/atomiechen/python-dmon) © 2025 by [Atomie CHEN](https://github.com/atomiechen) is licensed under the [MIT License](https://github.com/atomiechen/python-dmon/blob/main/LICENSE).
Raw data
{
"_id": null,
"home_page": null,
"name": "python-dmon",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "python-dmon, dmon, daemon, background, detach, process management",
"author": "Atomie CHEN",
"author_email": "Atomie CHEN <atomic_cwh@163.com>",
"download_url": "https://files.pythonhosted.org/packages/6b/d9/ef33b8d5de4623b91cecc3754adf31e9e4026ce3b6b48a998b8fab055cb8/python_dmon-0.2.3.tar.gz",
"platform": null,
"description": "# python-dmon\n\n\n[](https://github.com/atomiechen/python-dmon)\n[](https://pypi.org/project/python-dmon/)\n\n\nA lightweight, cross-platform daemon manager that runs any command \u2014 called a *task* \u2014 as a background process. \nIt also supports logging and log rotation out of the box. \n**No Docker or extra dependencies required**. \n\nShipped as the CLI tool `dmon`.\nIt is a Python-based and more powerful successor to the [handy-backend shell scripts](https://github.com/atomiechen/handy-backend).\n\n\n## Features\n\n- \ud83d\udda5\ufe0f **Cross-platform:** Works on Linux, macOS, and Windows.\n- \u26a1 **Lightweight:** Pure Python, no Docker or external dependencies needed.\n- \ud83e\udde9 **Flexible tasks:** Tasks can be configured in `pyproject.toml` or `dmon.yaml`; or run ad-hoc commands directly.\n- \ud83e\udeb5 **Logging & log rotation:** Automatically manage log files to prevent uncontrolled growth.\n\n\n## Installation\n\n`python-dmon` is available on [PyPI](https://pypi.org/project/python-dmon/):\n\n```sh\npip install python-dmon\n```\n\nWe recommend installing into an isolated environment, e.g., with `uv` / `pipx`:\n\n```sh\n# Install globally with uv tool\nuv tool install python-dmon\n\n# Or with pipx\npipx install python-dmon\n\n# Add as a dev dependency in your project\nuv add --dev python-dmon\n```\n\nYou can also invoke without installing:\n\n```sh\n# With uvx (uv tool run)\nuvx python-dmon\n\n# Or with pipx\npipx run python-dmon\n```\n\nTo get the latest features, install from source:\n\n```sh\npip install git+https://github.com/atomiechen/python-dmon.git\n```\n\n## Getting Started\n\n### Prepare Configuration\n\nCreate a `dmon.yaml` file:\n\n```yaml\ntasks:\n app: [\"python\", \"-u\", \"server.py\"]\n```\n\nOr add to your `pyproject.toml`:\n\n```toml\n[tool.dmon.tasks]\napp = [\"python\", \"-u\", \"server.py\"]\n```\n\nCommands can be a single string (run in shell), or list of strings (exec form).\nSee [Example Configuration](#example-configuration) for more configuration options.\n\n\n### Run tasks\n\nRun a configured task by its name:\n\n```sh\n# Start a task\ndmon start app\n\n# Stop a running task\ndmon stop app\n\n# Check task status\ndmon status app\n\n# Execute a task in the foreground (useful for debugging)\ndmon exec app\n```\n\nIf you have defined `default_task`, or only one task is defined in the config file, you can omit the task name:\n\n```sh\ndmon start\ndmon stop\ndmon status\ndmon exec\n```\n\nYou can use `--config` to specify a custom config file or the directory containing it:\n\n```sh\ndmon start --config /path/to/dmon.yaml app # YAML\ndmon start --config /path/to/pyproject.toml app # or TOML\ndmon start --config /path/to/dir app # dir with `dmon.y(a)ml` or `pyproject.toml`\n```\n\nAnd yes, you can use `dmon` to run in a nested manner:\n\n```yaml\ntasks:\n app: [\"python\", \"-u\", \"server.py\"]\n nested: pwd && dmon exec app # nest `dmon exec`\n subdir_task1:\n cwd: /path/to/dir\n cmd: [\"dmon\", \"exec\", \"app\"] # run task defined in another folder\n subdir_task2: dmon exec app --config /path/to/dir/dmon.yaml # like above\n```\n\n\n### Run an ad-hoc command\n\n```sh\n# Run a command with arguments in the background\ndmon run --name myserver python -u server.py\n\n# Run a shell command in the background\ndmon run --shell echo \"Hello World\"\n\n# Run a shell script in the background\ndmon run --cwd /path/to/script bash myscript.sh\n```\n\n> [!NOTE]\n> If no name is provided, `dmon` automatically assigns a fixed task name `default_run` to prevent duplicate runs.\n\n\n### List all running tasks\n\n```sh\ndmon list\n```\n\n\n## Example Configuration\n\nA task can be a **string**, **list**, or **dictionary**.\n\nHere is a more complete example with default values:\n\n```yaml\ntasks:\n your_task_name:\n # Command to run; can be a string (run in shell) or list of strings (exec form)\n cmd: [\"python\", \"server.py\"] # required\n cwd: \"/path/to/working/dir\" # (default: current dir)\n env: # (default: inherit from parent process)\n PYTHONUNBUFFERED: \"1\"\n override_env: false # override parent env and only use env defined here\n log_path: \"logs/<task>.log\" # path to log file\n log_rotate: false # enable log rotation\n log_max_size: 5 # max log file size before rotation in MB\n rotate_log_path: \"logs/<task>.rotate.log\" # path to rotation log\n rotate_log_max_size: 5 # max rotation log file size in MB\n meta_path: \".dmon/<task>.meta.json\" # path to meta file\ndefault_task: your_task_name # the default task name\n```\n\nIn TOML, write like this:\n\n```toml\n[tool.dmon.tasks]\nyour_task_name = { cmd = [\n \"python\", \"-u\", \"server.py\"\n], ... }\nanother_task = \"cd subdir && ls && bash start.sh\"\n\n[tool.dmon]\ndefault_task = \"your_task_name\"\n```\n\n\n## Under the Hood\n\nEach task is associated with a meta file (e.g. `.dmon/<task>.meta.json`) stored in the current working directory.\nThe file contains details such as the command, PID, log path, and more.\n**Do not** modify or delete these files manually.\n\n\n## License\n\n[python-dmon](https://github.com/atomiechen/python-dmon) \u00a9 2025 by [Atomie CHEN](https://github.com/atomiechen) is licensed under the [MIT License](https://github.com/atomiechen/python-dmon/blob/main/LICENSE).\n",
"bugtrack_url": null,
"license": null,
"summary": "A lightweight, cross-platform daemon manager that runs any command as a background process.",
"version": "0.2.3",
"project_urls": {
"Bug Tracker": "https://github.com/atomiechen/python-dmon/issues",
"Changelog": "https://github.com/atomiechen/python-dmon/blob/main/CHANGELOG.md",
"Homepage": "https://github.com/atomiechen/python-dmon"
},
"split_keywords": [
"python-dmon",
" dmon",
" daemon",
" background",
" detach",
" process management"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "649eca16fb03eadead7d8dcc83cec6a067b083deae1de943aee33bdb3c1b862b",
"md5": "2f88accb359d2411af1b9150963567e6",
"sha256": "ace1bec9d3c42a80d78f35eb3f25698a2515bca6eda676fc3011ad9ac8c80fec"
},
"downloads": -1,
"filename": "python_dmon-0.2.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2f88accb359d2411af1b9150963567e6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 16743,
"upload_time": "2025-10-26T12:11:33",
"upload_time_iso_8601": "2025-10-26T12:11:33.526148Z",
"url": "https://files.pythonhosted.org/packages/64/9e/ca16fb03eadead7d8dcc83cec6a067b083deae1de943aee33bdb3c1b862b/python_dmon-0.2.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6bd9ef33b8d5de4623b91cecc3754adf31e9e4026ce3b6b48a998b8fab055cb8",
"md5": "2a31154dcdb4d7c9a638fbeeb9c3511d",
"sha256": "50f24165a528bc48814f4c7d699633bda95065ec58ee52499159cead5d838d5f"
},
"downloads": -1,
"filename": "python_dmon-0.2.3.tar.gz",
"has_sig": false,
"md5_digest": "2a31154dcdb4d7c9a638fbeeb9c3511d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 13602,
"upload_time": "2025-10-26T12:11:34",
"upload_time_iso_8601": "2025-10-26T12:11:34.308849Z",
"url": "https://files.pythonhosted.org/packages/6b/d9/ef33b8d5de4623b91cecc3754adf31e9e4026ce3b6b48a998b8fab055cb8/python_dmon-0.2.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-26 12:11:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "atomiechen",
"github_project": "python-dmon",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "python-dmon"
}