Files
setec_cdm/setec-web/docker_store.py
DigiJ 9e839ee826 Initial commit — SETEC LABS Manager (Setec_CDM)
Flask-based VPS management panel with SSH remote command execution.
Includes E2E encrypted SSH tunnel (AES-256-GCM + Go agent), setup wizard,
security hardening tools, DNS management, firewall configs, monitoring,
backup, and .sec patch update system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 12:39:02 -07:00

710 lines
21 KiB
Python

# Docker app store - popular self-hosted apps with one-click install
# Each entry has the docker-compose snippet needed to deploy it
STORE = [
# ── Web / Proxy ──
{
"name": "Nginx Proxy Manager",
"desc": "Web UI for managing Nginx reverse proxies with SSL",
"cat": "Web / Proxy",
"image": "jc21/nginx-proxy-manager:latest",
"ports": {"81": "Admin UI", "80": "HTTP", "443": "HTTPS"},
"ui_port": 81,
"compose": """ nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: always
ports:
- "81:81"
- "8880:80"
- "8443:443"
volumes:
- /opt/seteclabs/npm/data:/data
- /opt/seteclabs/npm/letsencrypt:/etc/letsencrypt""",
"notes": "Default login: admin@example.com / changeme",
},
{
"name": "Traefik",
"desc": "Cloud-native reverse proxy and load balancer",
"cat": "Web / Proxy",
"image": "traefik:latest",
"ports": {"8080": "Dashboard"},
"ui_port": 8080,
"compose": """ traefik:
image: traefik:latest
container_name: traefik
restart: always
command:
- "--api.dashboard=true"
- "--api.insecure=true"
- "--providers.docker=true"
ports:
- "8880:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro""",
"notes": "Dashboard at :8080, configure via labels on other containers",
},
# ── Monitoring ──
{
"name": "Uptime Kuma",
"desc": "Self-hosted uptime monitoring with beautiful status pages",
"cat": "Monitoring",
"image": "louislam/uptime-kuma:latest",
"ports": {"3001": "Web UI"},
"ui_port": 3001,
"compose": """ uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
restart: always
ports:
- "3001:3001"
volumes:
- /opt/seteclabs/uptime-kuma:/app/data""",
"notes": "Monitor websites, APIs, DNS, and more. Create public status pages.",
},
{
"name": "Grafana",
"desc": "Dashboards and visualization for metrics",
"cat": "Monitoring",
"image": "grafana/grafana:latest",
"ports": {"3002": "Web UI"},
"ui_port": 3002,
"compose": """ grafana:
image: grafana/grafana:latest
container_name: grafana
restart: always
ports:
- "3002:3000"
volumes:
- /opt/seteclabs/grafana:/var/lib/grafana""",
"notes": "Default login: admin / admin",
},
{
"name": "Prometheus",
"desc": "Metrics collection and alerting",
"cat": "Monitoring",
"image": "prom/prometheus:latest",
"ports": {"9090": "Web UI"},
"ui_port": 9090,
"compose": """ prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: always
ports:
- "9090:9090"
volumes:
- /opt/seteclabs/prometheus:/prometheus
- /opt/seteclabs/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml""",
"notes": "Create prometheus.yml config before starting",
},
{
"name": "Netdata",
"desc": "Real-time server performance monitoring",
"cat": "Monitoring",
"image": "netdata/netdata:latest",
"ports": {"19999": "Web UI"},
"ui_port": 19999,
"compose": """ netdata:
image: netdata/netdata:latest
container_name: netdata
restart: always
ports:
- "19999:19999"
cap_add:
- SYS_PTRACE
security_opt:
- apparmor:unconfined
volumes:
- /etc/passwd:/host/etc/passwd:ro
- /etc/group:/host/etc/group:ro
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /var/run/docker.sock:/var/run/docker.sock:ro""",
"notes": "Full system metrics, zero config needed",
},
# ── Containers ──
{
"name": "Portainer",
"desc": "Docker management web UI",
"cat": "Containers",
"image": "portainer/portainer-ce:latest",
"ports": {"9443": "Web UI (HTTPS)", "9000": "Web UI (HTTP)"},
"ui_port": 9000,
"compose": """ portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
ports:
- "9443:9443"
- "9002:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/seteclabs/portainer:/data""",
"notes": "Docker management UI. Set admin password on first visit.",
},
{
"name": "Dockge",
"desc": "Compose stack manager with live editing",
"cat": "Containers",
"image": "louislam/dockge:latest",
"ports": {"5001": "Web UI"},
"ui_port": 5001,
"compose": """ dockge:
image: louislam/dockge:latest
container_name: dockge
restart: always
ports:
- "5001:5001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/seteclabs/dockge:/app/data
- /opt/seteclabs:/opt/seteclabs""",
"notes": "Manage docker compose stacks from a web UI",
},
# ── Cloud / Files ──
{
"name": "Nextcloud",
"desc": "Self-hosted cloud storage (Google Drive/Dropbox alternative)",
"cat": "Cloud / Files",
"image": "nextcloud:latest",
"ports": {"8081": "Web UI"},
"ui_port": 8081,
"compose": """ nextcloud:
image: nextcloud:latest
container_name: nextcloud
restart: always
ports:
- "8081:80"
volumes:
- /opt/seteclabs/nextcloud:/var/www/html""",
"notes": "File sync, calendar, contacts, office docs",
},
{
"name": "FileBrowser",
"desc": "Web-based file manager",
"cat": "Cloud / Files",
"image": "filebrowser/filebrowser:latest",
"ports": {"8082": "Web UI"},
"ui_port": 8082,
"compose": """ filebrowser:
image: filebrowser/filebrowser:latest
container_name: filebrowser
restart: always
ports:
- "8082:80"
volumes:
- /var/www:/srv
- /opt/seteclabs/filebrowser/db:/database""",
"notes": "Default login: admin / admin. Browses /var/www by default.",
},
{
"name": "MinIO",
"desc": "S3-compatible object storage",
"cat": "Cloud / Files",
"image": "minio/minio:latest",
"ports": {"9010": "API", "9011": "Console"},
"ui_port": 9011,
"compose": """ minio:
image: minio/minio:latest
container_name: minio
restart: always
command: server /data --console-address ":9001"
ports:
- "9010:9000"
- "9011:9001"
environment:
- MINIO_ROOT_USER=admin
- MINIO_ROOT_PASSWORD=setecminio2026
volumes:
- /opt/seteclabs/minio:/data""",
"notes": "S3-compatible storage. Console at :9011",
},
{
"name": "Syncthing",
"desc": "Continuous file synchronization between devices",
"cat": "Cloud / Files",
"image": "syncthing/syncthing:latest",
"ports": {"8384": "Web UI"},
"ui_port": 8384,
"compose": """ syncthing:
image: syncthing/syncthing:latest
container_name: syncthing
restart: always
ports:
- "8384:8384"
- "22000:22000/tcp"
- "22000:22000/udp"
volumes:
- /opt/seteclabs/syncthing:/var/syncthing""",
"notes": "Peer-to-peer file sync, no cloud needed",
},
# ── Security ──
{
"name": "Vaultwarden",
"desc": "Bitwarden-compatible password manager",
"cat": "Security",
"image": "vaultwarden/server:latest",
"ports": {"8083": "Web UI"},
"ui_port": 8083,
"compose": """ vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
ports:
- "8083:80"
environment:
- SIGNUPS_ALLOWED=false
- ADMIN_TOKEN=setecVault2026adminToken
volumes:
- /opt/seteclabs/vaultwarden:/data""",
"notes": "Use with Bitwarden browser extension. Admin panel at /admin",
},
{
"name": "CrowdSec",
"desc": "Collaborative security engine (fail2ban alternative)",
"cat": "Security",
"image": "crowdsecurity/crowdsec:latest",
"ports": {"8084": "API"},
"ui_port": 8084,
"compose": """ crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
restart: always
ports:
- "8084:8080"
volumes:
- /opt/seteclabs/crowdsec/config:/etc/crowdsec
- /opt/seteclabs/crowdsec/data:/var/lib/crowdsec/data
- /var/log:/var/log:ro""",
"notes": "Community-driven IP reputation and threat detection",
},
# ── Communication ──
{
"name": "Gotify",
"desc": "Self-hosted push notification server",
"cat": "Communication",
"image": "gotify/server:latest",
"ports": {"8085": "Web UI"},
"ui_port": 8085,
"compose": """ gotify:
image: gotify/server:latest
container_name: gotify
restart: always
ports:
- "8085:80"
volumes:
- /opt/seteclabs/gotify:/app/data""",
"notes": "Default login: admin / admin",
},
{
"name": "ntfy",
"desc": "Simple pub-sub push notifications via HTTP",
"cat": "Communication",
"image": "binwiederhier/ntfy:latest",
"ports": {"8086": "Web UI"},
"ui_port": 8086,
"compose": """ ntfy:
image: binwiederhier/ntfy:latest
container_name: ntfy
restart: always
command: serve
ports:
- "8086:80"
volumes:
- /opt/seteclabs/ntfy/cache:/var/cache/ntfy
- /opt/seteclabs/ntfy/etc:/etc/ntfy""",
"notes": "Send notifications via curl: curl -d 'message' http://host:8086/topic",
},
{
"name": "Element Web",
"desc": "Matrix chat client (Slack/Discord alternative)",
"cat": "Communication",
"image": "vectorim/element-web:latest",
"ports": {"8087": "Web UI"},
"ui_port": 8087,
"compose": """ element:
image: vectorim/element-web:latest
container_name: element
restart: always
ports:
- "8087:80" """,
"notes": "Needs a Matrix homeserver (Synapse/Dendrite) to connect to",
},
# ── Analytics ──
{
"name": "Plausible",
"desc": "Privacy-friendly web analytics (Google Analytics alternative)",
"cat": "Analytics",
"image": "plausible/analytics:latest",
"ports": {"8088": "Web UI"},
"ui_port": 8088,
"compose": """ plausible:
image: plausible/analytics:latest
container_name: plausible
restart: always
ports:
- "8088:8000"
environment:
- BASE_URL=http://localhost:8088
- SECRET_KEY_BASE=setecPlaus2026secretKeyBase1234567890abcdef
- DATABASE_URL=postgres://plausible:plausible@plausible-db/plausible
- CLICKHOUSE_DATABASE_URL=http://plausible-events-db:8123/plausible_events_db
depends_on:
- plausible-db
- plausible-events-db
plausible-db:
image: postgres:16-alpine
container_name: plausible-db
restart: always
environment:
- POSTGRES_USER=plausible
- POSTGRES_PASSWORD=plausible
- POSTGRES_DB=plausible
volumes:
- /opt/seteclabs/plausible/pgdata:/var/lib/postgresql/data
plausible-events-db:
image: clickhouse/clickhouse-server:latest
container_name: plausible-events-db
restart: always
volumes:
- /opt/seteclabs/plausible/clickhouse:/var/lib/clickhouse""",
"notes": "Lightweight, no cookies, GDPR-compliant analytics",
},
{
"name": "Umami",
"desc": "Simple privacy-focused web analytics",
"cat": "Analytics",
"image": "ghcr.io/umami-software/umami:postgresql-latest",
"ports": {"8089": "Web UI"},
"ui_port": 8089,
"compose": """ umami:
image: ghcr.io/umami-software/umami:postgresql-latest
container_name: umami
restart: always
ports:
- "8089:3000"
environment:
- DATABASE_URL=postgresql://umami:umami@umami-db:5432/umami
depends_on:
- umami-db
umami-db:
image: postgres:16-alpine
container_name: umami-db
restart: always
environment:
- POSTGRES_USER=umami
- POSTGRES_PASSWORD=umami
- POSTGRES_DB=umami
volumes:
- /opt/seteclabs/umami/pgdata:/var/lib/postgresql/data""",
"notes": "Default login: admin / umami",
},
# ── Wikis / Knowledge ──
{
"name": "Wiki.js",
"desc": "Modern wiki with markdown, visual editor, and Git sync",
"cat": "Wikis",
"image": "ghcr.io/requarks/wiki:2",
"ports": {"3003": "Web UI"},
"ui_port": 3003,
"compose": """ wikijs:
image: ghcr.io/requarks/wiki:2
container_name: wikijs
restart: always
ports:
- "3003:3000"
environment:
- DB_TYPE=sqlite
- DB_FILEPATH=/data/wiki.sqlite
volumes:
- /opt/seteclabs/wikijs:/data""",
"notes": "Setup wizard on first launch",
},
{
"name": "BookStack",
"desc": "Documentation platform with books/chapters/pages",
"cat": "Wikis",
"image": "lscr.io/linuxserver/bookstack:latest",
"ports": {"6875": "Web UI"},
"ui_port": 6875,
"compose": """ bookstack:
image: lscr.io/linuxserver/bookstack:latest
container_name: bookstack
restart: always
ports:
- "6875:80"
environment:
- PUID=1000
- PGID=1000
- APP_URL=http://localhost:6875
- DB_HOST=bookstack-db
- DB_PORT=3306
- DB_USER=bookstack
- DB_PASS=bookstack
- DB_DATABASE=bookstackapp
depends_on:
- bookstack-db
bookstack-db:
image: mariadb:10
container_name: bookstack-db
restart: always
environment:
- MYSQL_ROOT_PASSWORD=bookstack
- MYSQL_DATABASE=bookstackapp
- MYSQL_USER=bookstack
- MYSQL_PASSWORD=bookstack
volumes:
- /opt/seteclabs/bookstack/db:/var/lib/mysql""",
"notes": "Default login: admin@admin.com / password",
},
# ── Automation ──
{
"name": "n8n",
"desc": "Workflow automation (Zapier/IFTTT alternative)",
"cat": "Automation",
"image": "n8nio/n8n:latest",
"ports": {"5678": "Web UI"},
"ui_port": 5678,
"compose": """ n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: always
ports:
- "5678:5678"
volumes:
- /opt/seteclabs/n8n:/home/node/.n8n""",
"notes": "Visual workflow builder with 200+ integrations",
},
{
"name": "Node-RED",
"desc": "Flow-based programming for IoT and automation",
"cat": "Automation",
"image": "nodered/node-red:latest",
"ports": {"1880": "Web UI"},
"ui_port": 1880,
"compose": """ nodered:
image: nodered/node-red:latest
container_name: nodered
restart: always
ports:
- "1880:1880"
volumes:
- /opt/seteclabs/nodered:/data""",
"notes": "Drag-and-drop flow editor",
},
# ── Pastebins / Tools ──
{
"name": "PrivateBin",
"desc": "Encrypted pastebin (zero-knowledge)",
"cat": "Tools",
"image": "privatebin/nginx-fpm-alpine:latest",
"ports": {"8090": "Web UI"},
"ui_port": 8090,
"compose": """ privatebin:
image: privatebin/nginx-fpm-alpine:latest
container_name: privatebin
restart: always
ports:
- "8090:8080"
volumes:
- /opt/seteclabs/privatebin:/srv/data""",
"notes": "Encrypted pastes, server never sees plaintext",
},
{
"name": "IT-Tools",
"desc": "Collection of handy developer tools (encoders, converters, etc)",
"cat": "Tools",
"image": "corentinth/it-tools:latest",
"ports": {"8091": "Web UI"},
"ui_port": 8091,
"compose": """ it-tools:
image: corentinth/it-tools:latest
container_name: it-tools
restart: always
ports:
- "8091:80" """,
"notes": "Hash generators, encoders, UUID, JWT decoder, network tools, etc",
},
{
"name": "CyberChef",
"desc": "Data encoding/decoding/analysis swiss army knife",
"cat": "Tools",
"image": "ghcr.io/gchq/cyberchef:latest",
"ports": {"8092": "Web UI"},
"ui_port": 8092,
"compose": """ cyberchef:
image: ghcr.io/gchq/cyberchef:latest
container_name: cyberchef
restart: always
ports:
- "8092:80" """,
"notes": "GCHQ's data transformation tool",
},
{
"name": "Stirling-PDF",
"desc": "PDF manipulation tools (merge, split, convert, OCR)",
"cat": "Tools",
"image": "frooodle/s-pdf:latest",
"ports": {"8093": "Web UI"},
"ui_port": 8093,
"compose": """ stirling-pdf:
image: frooodle/s-pdf:latest
container_name: stirling-pdf
restart: always
ports:
- "8093:8080"
volumes:
- /opt/seteclabs/stirling-pdf:/usr/share/tessdata""",
"notes": "All-in-one PDF toolkit",
},
# ── Media ──
{
"name": "Jellyfin",
"desc": "Media server (Plex alternative, fully open source)",
"cat": "Media",
"image": "jellyfin/jellyfin:latest",
"ports": {"8096": "Web UI"},
"ui_port": 8096,
"compose": """ jellyfin:
image: jellyfin/jellyfin:latest
container_name: jellyfin
restart: always
ports:
- "8096:8096"
volumes:
- /opt/seteclabs/jellyfin/config:/config
- /opt/seteclabs/jellyfin/cache:/cache
- /opt/seteclabs/media:/media""",
"notes": "Stream movies, TV, music. Setup wizard on first launch.",
},
# ── CI/CD ──
{
"name": "Woodpecker CI",
"desc": "Lightweight CI/CD engine (Drone fork)",
"cat": "CI/CD",
"image": "woodpeckerci/woodpecker-server:latest",
"ports": {"8000": "Web UI"},
"ui_port": 8000,
"compose": """ woodpecker:
image: woodpeckerci/woodpecker-server:latest
container_name: woodpecker
restart: always
ports:
- "8000:8000"
environment:
- WOODPECKER_HOST=http://localhost:8000
- WOODPECKER_OPEN=true
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://repo.seteclabs.io
volumes:
- /opt/seteclabs/woodpecker:/data""",
"notes": "Integrates with Gitea. Needs OAuth app setup in Gitea.",
},
{
"name": "Drone",
"desc": "Container-native CI/CD platform",
"cat": "CI/CD",
"image": "drone/drone:latest",
"ports": {"8001": "Web UI"},
"ui_port": 8001,
"compose": """ drone:
image: drone/drone:latest
container_name: drone
restart: always
ports:
- "8001:80"
environment:
- DRONE_GITEA_SERVER=https://repo.seteclabs.io
- DRONE_SERVER_HOST=localhost:8001
- DRONE_SERVER_PROTO=http
volumes:
- /opt/seteclabs/drone:/data""",
"notes": "Needs Gitea OAuth app for authentication",
},
# ── Dashboards ──
{
"name": "Homer",
"desc": "Simple static homepage / application dashboard",
"cat": "Dashboards",
"image": "b4bz/homer:latest",
"ports": {"8094": "Web UI"},
"ui_port": 8094,
"compose": """ homer:
image: b4bz/homer:latest
container_name: homer
restart: always
ports:
- "8094:8080"
volumes:
- /opt/seteclabs/homer:/www/assets""",
"notes": "Edit config.yml in the volume to add your services",
},
{
"name": "Homarr",
"desc": "Modern dashboard with Docker integration",
"cat": "Dashboards",
"image": "ghcr.io/ajnart/homarr:latest",
"ports": {"7575": "Web UI"},
"ui_port": 7575,
"compose": """ homarr:
image: ghcr.io/ajnart/homarr:latest
container_name: homarr
restart: always
ports:
- "7575:7575"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /opt/seteclabs/homarr/configs:/app/data/configs
- /opt/seteclabs/homarr/icons:/app/public/icons""",
"notes": "Auto-discovers Docker containers",
},
# ── VPN ──
{
"name": "wg-easy",
"desc": "WireGuard VPN with web UI",
"cat": "VPN",
"image": "ghcr.io/wg-easy/wg-easy:latest",
"ports": {"51821": "Web UI", "51820": "WireGuard"},
"ui_port": 51821,
"compose": """ wg-easy:
image: ghcr.io/wg-easy/wg-easy:latest
container_name: wg-easy
restart: always
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
environment:
- WG_HOST=31.220.20.55
- PASSWORD=setecWG2026
volumes:
- /opt/seteclabs/wg-easy:/etc/wireguard""",
"notes": "Easy WireGuard management. Open UDP 51820 in firewall.",
},
]
CATEGORIES = sorted(set(app["cat"] for app in STORE))