kontainy 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. kontainy-0.0.1/LICENSE +21 -0
  2. kontainy-0.0.1/PKG-INFO +575 -0
  3. kontainy-0.0.1/README.md +544 -0
  4. kontainy-0.0.1/kontainy/__init__.py +0 -0
  5. kontainy-0.0.1/kontainy/__main__.py +116 -0
  6. kontainy-0.0.1/kontainy/core/__init__.py +0 -0
  7. kontainy-0.0.1/kontainy/core/api.py +321 -0
  8. kontainy-0.0.1/kontainy/core/catalog/__init__.py +154 -0
  9. kontainy-0.0.1/kontainy/core/catalog/base.py +96 -0
  10. kontainy-0.0.1/kontainy/core/catalog/docker.py +368 -0
  11. kontainy-0.0.1/kontainy/core/catalog/podman.py +356 -0
  12. kontainy-0.0.1/kontainy/core/catalog/quadlet.py +58 -0
  13. kontainy-0.0.1/kontainy/core/catalog/run_flags.py +174 -0
  14. kontainy-0.0.1/kontainy/core/constants.py +17 -0
  15. kontainy-0.0.1/kontainy/core/discovery.py +314 -0
  16. kontainy-0.0.1/kontainy/core/readers.py +295 -0
  17. kontainy-0.0.1/kontainy/core/templates.py +322 -0
  18. kontainy-0.0.1/kontainy/core/writers.py +295 -0
  19. kontainy-0.0.1/kontainy/gui/__init__.py +0 -0
  20. kontainy-0.0.1/kontainy/gui/dialogs/__init__.py +1 -0
  21. kontainy-0.0.1/kontainy/gui/dialogs/create_container.py +766 -0
  22. kontainy-0.0.1/kontainy/gui/main_window.py +265 -0
  23. kontainy-0.0.1/kontainy/gui/pages/__init__.py +1 -0
  24. kontainy-0.0.1/kontainy/gui/pages/base.py +157 -0
  25. kontainy-0.0.1/kontainy/gui/pages/containers.py +280 -0
  26. kontainy-0.0.1/kontainy/gui/pages/diagnostics.py +178 -0
  27. kontainy-0.0.1/kontainy/gui/pages/engines.py +149 -0
  28. kontainy-0.0.1/kontainy/gui/pages/learn.py +556 -0
  29. kontainy-0.0.1/kontainy/gui/pages/logs.py +100 -0
  30. kontainy-0.0.1/kontainy/gui/pages/settings.py +484 -0
  31. kontainy-0.0.1/kontainy/gui/styles.py +930 -0
  32. kontainy-0.0.1/kontainy/gui/syntax_highlighter.py +242 -0
  33. kontainy-0.0.1/kontainy/gui/widgets.py +40 -0
  34. kontainy-0.0.1/kontainy/gui/window_menu.py +248 -0
  35. kontainy-0.0.1/kontainy/learn/__init__.py +0 -0
  36. kontainy-0.0.1/kontainy/learn/content.py +508 -0
  37. kontainy-0.0.1/kontainy/rules/__init__.py +13 -0
  38. kontainy-0.0.1/kontainy/rules/catalog.py +611 -0
  39. kontainy-0.0.1/kontainy/rules/engine.py +251 -0
  40. kontainy-0.0.1/kontainy/utils/__init__.py +0 -0
  41. kontainy-0.0.1/kontainy/utils/config.py +234 -0
  42. kontainy-0.0.1/kontainy/utils/workers.py +100 -0
  43. kontainy-0.0.1/kontainy.egg-info/PKG-INFO +575 -0
  44. kontainy-0.0.1/kontainy.egg-info/SOURCES.txt +53 -0
  45. kontainy-0.0.1/kontainy.egg-info/dependency_links.txt +1 -0
  46. kontainy-0.0.1/kontainy.egg-info/entry_points.txt +3 -0
  47. kontainy-0.0.1/kontainy.egg-info/requires.txt +1 -0
  48. kontainy-0.0.1/kontainy.egg-info/top_level.txt +1 -0
  49. kontainy-0.0.1/pyproject.toml +55 -0
  50. kontainy-0.0.1/setup.cfg +4 -0
  51. kontainy-0.0.1/tests/test_catalog.py +50 -0
  52. kontainy-0.0.1/tests/test_discovery.py +40 -0
  53. kontainy-0.0.1/tests/test_rules.py +32 -0
  54. kontainy-0.0.1/tests/test_templates.py +41 -0
  55. kontainy-0.0.1/tests/test_writers.py +73 -0
kontainy-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bayram Kotan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,575 @@
1
+ Metadata-Version: 2.4
2
+ Name: kontainy
3
+ Version: 0.0.1
4
+ Summary: Every Docker and Podman setting, in one interface - a desktop manager for containers, with diagnostics and built-in learning
5
+ Author: Bayram Kotan
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/bayramkotan/kontainy
8
+ Project-URL: Repository, https://github.com/bayramkotan/kontainy
9
+ Project-URL: Issues, https://github.com/bayramkotan/kontainy/issues
10
+ Project-URL: Changelog, https://github.com/bayramkotan/kontainy/releases
11
+ Keywords: docker,podman,container,containers,kubernetes,quadlet,systemd,rootless,oci,devops,gui,pyside6,qt,linux
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: X11 Applications :: Qt
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: System Administrators
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Classifier: Topic :: System :: Installation/Setup
24
+ Classifier: Topic :: Software Development :: Build Tools
25
+ Classifier: Topic :: Education
26
+ Requires-Python: >=3.10
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: PySide6>=6.6
30
+ Dynamic: license-file
31
+
32
+ <p align="center">
33
+ <img src="assets/icon.png" alt="kontainy" width="128" height="128">
34
+ </p>
35
+
36
+ <h1 align="center">๐Ÿ“ฆ kontainy</h1>
37
+
38
+ <p align="center">
39
+ <strong>Every Docker and Podman setting, in one interface</strong><br>
40
+ <sub>Rival tools hide the settings that matter. kontainy shows all of them โ€” explained, with the gotcha attached</sub>
41
+ </p>
42
+
43
+ <p align="center">
44
+ <a href="https://github.com/bayramkotan/kontainy/releases/latest">
45
+ <img src="https://img.shields.io/github/v/release/bayramkotan/kontainy?style=for-the-badge&color=89b4fa&logo=github" alt="Release">
46
+ </a>
47
+ <img src="https://img.shields.io/badge/Platform-Linux%20%7C%20Windows%20%7C%20macOS-f9e2af?style=for-the-badge" alt="Platform">
48
+ <a href="https://pypi.org/project/kontainy/">
49
+ <img src="https://img.shields.io/pypi/v/kontainy?style=for-the-badge&color=a6e3a1&logo=pypi&logoColor=white" alt="PyPI">
50
+ </a>
51
+ <a href="https://github.com/bayramkotan/kontainy/stargazers">
52
+ <img src="https://img.shields.io/github/stars/bayramkotan/kontainy?style=for-the-badge&color=f5c2e7&logo=github" alt="Stars">
53
+ </a>
54
+ </p>
55
+
56
+ <p align="center">
57
+ <a href="#-why-kontainy-exists">Why</a> โ€ข
58
+ <a href="#-educational-by-design">Educational</a> โ€ข
59
+ <a href="#-install">Install</a> โ€ข
60
+ <a href="#-features">Features</a> โ€ข
61
+ <a href="#-the-settings-catalogue">Settings</a> โ€ข
62
+ <a href="#-diagnostics">Diagnostics</a> โ€ข
63
+ <a href="#-templates">Templates</a> โ€ข
64
+ <a href="#-learn">Learn</a> โ€ข
65
+ <a href="#-privilege-model">Privileges</a> โ€ข
66
+ <a href="#-quick-start">Quick Start</a> โ€ข
67
+ <a href="#-build-from-source">Build</a>
68
+ </p>
69
+
70
+ ---
71
+
72
+ ## ๐ŸŽฏ Why kontainy exists
73
+
74
+ Run Docker and Podman on the same machine for a week and you will meet all of
75
+ this: `docker context use` reports success and changes nothing, containers
76
+ "disappear" after installing Docker Desktop, a memory limit is accepted and
77
+ silently ignored, a log file quietly fills the root disk, and `podman pull
78
+ nginx` fails on a name that works everywhere else.
79
+
80
+ None of these produce an error message. That is the problem kontainy is built
81
+ around.
82
+
83
+ **kontainy does not trust the context system.** It connects to *every* socket
84
+ it finds, separately, and shows them all in one table with an Engine column. A
85
+ container is never lost โ€” you can see which engine holds it.
86
+
87
+ <p align="center">
88
+ <img src="assets/screenshots/engines.png" alt="Engines โ€” the resolved context chain and every reachable engine" width="850">
89
+ </p>
90
+
91
+ The `docker` CLI resolves its target through five layers, and the top one wins:
92
+
93
+ ```
94
+ 1. -H / --host flag
95
+ 2. DOCKER_HOST environment variable
96
+ 3. DOCKER_CONTEXT environment variable
97
+ 4. ~/.docker/config.json โ†’ currentContext
98
+ 5. unix:///var/run/docker.sock
99
+ ```
100
+
101
+ If `DOCKER_HOST` is set, the context is ignored completely โ€” which is why
102
+ `docker context use` can say "success" and do nothing at all. kontainy shows
103
+ this chain layer by layer and marks the winner.
104
+
105
+ ---
106
+
107
+ ## ๐ŸŽ“ Educational by Design
108
+
109
+ kontainy never hides the command it is running. Create a container, change a
110
+ setting, apply a fix โ€” the **exact shell command** appears in the command strip
111
+ at the bottom of every page, ready to copy. Every command is also written to a
112
+ persistent history you can export as a shell script.
113
+
114
+ The point is not convenience. The point is that you should be able to do the
115
+ same thing **without kontainy** afterwards.
116
+
117
+ <p align="center">
118
+ <img src="assets/screenshots/create_container.png" alt="Create Container โ€” live command preview growing as options are set" width="850">
119
+ </p>
120
+
121
+ This runs through the whole application:
122
+
123
+ - **Create Container** โ€” the preview grows as you tick boxes, syntax
124
+ highlighted, and the same definition renders as a `docker run` command, a
125
+ systemd Quadlet unit, or a compose service
126
+ - **Settings** โ€” every key shows its CLI equivalent, which file it lives in,
127
+ and whether a restart is needed
128
+ - **Diagnostics** โ€” every finding ends in a command, and says whether it runs
129
+ in user scope or needs root
130
+ - **Learn** โ€” every snippet is a command you can actually type, with a Copy
131
+ button
132
+ - **History & Log** โ€” every command this session, filterable, exportable
133
+
134
+ ---
135
+
136
+ ## ๐Ÿ“ฆ Install
137
+
138
+ ```bash
139
+ pip install kontainy
140
+ kontainy
141
+ ```
142
+
143
+ <details>
144
+ <summary><b>๐Ÿง On Linux, pip may refuse to install</b></summary>
145
+ <br>
146
+
147
+ Most current distributions mark the system Python as *externally managed*
148
+ (PEP 668), so a plain `pip install` stops with
149
+ `error: externally-managed-environment`. Two ways around it:
150
+
151
+ ```bash
152
+ # Isolated โ€” recommended, no system packages touched
153
+ pipx install kontainy
154
+
155
+ # Into the system Python โ€” needs the override flag
156
+ sudo pip install kontainy --break-system-packages --no-cache-dir -U
157
+ ```
158
+
159
+ The same flag applies when upgrading a system-wide install later on.
160
+
161
+ </details>
162
+
163
+ Or download the standalone binary โ€” **no Python required:**
164
+
165
+ | Platform | File | Notes |
166
+ |:--------:|:-----|:------|
167
+ | ๐Ÿง **Linux** | [`kontainy-x86_64.AppImage`](https://github.com/bayramkotan/kontainy/releases/latest) | `chmod +x` then run โ€” the fully supported target |
168
+ | ๐ŸชŸ **Windows** | [`kontainy.exe`](https://github.com/bayramkotan/kontainy/releases/latest) | Portable. Docker Desktop and `podman machine` only |
169
+ | ๐ŸŽ **macOS** | [`kontainy-macOS-arm64`](https://github.com/bayramkotan/kontainy/releases/latest) | Apple Silicon |
170
+
171
+ > **Linux is the first-class target.** Rootless Podman, Quadlet, systemd units,
172
+ > subuid mapping and linger only exist there, and roughly half the diagnostic
173
+ > rules are Linux-specific. The Windows and macOS builds work against Docker
174
+ > Desktop and `podman machine`, and disable what does not apply.
175
+
176
+ ---
177
+
178
+ ## โœจ Features
179
+
180
+ <table>
181
+ <tr>
182
+ <td width="50%" valign="top">
183
+
184
+ ### ๐Ÿ”Œ Engine discovery
185
+ - Connects to **every socket found**, never just the active context
186
+ - Docker local daemon, Docker Desktop for Linux, Rancher Desktop, Colima
187
+ - Podman **rootful and rootless** sockets
188
+ - Resolved CLI target chain, with the winning layer marked
189
+ - Detects the `podman-docker` shim (`docker` that is really Podman)
190
+ - **No external dependencies** โ€” talks the Docker Engine API over the UNIX
191
+ socket directly, no `docker-py`, no `requests`
192
+
193
+ ### ๐Ÿ“ฆ Containers
194
+ - Every engine in **one table**, with an Engine column
195
+ - Start, stop, restart, remove
196
+ - Summary, port map and raw JSON inspection
197
+ - Create with the **full run surface** (see below)
198
+ - 17 ready-made templates
199
+
200
+ </td>
201
+ <td width="50%" valign="top">
202
+
203
+ ### โš™๏ธ Settings
204
+ - **152 keys** across Docker and Podman
205
+ - Declared value, **effective value**, and the file it came from
206
+ - The full override chain: `/usr/share` โ†’ `/etc` โ†’ `~/.config`
207
+ - Red flag when declared and effective disagree โ€” the setting is being ignored
208
+ - **65 keys editable** without elevation; the rest read-only with a command
209
+ - Comment-preserving TOML writes, atomic, with a `.bak` backup
210
+
211
+ ### ๐Ÿ”ฌ Diagnostics
212
+ - **19 rules**: detect โ†’ explain โ†’ fix command
213
+ - Each links to a catalogue key and a Learn topic
214
+ - Detection never requires root
215
+
216
+ ### ๐Ÿ“š Learn
217
+ - 16 categories, from namespaces to Kubernetes, KVM and LXC
218
+ - Syntax-highlighted, copyable snippets
219
+
220
+ </td>
221
+ </tr>
222
+ </table>
223
+
224
+ ---
225
+
226
+ ## โš™๏ธ The settings catalogue
227
+
228
+ This is what kontainy is for. Docker Desktop and Podman Desktop were designed
229
+ for ease of use, and hide most of the configuration surface as a result โ€”
230
+ `daemon.json` gets a raw JSON box with no explanation, `containers.conf` gets
231
+ nothing at all.
232
+
233
+ | | Docker Desktop | Podman Desktop | **kontainy** |
234
+ |---|:---:|:---:|:---:|
235
+ | Start / stop containers | โœ… | โœ… | โœ… |
236
+ | `daemon.json` editing | raw JSON box | โœ— | **structured, explained, validated** |
237
+ | `containers.conf` / `storage.conf` | โœ— | โœ— | **full catalogue** |
238
+ | `registries.conf`, `short-name-mode` | โœ— | โœ— | **full catalogue** |
239
+ | Which file a value came from | โœ— | โœ— | **override chain shown** |
240
+ | Declared vs effective value | โœ— | โœ— | **compared, mismatch flagged** |
241
+ | All engines in one table | โœ— | โœ— | **โœ… with Engine column** |
242
+ | Where your terminal points | โœ— | โœ— | **โœ… resolved chain** |
243
+ | Gotcha note per setting | โœ— | โœ— | **โœ… 66 of 152** |
244
+
245
+ **152 settings** โ€” 56 Docker, 67 Podman, 29 shared โ€” spread across ten
246
+ surfaces:
247
+
248
+ | Surface | Keys | Covers |
249
+ |:---|:---:|:---|
250
+ | ๐ŸŒ Networking | 25 | address pools, bridge, MTU, DNS, iptables/nftables, netavark, pasta |
251
+ | ๐Ÿ” Security | 23 | capabilities, seccomp, AppArmor, SELinux, user namespaces |
252
+ | ๐Ÿ“Š Resource limits | 23 | memory, CPU, PIDs, ulimits, block I/O, OOM |
253
+ | โš™๏ธ Engine / Daemon | 19 | runtimes, cgroup manager, live restore, events |
254
+ | ๐Ÿ“ฆ Registry | 18 | mirrors, insecure registries, short-name mode, pull policy |
255
+ | ๐Ÿงฑ Container | 14 | restart policy, healthcheck, mounts, init, timezone |
256
+ | ๐Ÿ’พ Storage | 13 | drivers, graphroot, overlay options, quotas |
257
+ | ๐Ÿ”ง systemd / Quadlet | 8 | `.container` unit keys, auto-update, linger |
258
+ | ๐Ÿ“ Logging | 6 | drivers and rotation |
259
+ | ๐Ÿ—๏ธ Build | 3 | BuildKit and cache garbage collection |
260
+
261
+ Every entry carries: the key, the file it lives in, its type and valid choices,
262
+ the default, the **CLI equivalent**, whether a restart is needed, user or root
263
+ scope, a risk level, a description โ€” and for 66 of them, the **gotcha**: what
264
+ breaks when the setting is misunderstood.
265
+
266
+ > Listing a setting is easy. Writing down what happens when it is wrong is not,
267
+ > and no rival tool does it.
268
+
269
+ ---
270
+
271
+ ## ๐Ÿ”ฌ Diagnostics
272
+
273
+ The equivalent of a linter for your container setup. Every rule says three
274
+ things: what was found, why it happens, and the command that fixes it.
275
+
276
+ <p align="center">
277
+ <img src="assets/screenshots/diagnostics.png" alt="Diagnostics โ€” findings with explanation and fix command" width="850">
278
+ </p>
279
+
280
+ **19 rules**, none of which need root to detect:
281
+
282
+ | Group | Rules | Examples |
283
+ |:---|:---:|:---|
284
+ | **CTX** context | 6 | `DOCKER_HOST` overriding the context ยท Desktop leftovers (`credsStore`) ยท CLI plugins shadowing the distribution's ยท the `podman-docker` shim |
285
+ | **POD** Podman / rootless | 4 | socket not enabled ยท linger off, so containers die at logout ยท missing `subuid` range ยท auto-update timer inactive |
286
+ | **NET** networking | 3 | Docker address pool clashing with the local network or VPN ยท rootless ports below 1024 ยท nftables without the iptables layer |
287
+ | **DSK** disk | 2 | unlimited `json-file` logs filling the root disk ยท BuildKit cache that `image prune` does not touch |
288
+ | **RES** resources | 1 | cgroupfs on rootless cgroup v2, where limits are silently ignored |
289
+ | **SVC** systemd | 1 | `docker.socket` restarting the daemon you just stopped |
290
+ | **DKR** Docker Desktop | 1 | `/dev/kvm` missing or not readable |
291
+ | **PER** permissions | 1 | socket permission denied, group membership not yet applied |
292
+
293
+ ---
294
+
295
+ ## ๐Ÿ“ฆ Templates
296
+
297
+ *You should not have to hunt for example code.* Seventeen ready-made
298
+ definitions, each carrying the details people get wrong when copying from a
299
+ blog post: the named volume that keeps the data, the environment variable the
300
+ image will not start without, a health start period long enough for the service
301
+ to come up, and a capability set that is not simply `--privileged`.
302
+
303
+ | Category | Templates |
304
+ |:---|:---|
305
+ | **Databases** | PostgreSQL 16 ยท MariaDB 11 ยท Redis 7 ยท MongoDB 7 |
306
+ | **Web** | nginx ยท Caddy 2 ยท Traefik 3 |
307
+ | **Tooling** | MinIO ยท Gitea ยท Vaultwarden ยท n8n ยท Pi-hole |
308
+ | **Monitoring** | Grafana ยท Prometheus |
309
+ | **Development** | JupyterLab ยท code-server ยท Ollama |
310
+
311
+ Each renders three ways from the same definition:
312
+
313
+ <details>
314
+ <summary><b>๐Ÿ“‹ PostgreSQL, all three formats</b></summary>
315
+ <br>
316
+
317
+ ```bash
318
+ podman run -d \
319
+ --name postgres \
320
+ --restart=unless-stopped \
321
+ -p 5432:5432 \
322
+ -v pgdata:/var/lib/postgresql/data \
323
+ -e POSTGRES_USER=postgres \
324
+ -e POSTGRES_PASSWORD=<CHANGE_ME> \
325
+ --cap-drop=ALL \
326
+ --cap-add=CHOWN --cap-add=DAC_OVERRIDE --cap-add=FOWNER \
327
+ --cap-add=SETGID --cap-add=SETUID \
328
+ --memory=1g \
329
+ --health-cmd='pg_isready -U postgres' \
330
+ --health-start-period=30s \
331
+ docker.io/library/postgres:16
332
+ ```
333
+
334
+ ```ini
335
+ [Unit]
336
+ Description=PostgreSQL 16
337
+
338
+ [Container]
339
+ Image=docker.io/library/postgres:16
340
+ PublishPort=5432:5432
341
+ Volume=pgdata:/var/lib/postgresql/data
342
+ Environment=POSTGRES_PASSWORD=CHANGE_ME
343
+ DropCapability=ALL
344
+ AddCapability=CHOWN
345
+ AutoUpdate=registry
346
+
347
+ [Service]
348
+ Restart=always
349
+
350
+ [Install]
351
+ WantedBy=default.target
352
+ ```
353
+
354
+ ```yaml
355
+ services:
356
+ postgres:
357
+ image: docker.io/library/postgres:16
358
+ restart: unless-stopped
359
+ ports:
360
+ - "5432:5432"
361
+ volumes:
362
+ - pgdata:/var/lib/postgresql/data
363
+ cap_drop:
364
+ - ALL
365
+
366
+ volumes:
367
+ pgdata:
368
+ ```
369
+
370
+ </details>
371
+
372
+ **Quadlet generation is the part no other GUI has.** `podman generate systemd`
373
+ is deprecated; Quadlet replaced it, and nothing but a text editor writes those
374
+ units today.
375
+
376
+ ---
377
+
378
+ ## ๐Ÿงฑ Create Container
379
+
380
+ Rival tools give you image, name, ports and volumes. kontainy gives you the
381
+ whole surface, across seven tabs, with a live command preview underneath:
382
+
383
+ | Tab | Covers |
384
+ |:---|:---|
385
+ | **Basics** | image, name, command, entrypoint, working dir, user, restart policy, environment, labels |
386
+ | **Network** | network mode, published ports, hostname, DNS, extra hosts |
387
+ | **Storage** | volumes and bind mounts with `:ro` `:z` `:Z` propagation, tmpfs, read-only root, shm size |
388
+ | **Resources** | memory, swap, CPUs, cpuset, shares, PID limit, ulimits, OOM score |
389
+ | **Security** | privileged, no-new-privileges, user namespace, seccomp, AppArmor, SELinux, **18 capability checkboxes** |
390
+ | **Health** | command, interval, timeout, retries, start period |
391
+ | **Advanced** | init, TTY, log driver and options, sysctls, devices, pod, passthrough flags |
392
+
393
+ ---
394
+
395
+ ## ๐Ÿ“š Learn
396
+
397
+ kontainy teaches container management, not kontainy. **16 categories**,
398
+ target 204 topics, each with explanation, diagram, table and runnable snippet.
399
+
400
+ | Category | Topics | Covers |
401
+ |:---|:---:|:---|
402
+ | โšก Quick Start | 8 | first container, ports, volumes, cleanup |
403
+ | ๐Ÿ“ฆ Container Internals | 14 | namespaces, cgroups v1/v2, capabilities, overlayfs, OCI specs |
404
+ | ๐Ÿณ Docker | 18 | architecture, run flags, contexts, `daemon.json`, BuildKit |
405
+ | ๐Ÿฆญ Podman | 18 | daemonless design, rootless, pods, `containers.conf` |
406
+ | โš™๏ธ systemd & Quadlet | 10 | units, linger, socket activation, `.container` files |
407
+ | โ˜ธ๏ธ Kubernetes | 20 | pods, deployments, services, kubeconfig, probes, RBAC |
408
+ | ๐Ÿ–ฅ๏ธ KVM / QEMU / libvirt | 12 | domain XML, qcow2, virtio, snapshots, VFIO passthrough |
409
+ | ๐Ÿงฑ LXC / LXD / Incus | 10 | system containers, idmap, storage pools, clustering |
410
+ | ๐ŸŒ Networking | 14 | bridges, macvlan, DNS, nftables, MTU, subnet clashes |
411
+ | ๐Ÿ’พ Storage | 12 | volumes, bind mounts, overlay2, quotas, SELinux labels |
412
+ | ๐Ÿ” Security | 14 | rootless, capabilities, seccomp, signing, scanning, SBOM |
413
+ | ๐Ÿ—๏ธ Images & Registries | 12 | manifests, digests, multi-arch, buildah, skopeo, mirrors |
414
+ | ๐ŸŽผ Compose & Orchestration | 10 | compose schema, profiles, healthchecks |
415
+ | ๐Ÿ” Troubleshooting | 14 | lost containers, permissions, full disks, exit codes |
416
+ | ๐Ÿš€ Performance | 10 | crun vs runc, overlay vs fuse, cache strategy |
417
+ | ๐Ÿ”„ Migration & Interop | 8 | Docker to Podman, the shim, Desktop leftovers, WSL2, CI |
418
+
419
+ Diagnostic rules link into Learn: the rule tells you *what to do*, the topic
420
+ explains *why*.
421
+
422
+ ---
423
+
424
+ ## ๐Ÿ” Privilege model
425
+
426
+ **kontainy never elevates privileges.** No `pkexec`, no `sudo`, no `runas`.
427
+
428
+ | File | Scope | What kontainy does |
429
+ |:---|:---:|:---|
430
+ | `~/.config/containers/containers.conf` | ๐Ÿ‘ค user | **writes** |
431
+ | `~/.config/containers/storage.conf` | ๐Ÿ‘ค user | **writes** |
432
+ | `~/.config/containers/registries.conf` | ๐Ÿ‘ค user | **writes** |
433
+ | `~/.config/containers/systemd/*` (Quadlet) | ๐Ÿ‘ค user | **writes** |
434
+ | `~/.docker/config.json` | ๐Ÿ‘ค user | **writes** |
435
+ | `/etc/docker/daemon.json` | ๐Ÿ–ฅ root | read-only + copyable command |
436
+ | `/etc/containers/*` | ๐Ÿ–ฅ root | read-only + copyable command |
437
+ | `/etc/subuid`, `/etc/subgid` | ๐Ÿ–ฅ root | read-only + copyable command |
438
+ | `/usr/share/containers/*` | ๐Ÿ“ฆ distribution | read-only, shown in the override chain |
439
+
440
+ Writes take a `.bak` backup, land atomically through `os.replace` โ€” a
441
+ half-written `daemon.json` stops the daemon from starting at all โ€” and preserve
442
+ existing comments in TOML files, including the ones explaining the very setting
443
+ being changed.
444
+
445
+ Rootless Podman keeps its entire configuration under `~/.config`, which is why
446
+ this model costs so little: **65 of the 152 settings are directly editable.**
447
+
448
+ ---
449
+
450
+ ## ๐Ÿš€ Quick Start
451
+
452
+ ### From PyPI
453
+
454
+ ```bash
455
+ pip install kontainy
456
+ kontainy
457
+ ```
458
+
459
+ ### From source
460
+
461
+ ```bash
462
+ git clone https://github.com/bayramkotan/kontainy.git
463
+ cd kontainy
464
+ python -m venv .venv
465
+ .venv/bin/pip install -r requirements.txt
466
+ .venv/bin/python main.py
467
+ ```
468
+
469
+ ### Linux โ€” system dependencies
470
+
471
+ PySide6 needs the XCB platform libraries. On a minimal install:
472
+
473
+ ```bash
474
+ # Arch / CachyOS
475
+ sudo pacman -S --needed libxcb xcb-util-cursor xcb-util-keysyms \
476
+ xcb-util-wm xcb-util-image xcb-util-renderutil libxkbcommon-x11
477
+
478
+ # Debian / Ubuntu
479
+ sudo apt install libxcb-cursor0 libxcb-xinerama0 libxcb-icccm4 \
480
+ libxkbcommon-x11-0 libxcb-keysyms1 libxcb-image0 libxcb-render-util0
481
+
482
+ # Fedora
483
+ sudo dnf install xcb-util-cursor xcb-util-keysyms xcb-util-wm \
484
+ xcb-util-image xcb-util-renderutil libxkbcommon-x11
485
+ ```
486
+
487
+ For Podman support, enable the API socket:
488
+
489
+ ```bash
490
+ systemctl --user enable --now podman.socket
491
+ loginctl enable-linger $USER # so containers survive logout
492
+ ```
493
+
494
+ ### CLI
495
+
496
+ kontainy answers three questions without opening a window:
497
+
498
+ ```bash
499
+ kontainy --scan # the context chain, every engine, systemd unit states
500
+ kontainy --doctor # run every diagnostic rule and print the findings
501
+ kontainy --stats # catalogue, rule and Learn counts
502
+ ```
503
+
504
+ ```console
505
+ $ kontainy --scan
506
+ === Terminal target ===
507
+ >> DOCKER_HOST (environment) unix:///home/you/.docker/desktop/docker.sock
508
+ DOCKER_CONTEXT (environment) โ€”
509
+ config.json โ†’ currentContext desktop-linux
510
+ built-in default unix:///var/run/docker.sock
511
+ EFFECTIVE: unix:///home/you/.docker/desktop/docker.sock
512
+
513
+ === Engines found ===
514
+ * unix:///home/you/.docker/desktop/docker.sock docker 29.8.0 (rootful)
515
+ unix:///run/user/1000/podman/podman.sock podman 6.1.2 (rootless)
516
+ unix:///run/docker.sock docker 29.8.1 (rootful)
517
+ ```
518
+
519
+ ---
520
+
521
+ ## ๐Ÿ“ธ Screenshots
522
+
523
+ <p align="center">
524
+ <img src="assets/screenshots/settings.png" alt="Settings โ€” declared value, effective value and the override chain" width="850">
525
+ </p>
526
+ <p align="center">
527
+ <img src="assets/screenshots/learn.png" alt="Learn โ€” collapsible topic cards with highlighted snippets" width="850">
528
+ </p>
529
+ <p align="center">
530
+ <img src="assets/screenshots/containers.png" alt="Containers โ€” every engine in one table" width="850">
531
+ </p>
532
+
533
+ ---
534
+
535
+ ## ๐Ÿ—๏ธ Build from source
536
+
537
+ Builds are made in CI, on each platform's own runner โ€” there is no
538
+ cross-compilation. Pushing a `v*` tag runs the whole pipeline: tests, then
539
+ Windows, macOS ARM64 and Linux AppImage builds, then a GitHub release with a
540
+ categorised changelog, then PyPI.
541
+
542
+ ```bash
543
+ python build.py # one file, windowed -> dist/kontainy[.exe]
544
+ python build.py --debug # one file, console
545
+ python build.py --onedir # a directory -> dist/kontainy/
546
+ ```
547
+
548
+ Run the test suite โ€” 245 tests in under four seconds, because PySide6 is
549
+ stubbed and the suite covers decisions rather than widgets:
550
+
551
+ ```bash
552
+ pip install pytest
553
+ python -m pytest -q
554
+ ```
555
+
556
+ ---
557
+
558
+ ## ๐ŸŒ Translations
559
+
560
+ The interface is English. A translation layer covering eleven languages is
561
+ planned; see the project roadmap.
562
+
563
+ ---
564
+
565
+ ## ๐Ÿ“ License
566
+
567
+ MIT โ€” see [LICENSE](LICENSE).
568
+
569
+ <div align="center">
570
+
571
+ โญ **If kontainy helps you, consider [giving it a star](https://github.com/bayramkotan/kontainy)!** โญ
572
+
573
+ [๐Ÿ› Report Bug](https://github.com/bayramkotan/kontainy/issues) ยท [๐Ÿ’ก Request Feature](https://github.com/bayramkotan/kontainy/issues)
574
+
575
+ </div>