-
-
Notifications
You must be signed in to change notification settings - Fork 289
Add Simple DockSTARTer - Simplified Python alternative #2313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Simple DockSTARTer - Simplified Python alternative #2313
Conversation
Created a radically simplified alternative to DockSTARTer: - Single Python script (321 lines) vs 199 bash scripts (~13,000 lines) - Modern interactive CLI with InquirerPy and Rich - Simple YAML-based app definitions - 16 pre-configured popular apps - Automated installation script - Comprehensive documentation (README + Quick Start) Key improvements: ✓ 97% reduction in code complexity ✓ Python 3 instead of Bash for better maintainability ✓ Beautiful terminal UI with colors and menus ✓ Easy to understand and extend ✓ Focus on core functionality (KISS principle) ✓ Auto-generates docker-compose.yml from app selections Includes apps: - Media servers (Jellyfin, Plex) - Automation (*arr stack: Sonarr, Radarr, Jackett) - Download clients (Transmission) - Management (Portainer, Watchtower) - Networking (Pi-hole, WireGuard, Nginx) - Smart home (Home Assistant) - Cloud (Nextcloud) - Monitoring (Grafana, Tautulli) - Dashboards (Homer) Files: - dockstarter.py: Main application - install.sh: Automated setup script - README.md: Full documentation - QUICKSTART.md: 5-minute getting started guide - requirements.txt: Python dependencies - apps/: 16 app definition files
Reviewer's GuideAdds a new "simple-dockstarter" Python-based subproject providing a single-script, menu-driven Docker management tool plus install script, app definition YAMLs, and documentation, without touching existing DockSTARTer bash code. Sequence diagram for generating and starting containers via Simple DockSTARTersequenceDiagram
actor User
participant SimpleDockSTARTer
participant AppDefinitionFiles
participant ConfigStore
participant DockerComposeArtifacts
participant DockerEngine
User->>SimpleDockSTARTer: start_script()
SimpleDockSTARTer->>DockerEngine: docker --version
DockerEngine-->>SimpleDockSTARTer: version_ok
SimpleDockSTARTer->>ConfigStore: load_config()
ConfigStore-->>SimpleDockSTARTer: config_data
User->>SimpleDockSTARTer: select_apps()
SimpleDockSTARTer->>AppDefinitionFiles: load_available_apps()
AppDefinitionFiles-->>SimpleDockSTARTer: apps_metadata
SimpleDockSTARTer->>User: show_checkbox_menu()
User-->>SimpleDockSTARTer: selected_apps
SimpleDockSTARTer->>ConfigStore: save_config(selected_apps)
User->>SimpleDockSTARTer: configure_settings()
SimpleDockSTARTer->>User: prompt_timezone_and_data_dir()
User-->>SimpleDockSTARTer: timezone_and_data_dir
SimpleDockSTARTer->>ConfigStore: save_config(updated)
User->>SimpleDockSTARTer: generate_docker_compose()
SimpleDockSTARTer->>AppDefinitionFiles: load_available_apps()
AppDefinitionFiles-->>SimpleDockSTARTer: app_definitions
SimpleDockSTARTer->>DockerComposeArtifacts: write docker-compose.yml
SimpleDockSTARTer->>DockerComposeArtifacts: write .env
User->>SimpleDockSTARTer: start_containers()
SimpleDockSTARTer->>DockerEngine: docker compose up -d
DockerEngine-->>SimpleDockSTARTer: containers_running
SimpleDockSTARTer-->>User: success_message
Class diagram for SimpleDockSTARTer core Python scriptclassDiagram
class SimpleDockSTARTer {
+Path base_dir
+Path apps_dir
+Path config_file
+Path docker_compose_file
+Path env_file
+Dict config
+SimpleDockSTARTer()
+Dict load_config()
+save_config()
+Dict load_available_apps()
+select_apps()
+configure_settings()
+generate_docker_compose()
+docker_command(command)
+show_status()
+main_menu()
}
class ConfigStore {
+Path path
+Dict data
}
class AppDefinitionFiles {
+Path directory
+Dict apps
}
class DockerComposeArtifacts {
+Path compose_file
+Path env_file
}
class DockerEngine {
}
SimpleDockSTARTer --> ConfigStore : reads_writes
SimpleDockSTARTer --> AppDefinitionFiles : loads_apps_from
SimpleDockSTARTer --> DockerComposeArtifacts : generates
SimpleDockSTARTer --> DockerEngine : runs_docker_compose
ConfigStore : config.yml
AppDefinitionFiles : apps/*.yml
DockerComposeArtifacts : docker-compose.yml
DockerComposeArtifacts : .env
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- In
SimpleDockSTARTer.load_config, if an existingconfig.ymlis missing newer keys likeuser_id/group_id/timezone/data_diryou’ll getKeyErrorlater (e.g. ingenerate_docker_compose); consider merging the loaded config into a defaults dict so missing keys are always backfilled. - The install script’s test step (
python3 dockstarter.py --help) will actually drop into the interactive menu because--helpisn’t handled, which can block non-interactive installs; either add lightweight argument handling indockstarter.py(e.g. a--version/--helpthat exits immediately) or change the test to something that doesn’t invoke the full TUI. - In
install.sh,pip3 install --user InquirerPy rich PyYAML 2>&1 | grep -i "successfully installed" || truecan hide real installation errors and will not run fromrequirements.txt; it would be more robust to callpip3 install --user -r requirements.txtand avoid piping togrepso failures surface clearly.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `SimpleDockSTARTer.load_config`, if an existing `config.yml` is missing newer keys like `user_id`/`group_id`/`timezone`/`data_dir` you’ll get `KeyError` later (e.g. in `generate_docker_compose`); consider merging the loaded config into a defaults dict so missing keys are always backfilled.
- The install script’s test step (`python3 dockstarter.py --help`) will actually drop into the interactive menu because `--help` isn’t handled, which can block non-interactive installs; either add lightweight argument handling in `dockstarter.py` (e.g. a `--version/--help` that exits immediately) or change the test to something that doesn’t invoke the full TUI.
- In `install.sh`, `pip3 install --user InquirerPy rich PyYAML 2>&1 | grep -i "successfully installed" || true` can hide real installation errors and will not run from `requirements.txt`; it would be more robust to call `pip3 install --user -r requirements.txt` and avoid piping to `grep` so failures surface clearly.
## Individual Comments
### Comment 1
<location> `simple-dockstarter/install.sh:101` </location>
<code_context>
+echo -e "${CYAN}[4/5]${NC} Testing installation..."
+
+# Test if script can run
+if python3 dockstarter.py --help &> /dev/null || true; then
+ echo -e "${GREEN}✓${NC} Script is working"
+else
</code_context>
<issue_to_address>
**issue (bug_risk):** The `|| true` makes this check always succeed, so the conditional no longer tests the script correctly.
With `... --help &> /dev/null || true`, the `if` condition always sees exit code 0, so the success branch runs even if `python3 dockstarter.py` fails. To let the condition actually reflect whether the script runs, drop the `|| true`:
```bash
if python3 dockstarter.py --help &> /dev/null; then
echo -e "${GREEN}✓${NC} Script is working"
else
echo -e "${YELLOW}⚠${NC} Script test completed (--help not implemented, this is normal)"
fi
```
</issue_to_address>
### Comment 2
<location> `simple-dockstarter/install.sh:46` </location>
<code_context>
+```bash
+# Docker installieren (Ubuntu/Debian)
+curl -fsSL https://get.docker.com | sh
+sudo usermod -aG docker $USER
+# Neu einloggen erforderlich!
+```
</code_context>
<issue_to_address>
**nitpick (bug_risk):** User variable should be quoted to avoid issues with unusual usernames.
To handle usernames with spaces or shell‑special characters safely, quote the variable:
```bash
sudo usermod -aG docker "$USER"
```
</issue_to_address>
### Comment 3
<location> `simple-dockstarter/apps/pihole.yml:10-12` </location>
<code_context>
+ - "8080:80"
+volumes:
+ - "${DATA_DIR}/meine-app:/config"
+environment:
+ - PUID=${PUID}
+ - PGID=${PGID}
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Bundling hardcoded weak default passwords in app definitions can lead to insecure default deployments.
Several app definitions (for example, Pi-hole `WEBPASSWORD=admin`, Grafana `GF_SECURITY_ADMIN_PASSWORD=admin`) currently use real, weak default credentials. This makes it too easy to deploy them insecurely if exposed on a LAN or the internet.
Prefer placeholder values like `CHANGE_ME` or omit the password variables so users must set them explicitly (e.g., via a prompt in the Python script or documented environment overrides). This helps prevent long‑term use of insecure defaults.
</issue_to_address>
### Comment 4
<location> `simple-dockstarter/README.md:17` </location>
<code_context>
+| Zeilen Code | ~13.000 | ~400 |
+| Sprache | Bash | Python 3 |
+| Themes | 12 Themes | Modernes UI |
+| Multi-Instance | Ja | Nein (KISS Prinzip) |
+| Komplexität | Sehr hoch | Sehr niedrig |
+| Wartbarkeit | Schwierig | Einfach |
</code_context>
<issue_to_address>
**nitpick (typo):** „KISS-Prinzip“ im Deutschen üblicherweise mit Bindestrich schreiben
Bitte `KISS Prinzip` in `KISS-Prinzip` ändern, um die deutsche Schreibweise zu korrigieren und zu vereinheitlichen.
```suggestion
| Multi-Instance | Ja | Nein (KISS-Prinzip) |
```
</issue_to_address>
### Comment 5
<location> `simple-dockstarter/QUICKSTART.md:83` </location>
<code_context>
+| Grafana | http://localhost:3000 | 3000 |
+| Nextcloud | http://localhost:8081 | 8081 |
+
+**Tipp:** Ersetze `localhost` mit deiner Server-IP wenn du von einem anderen Gerät zugreifst.
+
+## 4️⃣ Häufige Befehle
</code_context>
<issue_to_address>
**suggestion (typo):** Präposition und Kommasetzung in deutschem Satz leicht anpassen
Vorschlag: „Ersetze `localhost` durch deine Server-IP, wenn du von einem anderen Gerät zugreifst.“
```suggestion
**Tipp:** Ersetze `localhost` durch deine Server-IP, wenn du von einem anderen Gerät zugreifst.
```
</issue_to_address>
### Comment 6
<location> `simple-dockstarter/QUICKSTART.md:173` </location>
<code_context>
+docker compose up -d
+```
+
+### Permissions Fehler
+```bash
+# Prüfe PUID/PGID
</code_context>
<issue_to_address>
**nitpick (typo):** „Permissions Fehler“ als Zusammensetzung mit Bindestrich schreiben
Nutze hier z.B. „Permissions-Fehler“ oder konsequent deutsch „Berechtigungsfehler“.
```suggestion
### Berechtigungsfehler
```
</issue_to_address>
### Comment 7
<location> `simple-dockstarter/dockstarter.py:204` </location>
<code_context>
def generate_docker_compose(self):
"""Generate docker-compose.yml from selected apps"""
if not self.config.get('selected_apps'):
console.print("[red]No apps selected! Please select apps first.[/red]")
return
apps = self.load_available_apps()
compose = {
'version': '3.8',
'services': {}
}
# Generate .env file
env_vars = [
f"PUID={self.config['user_id']}",
f"PGID={self.config['group_id']}",
f"TZ={self.config['timezone']}",
f"DATA_DIR={self.config['data_dir']}"
]
for app_name in self.config['selected_apps']:
if app_name not in apps:
console.print(f"[yellow]Warning: {app_name} definition not found[/yellow]")
continue
app = apps[app_name]
service = {
'container_name': app_name,
'image': app['image'],
'restart': app.get('restart', 'unless-stopped')
}
# Add environment variables
if 'environment' in app:
service['environment'] = app['environment']
# Add volumes
if 'volumes' in app:
service['volumes'] = [
vol.replace('${DATA_DIR}', self.config['data_dir'])
for vol in app['volumes']
]
# Add ports
if 'ports' in app:
service['ports'] = app['ports']
# Add networks
if 'networks' in app:
service['networks'] = app['networks']
# Add depends_on
if 'depends_on' in app:
service['depends_on'] = app['depends_on']
# Add custom options
for key in ['devices', 'privileged', 'labels', 'cap_add']:
if key in app:
service[key] = app[key]
compose['services'][app_name] = service
# Add app-specific env vars
if 'env_vars' in app:
env_vars.extend(app['env_vars'])
# Write docker-compose.yml
with open(self.docker_compose_file, 'w') as f:
yaml.dump(compose, f, default_flow_style=False, sort_keys=False)
# Write .env file
with open(self.env_file, 'w') as f:
f.write('\n'.join(env_vars) + '\n')
console.print(f"[green]✓[/green] Generated docker-compose.yml with {len(compose['services'])} service(s)")
console.print(f"[green]✓[/green] Generated .env file")
</code_context>
<issue_to_address>
**suggestion (code-quality):** Replace f-string with no interpolated values with string ([`remove-redundant-fstring`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/remove-redundant-fstring/))
```suggestion
console.print("[green]✓[/green] Generated .env file")
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| echo -e "${CYAN}[4/5]${NC} Testing installation..." | ||
|
|
||
| # Test if script can run | ||
| if python3 dockstarter.py --help &> /dev/null || true; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): The || true makes this check always succeed, so the conditional no longer tests the script correctly.
With ... --help &> /dev/null || true, the if condition always sees exit code 0, so the success branch runs even if python3 dockstarter.py fails. To let the condition actually reflect whether the script runs, drop the || true:
if python3 dockstarter.py --help &> /dev/null; then
echo -e "${GREEN}✓${NC} Script is working"
else
echo -e "${YELLOW}⚠${NC} Script test completed (--help not implemented, this is normal)"
fi| environment: | ||
| - TZ=${TZ} | ||
| - WEBPASSWORD=admin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚨 suggestion (security): Bundling hardcoded weak default passwords in app definitions can lead to insecure default deployments.
Several app definitions (for example, Pi-hole WEBPASSWORD=admin, Grafana GF_SECURITY_ADMIN_PASSWORD=admin) currently use real, weak default credentials. This makes it too easy to deploy them insecurely if exposed on a LAN or the internet.
Prefer placeholder values like CHANGE_ME or omit the password variables so users must set them explicitly (e.g., via a prompt in the Python script or documented environment overrides). This helps prevent long‑term use of insecure defaults.
| | Zeilen Code | ~13.000 | ~400 | | ||
| | Sprache | Bash | Python 3 | | ||
| | Themes | 12 Themes | Modernes UI | | ||
| | Multi-Instance | Ja | Nein (KISS Prinzip) | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick (typo): „KISS-Prinzip“ im Deutschen üblicherweise mit Bindestrich schreiben
Bitte KISS Prinzip in KISS-Prinzip ändern, um die deutsche Schreibweise zu korrigieren und zu vereinheitlichen.
| | Multi-Instance | Ja | Nein (KISS Prinzip) | | |
| | Multi-Instance | Ja | Nein (KISS-Prinzip) | |
| | Grafana | http://localhost:3000 | 3000 | | ||
| | Nextcloud | http://localhost:8081 | 8081 | | ||
|
|
||
| **Tipp:** Ersetze `localhost` mit deiner Server-IP wenn du von einem anderen Gerät zugreifst. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (typo): Präposition und Kommasetzung in deutschem Satz leicht anpassen
Vorschlag: „Ersetze localhost durch deine Server-IP, wenn du von einem anderen Gerät zugreifst.“
| **Tipp:** Ersetze `localhost` mit deiner Server-IP wenn du von einem anderen Gerät zugreifst. | |
| **Tipp:** Ersetze `localhost` durch deine Server-IP, wenn du von einem anderen Gerät zugreifst. |
| docker compose up -d | ||
| ``` | ||
|
|
||
| ### Permissions Fehler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick (typo): „Permissions Fehler“ als Zusammensetzung mit Bindestrich schreiben
Nutze hier z.B. „Permissions-Fehler“ oder konsequent deutsch „Berechtigungsfehler“.
| ### Permissions Fehler | |
| ### Berechtigungsfehler |
| f.write('\n'.join(env_vars) + '\n') | ||
|
|
||
| console.print(f"[green]✓[/green] Generated docker-compose.yml with {len(compose['services'])} service(s)") | ||
| console.print(f"[green]✓[/green] Generated .env file") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Replace f-string with no interpolated values with string (remove-redundant-fstring)
| console.print(f"[green]✓[/green] Generated .env file") | |
| console.print("[green]✓[/green] Generated .env file") |
|
This is a neat idea. I haven't looked at the code. I think it would make more sense as a separate repo rather than included in the main repo. FYI I do not know python, but it's a quite popular language so I'm sure there would be others able to contribute. If you would be interested in maintaining and supporting this in a separate repo I'd be happy to set one up under the org and invite you with full access and link to the project from this repo once you feel it's ready. Of course you're also welcome to do this without it being part of the org. |
Improved documentation to make it clearer for users: - Updated README.md with local installation instructions - Simplified QUICKSTART.md with step-by-step guidance - Added START.md for absolute beginners Changes: - Removed confusing git clone instructions (files already exist locally) - Added detailed installation walkthrough - Created beginner-friendly START.md guide - Clarified that install.sh automates everything - Made it clear this is for local use only All documentation now assumes user already has the files and focuses on simple, clear instructions for getting started.
Added comprehensive download/distribution documentation: - Created DOWNLOAD.md with all distribution options - Updated README.md, QUICKSTART.md, START.md with download section - Clarified that Simple DockSTARTer is standalone/not in official repo - Removed incorrect links to official repo - Added options for: TAR/ZIP creation, GitHub publishing, direct sharing Key clarifications: - Simple DockSTARTer is independent from official DockSTARTer - Not yet published in official repository - Can be distributed as standalone package - Works independently with just Python + Docker Distribution methods documented: 1. TAR/ZIP archive for sharing 2. Creating own GitHub repository 3. Direct folder copying 4. Checking if files already exist locally Makes it clear for users how to obtain and share Simple DockSTARTer.
Transformed Simple DockSTARTer into a fully independent project: Changes to all documentation: - Removed all references to official DockSTARTer repository - Made all paths flexible and location-independent - Emphasized standalone nature throughout - Updated download/distribution instructions DOWNLOAD.md: - Complete rewrite for standalone distribution - Added multiple distribution methods (TAR, GitHub, server hosting) - Security best practices for distribution - Version management guidance - Step-by-step release process README.md: - Removed comparison with "Original DockSTARTer" - Changed to generic "complex Docker tools" comparison - Updated credits section (inspiration vs dependency) - Made paths flexible (not hardcoded to specific location) - Added MIT license text - Emphasized KISS principle and design philosophy START.md & QUICKSTART.md: - Removed hardcoded paths (~/DockSTARTer/simple-dockstarter/) - Added examples of different possible locations - Made instructions path-agnostic - Clarified standalone nature upfront Key message: Simple DockSTARTer is now presented as a completely independent project that happens to be inspired by DockSTARTer, not as a variant or modification of it. It's its own thing. Ready for independent distribution via GitHub, ZIP, or any method.
Added README-STANDALONE.md to clearly explain: - Simple DockSTARTer is a separate, independent project - How to move it to a standalone location - Differences between Original DockSTARTer and Simple DockSTARTer - Instructions for creating independent packages - No confusion between the two projects Provides clear guidance for users to extract Simple DockSTARTer from the DockSTARTer repository and use it independently.
Created a radically simplified alternative to DockSTARTer:
Key improvements:
✓ 97% reduction in code complexity
✓ Python 3 instead of Bash for better maintainability ✓ Beautiful terminal UI with colors and menus
✓ Easy to understand and extend
✓ Focus on core functionality (KISS principle)
✓ Auto-generates docker-compose.yml from app selections
Includes apps:
Files:
Pull request
Purpose
Describe the problem or feature in addition to a link to the issues.
Approach
How does this change address the problem?
Open Questions and Pre-Merge TODOs
Check all boxes as they are completed
Learning
Describe the research stage
Links to blog posts, patterns, libraries or addons used to solve this problem
Requirements
Check all boxes as they are completed
Summary by Sourcery
Add a new Simple DockSTARTer subproject providing a lightweight, Python-based alternative to the existing DockSTARTer for managing Dockerized home-server apps.
New Features:
Enhancements:
Documentation: