Configurable desktop launcher for Docker-based applications
Project description
docker-app-launcher
Configurable desktop launcher for Docker-based applications. One persistent window. It opens, shows progress, and never closes itself — no dialog chains.
Quick Start
pip install docker-app-launcher
Python API (3 lines)
from docker_app_launcher import LauncherConfig, launch
launch(LauncherConfig(
app_name="My App",
container_name="my-app",
default_port=8080,
))
CLI
docker-app-launcher --config launcher.json # open the window
docker-app-launcher --version # print the launcher version and exit
docker-app-launcher --check # is Docker running?
docker-app-launcher --status # print state and exit
docker-app-launcher --install --port 9000 # build + start headless
docker-app-launcher --start # start the stopped app
docker-app-launcher --stop # stop the running app
docker-app-launcher --uninstall # remove containers/images
docker-app-launcher --cleanup # remove stale leftovers
docker-app-launcher --open # open the app in the browser
docker-app-launcher --debug ... # verbose logging to stdout + launcher-debug.log
launcher.json
Everything is configurable. Only app_name is required — the rest is derived
(slug, container/image names, compose project, config dir) or defaulted.
{
"app_name": "My App",
"container_name": "my-app",
"default_port": 8080,
"compose_file": "docker-compose.prod.yml",
"install_dir": "/opt/my-app",
"health_check_path": "/api/health",
"health_check_key": "status",
"health_check_value": "ok",
"repo_url": "https://github.com/owner/repo",
"app_version": "0.4.0",
"update_check_enabled": true,
"internal_ports": { "nginx": 80 },
"env_internal_port_keys": { "nginx": "NGINX_PORT" },
"show_advanced_ports": true,
"locale": "en"
}
internal_ports,env_internal_port_keys, andshow_advanced_portsare optional expert fields — omit them and the launcher behaves exactly as before (single host port, no advanced panel).
Features
- One persistent window — never closes itself; only the X closes it.
- Docker check on startup — distinguishes not installed / running / stopped / no Docker.
- Live build progress — the Docker build is streamed line-by-line into the window.
- Configurable port — editable in the GUI and via
--port, validated and persisted (tolauncher.jsonand the.envnext to the compose file, so the launcher and Compose can't disagree). - Live port changes — the port field stays editable while the app runs; "Apply port" validates, rewrites
.env, and recreates the stack in seconds (no rebuild — only the published host port changed), then health-checks on the new port. - Advanced internal ports (experts) — optional
internal_ports/env_internal_port_keyslet you remap in-container ports (full 1–65535 range, e.g. nginx:80); a collapsed "Advanced settings" panel (gated byshow_advanced_ports) applies them with an image rebuild + health check. Empty by default: no extra.envkeys, no UI, no behaviour change. - Verified actions — install runs a health check; uninstall re-lists the containers to confirm they are gone.
- Install manifest + startup cleanup — finds and offers to remove stale leftovers of older installs.
- Verbose uninstall / cleanup — every step reported with a ✓ / ✗ result.
- Single-instance guard — a PID-based lockfile refuses a second launch with an "already running" notice instead of opening a duplicate window.
- Background update check — checks GitHub Releases (derived from
repo_url) and notes in-window when a newer release exists. Opt-out viaupdate_check_enabled; silent on any network error. - File logging — a rotated
launcher.logplus a per-runinstall.logunder the config dir, and alauncher-debug.logon--debug. Best-effort: an unwritable dir degrades gracefully rather than crashing. - Concurrency-safe UI — every button is disabled for the full duration of an action and the window is held on top, so a second action can't be launched in parallel.
- Quiet on Windows — every Docker subprocess runs with
CREATE_NO_WINDOW, so an install no longer flashes a swarm of console windows (no change on Linux/macOS). - PyInstaller-ready — a bundled spec template, hidden-imports list, and build-time version injection for shipping frozen single-file builds.
- System tray + "Run in background" (optional) —
pip install docker-app-launcher[tray]; while running, the window minimizes to the tray (a visible Run in the background button and the X both use it). When the tray can't dock it falls back to a taskbar-minimized window, so it never silently closes.- Linux note: the reliable tray uses pystray's AppIndicator backend, which needs
gi(PyGObject) plus the AppIndicator typelib. The[tray]extra pip-installs PyGObject (Linux-only; needslibgirepository1.0-dev,libcairo2-dev,pkg-configto build), and you also need the typelib at runtime — on Ubuntu:sudo apt install gir1.2-ayatanaappindicator3-0.1. If you instead rely on the systempython3-gi(apt), create the venv with--system-site-packagessogiis importable. Without any of this the launcher still works — it just minimizes to the taskbar. Run with--debugto see which backend was selected.
- Linux note: the reliable tray uses pystray's AppIndicator backend, which needs
- DE / EN i18n — with per-app custom-string overrides via
custom_strings. - Actions architecture — all business logic is GUI-free and unit-tested without a display.
- CLI ↔ GUI parity — both call the exact same actions layer.
Architecture
| Module | Responsibility |
|---|---|
config.py |
LauncherConfig dataclass — the single source of truth. |
actions.py |
All business logic. No tkinter. Fully testable. |
gui.py |
LauncherApp(tk.Tk) — a thin window over the actions. |
tray.py |
Optional system tray (pystray + Pillow). |
i18n.py |
DE/EN strings with custom-string overrides. |
lockfile.py |
PID-based single-instance guard. |
update_check.py |
Background GitHub Releases update check. |
logging_setup.py |
Rotated file logging (launcher.log / install.log). |
subprocess_utils.py |
Windows CREATE_NO_WINDOW kwargs for all subprocesses. |
pyinstaller/ |
Spec template + helpers for frozen builds. |
__main__.py |
CLI entry point + GUI router. |
Configuration reference
See LauncherConfig for the full field list (app identity, network/health, Docker timeouts, paths, GUI, links, cleanup, tray, i18n, and lifecycle callbacks).
Development
poetry install --with dev --all-extras
make ci # lint + format-check + typecheck + tests
make test # tests with coverage
make fix # auto-fix lint + format
Used by
License
MIT © Asterios Raptis
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docker_app_launcher-0.5.0.tar.gz.
File metadata
- Download URL: docker_app_launcher-0.5.0.tar.gz
- Upload date:
- Size: 44.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acfcbb4f2d394d164963e783ed3d5bfd363881eca7c866f90a97b138da68b9b3
|
|
| MD5 |
2ec16c3a4dd42d0c41330c0ddbd884f9
|
|
| BLAKE2b-256 |
d13567af1e4b47922f5c01a3dfe661807b2de73c882a2c184317fb01af676d8a
|
File details
Details for the file docker_app_launcher-0.5.0-py3-none-any.whl.
File metadata
- Download URL: docker_app_launcher-0.5.0-py3-none-any.whl
- Upload date:
- Size: 48.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b844ce3c0f13624878bf3225a13845f9d36f2fe1c768a732973c754fee4004d
|
|
| MD5 |
1b3a001d661a84cb9db455f00762e806
|
|
| BLAKE2b-256 |
575159e0f12dacd0dca94bc23edbb45d2db26e13566309504d42141dcea49ef1
|