diff --git a/README.md b/README.md index 737a19a2f..fa2d35409 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ A [Large Language Model (LLM)](https://en.wikipedia.org/wiki/Large_language_mode - [Ollama + Open WebUI](examples/ollama-ui) - Get up and running with Llama 3, Mistral, Gemma, and other large language models using Ollama. Using an interactive, user-friendly WebUI via Open WebUI (formerly known as Ollama WebUI). - [Serge](examples/serge) - A web interface for chatting with Alpaca through llama.cpp. Fully dockerized, with an easy to use API. +- [LynxPrompt](examples/lynxprompt) - Self-hosted platform for managing and sharing AI IDE configuration files (AGENTS.md, CLAUDE.md) with a web UI, CLI, and federation support. ### Virtual Private Network (VPN) & Remote Access @@ -200,6 +201,7 @@ Tools and software for [software project management](https://en.wikipedia.org/wi - [Unify Network Application](examples/unify-network-application) - The Unifi-network-application software is a powerful, enterprise wireless software engine ideal for high-density client deployments requiring low latency and high uptime performance. - [UpSnap](examples/upsnap) - A simple wake on lan app written with SvelteKit, Go, PocketBase and nmap. - [Beszel](examples/beszel) - Lightweight server monitoring platform with Docker statistics, historical data, and alerts. +- [GenieACS](examples/genieacs) - Open-source TR-069 remote management platform for ISP customer-premises equipment (routers, ONTs, set-top boxes). ### Recipe Management @@ -256,6 +258,7 @@ Digital [archiving](https://en.wikipedia.org/wiki/Archival_science) and [preserv - [Shiori](examples/shiori) - Simple bookmark manager and website archiver built with Go. - [Readeck](examples/readeck) - Readeck is a simple web application that lets you save the precious readable content of web pages you like and want to keep forever. - [Linkwarden](examples/linkwarden) - Self-hosted collaborative bookmark manager to collect, organize, and preserve webpages, articles, and documents. +- [Telegram Archive](examples/telegram-archive) - Own your Telegram history with automated, incremental backups and a local web viewer that mirrors the Telegram UI. ### Document Management diff --git a/examples/genieacs/README.md b/examples/genieacs/README.md new file mode 100644 index 000000000..0d8e10314 --- /dev/null +++ b/examples/genieacs/README.md @@ -0,0 +1,9 @@ +# References + +- https://github.com/GeiserX/genieacs-container +- https://hub.docker.com/r/drumsergio/genieacs +- https://genieacs.com + +# Notes + +GenieACS is an open-source TR-069 remote management platform for ISP customer-premises equipment (routers, ONTs, set-top boxes). The web UI is available on port 3000. CWMP (port 7547) is where devices connect. diff --git a/examples/genieacs/docker-compose.yml b/examples/genieacs/docker-compose.yml new file mode 100644 index 000000000..4863b0301 --- /dev/null +++ b/examples/genieacs/docker-compose.yml @@ -0,0 +1,60 @@ +services: + + genieacs: + image: drumsergio/genieacs:1.2.16.6 + container_name: genieacs + restart: unless-stopped + depends_on: + mongo: + condition: service_healthy + ports: + - 7547:7547 + - 7557:7557 + - 7567:7567 + - 3000:3000 + expose: + - 3000 + volumes: + - ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/genieacs/ext:/opt/genieacs/ext + environment: + GENIEACS_UI_JWT_SECRET: ${GENIEACS_UI_JWT_SECRET:-ChangeMe1234} + GENIEACS_MONGODB_CONNECTION_URL: mongodb://mongo/genieacs?authSource=admin + GENIEACS_CWMP_ACCESS_LOG_FILE: /var/log/genieacs/genieacs-cwmp-access.log + GENIEACS_NBI_ACCESS_LOG_FILE: /var/log/genieacs/genieacs-nbi-access.log + GENIEACS_FS_ACCESS_LOG_FILE: /var/log/genieacs/genieacs-fs-access.log + GENIEACS_UI_ACCESS_LOG_FILE: /var/log/genieacs/genieacs-ui-access.log + GENIEACS_DEBUG_FILE: /var/log/genieacs/genieacs-debug.yaml + GENIEACS_EXT_DIR: /opt/genieacs/ext + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + #networks: + # - proxy + #labels: + # - traefik.enable=true + # - traefik.docker.network=proxy + # - traefik.http.routers.genieacs.rule=Host(`acs.example.com`) + # - traefik.http.services.genieacs.loadbalancer.server.port=3000 + + mongo: + image: mongo:8.0 + container_name: genieacs-mongo + restart: unless-stopped + expose: + - 27017 + volumes: + - ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/genieacs/mongodb:/data/db + - ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/genieacs/mongodb-config:/data/configdb + healthcheck: + test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 40s + +#networks: +# proxy: +# external: true diff --git a/examples/lynxprompt/.env b/examples/lynxprompt/.env new file mode 100644 index 000000000..cd86e3866 --- /dev/null +++ b/examples/lynxprompt/.env @@ -0,0 +1,12 @@ +# Change these settings +APP_URL=http://localhost:3000 +NEXTAUTH_SECRET= +POSTGRES_PASSWORD= +SUPERADMIN_EMAIL=admin@example.com + +# Sign-in links go out by mail +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER=lynxprompt@example.com +SMTP_PASSWORD= +SMTP_FROM=lynxprompt@example.com diff --git a/examples/lynxprompt/README.md b/examples/lynxprompt/README.md new file mode 100644 index 000000000..e0a76ef22 --- /dev/null +++ b/examples/lynxprompt/README.md @@ -0,0 +1,9 @@ +# References + +- https://github.com/GeiserX/LynxPrompt +- https://hub.docker.com/r/drumsergio/lynxprompt +- https://lynxprompt.com + +# Notes + +Fill in the `.env` file: generate `NEXTAUTH_SECRET` with `openssl rand -base64 32` and `POSTGRES_PASSWORD` with `openssl rand -hex 24`. Sign-in is a link sent by mail, so set the `SMTP_*` values of a real mail server (leave `SMTP_USER` and `SMTP_PASSWORD` empty if it needs no login; port 465 uses TLS). Set `APP_URL` to the address you open it on, `http://` or `https://`, and `SUPERADMIN_EMAIL` to your address to become superadmin on your first sign-in. The app runs as uid 1001, so avatar and logo uploads need `sudo chown -R 1001:1001 ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/lynxprompt/uploads`. diff --git a/examples/lynxprompt/docker-compose.yml b/examples/lynxprompt/docker-compose.yml new file mode 100644 index 000000000..e7181c4e6 --- /dev/null +++ b/examples/lynxprompt/docker-compose.yml @@ -0,0 +1,85 @@ +services: + + lynxprompt: + image: drumsergio/lynxprompt:2.1.40 + container_name: lynxprompt + # The image is built for amd64 only; ARM hosts run it under emulation. + platform: linux/amd64 + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + ports: + - 3000:3000 + expose: + - 3000 + volumes: + - ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/lynxprompt/uploads:/data/uploads + environment: + # NextAuth (required, generate with: openssl rand -base64 32) + NEXTAUTH_URL: ${APP_URL:-http://localhost:3000} + NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:?Generate with openssl rand -base64 32} + APP_URL: ${APP_URL:-http://localhost:3000} + # Promoted to superadmin when this address signs in + SUPERADMIN_EMAIL: ${SUPERADMIN_EMAIL:-} + # Databases: one server, one database per schema; the app creates + # lynxprompt_users, lynxprompt_blog and lynxprompt_support on first start + DB_APP_HOST: postgres + DB_APP_USER: lynxprompt + DB_APP_PASSWORD: ${POSTGRES_PASSWORD:-DatabasePassword1234} + DB_APP_NAME: lynxprompt + DB_USERS_HOST: postgres + DB_USERS_USER: lynxprompt + DB_USERS_PASSWORD: ${POSTGRES_PASSWORD:-DatabasePassword1234} + DB_USERS_NAME: lynxprompt_users + DB_BLOG_HOST: postgres + DB_BLOG_USER: lynxprompt + DB_BLOG_PASSWORD: ${POSTGRES_PASSWORD:-DatabasePassword1234} + DB_BLOG_NAME: lynxprompt_blog + DB_SUPPORT_HOST: postgres + DB_SUPPORT_USER: lynxprompt + DB_SUPPORT_PASSWORD: ${POSTGRES_PASSWORD:-DatabasePassword1234} + DB_SUPPORT_NAME: lynxprompt_support + # Mail (required: sign-in is a link sent by mail) + SMTP_HOST: ${SMTP_HOST:?Set the SMTP server that sends the sign-in links} + SMTP_PORT: ${SMTP_PORT:-587} + SMTP_USER: ${SMTP_USER:-} + SMTP_PASSWORD: ${SMTP_PASSWORD:-} + SMTP_FROM: ${SMTP_FROM:?Set the sender address of the sign-in mails} + UPLOAD_DIR: /data/uploads/blog + # Optional: GitHub sign-in, AI features + #ENABLE_GITHUB_OAUTH: ${ENABLE_GITHUB_OAUTH:-false} + #GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID:-} + #GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET:-} + #ENABLE_AI: ${ENABLE_AI:-false} + #ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} + #networks: + # - proxy + #labels: + # - traefik.enable=true + # - traefik.docker.network=proxy + # - traefik.http.routers.lynxprompt.rule=Host(`lynxprompt.example.com`) + # - traefik.http.services.lynxprompt.loadbalancer.server.port=3000 + + postgres: + image: postgres:18-alpine + container_name: lynxprompt-postgres + restart: unless-stopped + expose: + - 5432 + volumes: + # Postgres 18 keeps its data one level up and refuses a mount at /var/lib/postgresql/data + - ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/lynxprompt/postgres:/var/lib/postgresql + environment: + POSTGRES_DB: lynxprompt + POSTGRES_USER: lynxprompt + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-DatabasePassword1234} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U lynxprompt -d lynxprompt"] + interval: 10s + timeout: 5s + retries: 5 + +#networks: +# proxy: +# external: true diff --git a/examples/telegram-archive/README.md b/examples/telegram-archive/README.md new file mode 100644 index 000000000..09e6e3c97 --- /dev/null +++ b/examples/telegram-archive/README.md @@ -0,0 +1,9 @@ +# References + +- https://github.com/GeiserX/Telegram-Archive +- https://hub.docker.com/r/drumsergio/telegram-archive +- https://hub.docker.com/r/drumsergio/telegram-archive-viewer + +# Notes + +Both containers run as uid 1000, so the data folder must belong to that user: `sudo chown -R 1000:1000 ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/telegram-archive`. Log in to Telegram once before the first start with `docker compose run --rm telegram-backup python -m telegram_archive auth`; it asks for the code Telegram sends you. The viewer is on port 8000. diff --git a/examples/telegram-archive/docker-compose.yml b/examples/telegram-archive/docker-compose.yml new file mode 100644 index 000000000..c893a3f2f --- /dev/null +++ b/examples/telegram-archive/docker-compose.yml @@ -0,0 +1,57 @@ +services: + + telegram-backup: + image: drumsergio/telegram-archive:9.3.2 + container_name: telegram-backup + restart: unless-stopped + command: ["python", "-m", "telegram_archive", "schedule"] + volumes: + - ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/telegram-archive:/data + environment: + # Telegram Credentials (required — get from https://my.telegram.org) + TELEGRAM_API_ID: ${TELEGRAM_API_ID} + TELEGRAM_API_HASH: ${TELEGRAM_API_HASH} + TELEGRAM_PHONE: ${TELEGRAM_PHONE} + SESSION_NAME: ${SESSION_NAME:-telegram_backup} + # Full pass schedule (cron format). Empty means one pass a day; new messages are saved as they arrive. + SCHEDULE: ${SCHEDULE:-} + # Backup settings + BACKUP_PATH: /data/backups + DOWNLOAD_MEDIA: ${DOWNLOAD_MEDIA:-true} + MAX_MEDIA_SIZE_MB: ${MAX_MEDIA_SIZE_MB:-100} + # Chat filtering (comma-separated types: private, groups, channels) + CHAT_TYPES: ${CHAT_TYPES:-private,groups,channels} + # Database + DB_TYPE: ${DB_TYPE:-sqlite} + DB_PATH: /data/backups/telegram_backup.db + + telegram-viewer: + image: drumsergio/telegram-archive-viewer:9.3.2 + container_name: telegram-viewer + restart: unless-stopped + ports: + - 8000:8000 + expose: + - 8000 + volumes: + - ${DOCKER_VOLUME_STORAGE:-/mnt/docker-volumes}/telegram-archive:/data + environment: + BACKUP_PATH: /data/backups + # Authentication (recommended) + VIEWER_USERNAME: ${VIEWER_USERNAME:-admin} + VIEWER_PASSWORD: ${VIEWER_PASSWORD:-ChangeMe1234} + VIEWER_TIMEZONE: ${VIEWER_TIMEZONE:-Europe/Berlin} + # Database — must match backup service + DB_TYPE: ${DB_TYPE:-sqlite} + DB_PATH: /data/backups/telegram_backup.db + #networks: + # - proxy + #labels: + # - traefik.enable=true + # - traefik.docker.network=proxy + # - traefik.http.routers.telegram-viewer.rule=Host(`telegram.example.com`) + # - traefik.http.services.telegram-viewer.loadbalancer.server.port=8000 + +#networks: +# proxy: +# external: true