# Ajenti: a Python server panel that edits your existing config instead of replacing it

> A modular Linux and BSD admin panel built on Python 3 and AngularJS whose defining promise is non-destructive: it reads the config files you already have and leaves comments and formatting intact.

**ajenti/ajenti** — Ajenti Core and stock plugins

- Repository: https://github.com/ajenti/ajenti
- Website: http://ajenti.org/core/
- Stars: 7,968 · Forks: 855
- Language: Python
- License: MIT
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/ajenti-ajenti

## Non-destructive config editing is the feature everything else serves

Most web server panels generate configuration from a form and write it out whole. Ajenti makes the opposite promise, and the README puts it in the feature list under caring: it does not overwrite your config files, options and comments, and all changes are non-destructive.

That is a stronger constraint than it sounds. Parsing an `nginx.conf` or a systemd unit while preserving the comments someone wrote six months ago, the ordering they chose, and the blank lines that make the file readable, means the panel cannot treat the file as a data structure it owns. It has to treat it as text it is a guest in. That is the reason the project claims it picks up your current configuration and works on your existing system as is, without any preparation.

The adjacent claim is that Ajenti is easy to install with pip and a provided script. Together, these two features define the product: install into a running server, see the machine you already have, and change one setting without rewriting a file you have hand-maintained for years.

The practical test is straightforward. Take a config file with comments and unusual formatting, change a value through the panel, and see what the diff looks like. That is the feature, and everything else is secondary to it.

## Python 3 and AngularJS, which dates the stack

Ajenti 2 is described as providing a new interface and a better architecture, developed with Python 3 and AngularJS. That pairing is the most important fact about the project in 2026, because AngularJS reached end of life years ago and is no longer maintained or patched.

The consequences are practical rather than ideological. The server side is ordinary Python and the plugin story is Python, so that half is unaffected. The browser side depends on an unmaintained framework, which means you do not get security patches from upstream, you are not on a supported path for new front-end work, and any plugin UI you write is bound to that framework's patterns. For an internal admin panel on a machine you control, that is often an acceptable trade. For anything you intend to expose more widely, it is a factor to weigh.

The repository topics list `angular`, `javascript`, `python`, `linux` and `panel`, so the mix is acknowledged rather than hidden. The `package.json` at the root is thin, holding a coffeelint config with a four space indentation rule and a maximum line length of 999, plus Babel 6 era dev dependencies including `babel-preset-es2015` and `babel-plugin-external-helpers`. Babel 6 dates from 2015, which corroborates the frontend vintage.

Lightweight is another stated goal: a small memory footprint and low CPU use, with the claim that it runs on low-end machines, wall plugs and routers. That is a plausible fit for the design, since a panel that shells out to read config and writes back text does not need much.

## The Makefile is the clearest document of how the project is built

Most projects bury their build system. Ajenti's `Makefile` is short, readable and unusually informative, because it is a list of the maintainers' actual workflows.

Running a development instance takes one target:

```bash
cd ajenti-panel && ./ajenti-panel -v --autologin --plugins ../plugins --dev -c
```

The flags explain the architecture. Plugins are loaded from a directory outside the package rather than being baked in, which is what makes the modular model real. A custom config file path is threaded through every run target as a variable, so a developer can test against a different configuration than production uses. The difference between `run` and `rundev` is the presence of `--dev` and of `--autologin`, and there is a separate `rundevlogin` target that keeps the login screen while still running in dev mode.

`rund` adds a `-d` flag, which in a panel of this shape is the detach option.

The build itself delegates to a separate tool called `ajenti-dev-multitool`, with a `--msgfmt` pass for compiling message catalogues and a `--build` pass for the packages. The same multitool handles Crowdin integration, with targets for extracting strings, pushing, pulling and adding translations, and there is a `check` target that looks for outdated dependencies. Uploads go through `setup.py sdist` in both `ajenti-core` and `ajenti-panel` followed by `twine upload` under a team identifier, which tells you the project publishes to PyPI as a two-package split.

## A two package split with a separate plugin directory

The repository tree reveals the packaging: `ajenti-core/` and `ajenti-panel/` are the two Python distributions, and `plugins/` is a directory of its own holding the stock plugins, given that the README describes the repository as Ajenti Core and stock plugins.

That split is the reason for the `ajenti-dev-multitool` tool. Building the core, building the panel and building a given plugin are three related but separate jobs, and the Makefile's plugin upload target loops over them with a `--setuppy 'sdist'` argument rather than building them one at a time. The `clean` target clears `build`, `dist` and `.last-upload` directories under each plugin, which tells you the build output layout.

The tree also shows the testing arrangement, which is broader than a single framework usually manages. There is `tests-pytest/` for the Python side, `tests-karma/` for the frontend, and `e2e/` with its own `./run` script as the default test target. The `webdriver` and `webdriver-update` targets invoke `node_modules/protractor/bin/webdriver-manager` from inside `e2e/`, so the end to end suite drives a real browser through Selenium or WebDriver rather than mocking the DOM. `pylama.ini` handles Python linting and `.deepsource.toml` points at a hosted static analysis service.

`official_plugins.json` at the repository root is a small but telling file: the canonical list of stock plugins lives in the repository rather than only in the plugin registry, which makes the set of bundled plugins auditable.

For distribution beyond pip, there is a `debian/` directory and a `scripts/build_deb.sh` invoked by a `build_dev` target, so there is a real Debian packaging path rather than only source installs.

## Three releases in 2026, two of them security work

The published releases are recent and short. v2.2.15 on 2026-03-31 adds anti-framing headers and more checks on tasks. v2.2.13 on 2026-02-24 is entirely security: more checks on headers, and cache isolation made time limited. v2.2.12 on 2026-02-15 is the most substantial of the three, and it mixes documentation, dependency and hardening work.

From v2.2.12: the install page was updated to make venv installation mandatory, gevent and zope.event were pinned to avoid conflicts, socketio and engineio were updated, a deprecated distro library method was replaced, and the standard `cgi` module was swapped for `legacy-cgi` on Debian 13 and above. NTP support was added for ntpsec-ntpdate on Debian 13 and later. Existing usernames are now checked before a login attempt is made, TOTP authentication was hardened with a secret key, a sortable view bug with an empty array was fixed, and the network plugin's IP manager was refactored to avoid injection.

That is a good sample of what a mature panel project's release notes look like: dependency pins, deprecation fixes for a specific distribution version, and a handful of genuine security changes with contributors named.

The last push was on 2026-09-12, about five months after the newest tag, so commits are landing on master without a release cutting them yet.

The venv requirement deserves attention for anyone installing today. Making it mandatory means a system-wide install path is no longer the documented route, which is the right call for a panel that lives inside a Python environment touching system configuration.

## Writing a plugin, and where the documentation actually lives

Extensibility is listed as a feature with a specific claim attached: Ajenti 2 is easily extensible using Python, and plugin development through the Ajenti APIs is quick. The README links straight to a write your first plugin page.

The stock plugin set covers the ground the screenshots suggest: login, dashboard, settings, a plugin manager, systemd service control and a terminal. Those six views are the whole visible product, and everything beyond them comes from plugins. The terminal in particular explains the architecture better than any prose would: the panel can give you an interactive shell in the browser, which is a shortcut to the same thing SSH would give you, and which is exactly why the lightweight and non-destructive claims need testing on a machine you care about.

Documentation lives at docs.ajenti.org, with the README linking to an install page and a developer introduction. It is built with Sphinx, visible in the `doc` target which runs `sphinx-build` into `docs/build/html`, and translations go through Crowdin with the badge and the Makefile targets both pointing there. `requirements-rtd.txt` at the root holds the readthedocs specific dependencies, and `.readthedocs.yaml` configures the build.

Two files are worth reading before installing. `CHANGELOG.txt` at the root holds the full history, which the GitHub releases only summarise. And `SECURITY.md` exists, which for a panel that runs as root on your server is a reasonable expectation rather than an impressive one.

The homepage is ajenti.org/core/, and the project description in the repository metadata is the plainest summary available: Ajenti Core and stock plugins. That is a small project with a clear boundary, which for an admin panel is a virtue.

## Conclusion

Ajenti makes most sense for a single server or a handful of boxes that someone actually administers, where the alternative is SSH and a stack of `vi` sessions. Its central claim is the one to judge it on: the panel parses the configuration files already on disk and rewrites them without discarding your comments or reformatting everything around your change. If that holds on your system's files, Ajenti is comfortable to leave switched on. If it does not, you have found the project's real boundary. Plugin development is a first class activity rather than a bolted-on API, the README states it plainly, and the tooling around it, including a dev multitool for builds, message catalogues and outdated dependency checks, shows a mature build process. Last push was on 2026-09-12, the newest release is v2.2.15 from 2026-03-31, and the venv based install is now documented as mandatory.

## FAQ

### What is Ajenti and what does it manage?

Ajenti is a modular server admin panel for Linux and BSD. The stock plugins cover login, a dashboard, settings, plugin management, systemd service control and a browser terminal, and more can be added as Python plugins. The distinguishing claim is that it reads and edits the configuration files already on your system without overwriting your comments or options, rather than generating files from a form.

### How do I install Ajenti on a server?

The README points to a pip based install using a provided script, and as of v2.2.12 the documentation makes a venv installation mandatory rather than optional. The Makefile shows the panel entry point being launched as `./ajenti-panel` from `ajenti-panel/`, with plugins loaded from a separate directory and a custom config file passed in with a flag. Full steps are on the install page at docs.ajenti.org.

### How does Ajenti compare with Cockpit?

The repositories do not make that comparison, so the honest answer is to compare the design goals. Ajenti's stated priorities are a small memory and CPU footprint so it can run on wall plugs and routers, and non-destructive editing of existing configuration files. Cockpit ships as a package tied to systemd conventions on Fedora and Debian derivatives. Which fits better depends on your distribution and on whether preserving hand-edited config matters more to you than packaging convenience.

## Sources

- [ajenti/ajenti on GitHub](https://github.com/ajenti/ajenti)
- [License: MIT](https://github.com/ajenti/ajenti/blob/master/LICENSE)
- [Project website](http://ajenti.org/core/)
- [README](https://github.com/ajenti/ajenti/blob/master/README.md)
- [Releases](https://github.com/ajenti/ajenti/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ajenti-ajenti
