{"id":50556943,"url":"https://github.com/pprodman/ugreen-homelab","last_synced_at":"2026-06-04T08:01:15.894Z","repository":{"id":358091407,"uuid":"1238553357","full_name":"pprodman/ugreen-homelab","owner":"pprodman","description":"Homelab docker setup","archived":false,"fork":false,"pushed_at":"2026-05-15T17:05:57.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-15T19:41:46.406Z","etag":null,"topics":["docker","docker-compose","homelab"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pprodman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-14T08:17:04.000Z","updated_at":"2026-05-15T17:06:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pprodman/ugreen-homelab","commit_stats":null,"previous_names":["pprodman/ugreen-homelab"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pprodman/ugreen-homelab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pprodman%2Fugreen-homelab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pprodman%2Fugreen-homelab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pprodman%2Fugreen-homelab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pprodman%2Fugreen-homelab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pprodman","download_url":"https://codeload.github.com/pprodman/ugreen-homelab/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pprodman%2Fugreen-homelab/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33895175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","homelab"],"created_at":"2026-06-04T08:01:15.070Z","updated_at":"2026-06-04T08:01:15.838Z","avatar_url":"https://github.com/pprodman.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🐻🦁 ugreen-homelab\n\nHomelab Docker setup for the **BearsLions** homelab running on a **Ugreen DXP2800** (Intel N100, 8GB RAM).\n\nAll stacks are managed via **Dockhand** using a GitOps approach — configuration lives here, secrets stay in Dockhand.\n\n---\n\n## 📁 Repository Structure\n\n```\nugreen-homelab/\n├── global.env                  # Shared variables injected into all stacks\n├── adguard/\n│   └── docker-compose.yml\n├── beszel/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── code-server/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── homepage/\n│   └── docker-compose.yml\n├── immich/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── n8n/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── obsidian-sync/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── pangolin-agent/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── speedtest-tracker/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── tailscale/\n│   ├── docker-compose.yml\n│   └── .env.example\n├── uptime-kuma/\n│   └── docker-compose.yml\n├── vaultwarden/\n│   ├── docker-compose.yml\n│   └── .env.example\n└── watchyourlan/\n    └── docker-compose.yml\n```\n\n\u003e `.env` files are **gitignored**. Each stack with secrets includes a `.env.example` as reference.\n\u003e Sensitive values are managed via **Dockhand Secrets** (encrypted, never written to disk).\n\n---\n\n## 🌍 Global Configuration (`global.env`)\n\nShared variables injected into every stack by Dockhand at deploy time.\n\n| Variable | Description |\n|---|---|\n| `PUID` / `PGID` | User/group ID for LinuxServer images |\n| `TZ` | Timezone (`Europe/Madrid`) |\n| `DOCKER_ROOT` | Root path (`/volume1/docker`) |\n| `APPDATA_PATH` | Persistent data path (`/volume1/docker/appdata`) |\n| `GITOPS_PATH` | This repo's path on disk (`/volume1/docker/gitops`) |\n| `LOG_MAX_SIZE` / `LOG_MAX_FILE` | Global log rotation limits |\n| `DOMAIN` | Base domain (`bearslions.com`) |\n| `NAS_IP` | NAS local IP address (`192.168.1.225`) |\n\n---\n\n## 🛠️ Services\n\n### 🛡️ AdGuard Home\n**Image:** `adguard/adguardhome:latest`\n**IP:** `192.168.1.53` (macvlan)\n**Network:** `adguard_macvlan` — dedicated macvlan with fixed IP for DNS\n**Secrets:** None.\n\nNetwork-wide DNS server and ad blocker. Uses a dedicated macvlan network so it can bind to port 53 without conflicts with the host.\n\n```\nappdata/adguard/work/    ← runtime data\nappdata/adguard/conf/    ← configuration\n```\n\n---\n\n### 📊 Beszel\n**Images:** `henrygd/beszel` + `henrygd/beszel-agent`\n**Port:** `8090` (hub)\n**Secrets:** `BESZEL_AGENT_KEY`\n\nSystem monitoring dashboard with hub-agent architecture. The agent runs in host network mode to collect system metrics; the hub provides the web UI.\n\n| Variable | Description |\n|---|---|\n| `BESZEL_AGENT_KEY` | Public key for hub-agent authentication |\n\n```\nappdata/beszel/hub_data/    ← hub database \u0026 config\n```\n\n---\n\n### 💻 Code Server\n**Image:** `lscr.io/linuxserver/code-server:latest`\n**Port:** `8443`\n**Secrets:** `WEB_PASSWORD`\n\nVS Code in the browser. Configured with master access to the entire `DOCKER_ROOT`, making it a central editor for all stacks.\n\n| Variable | Description |\n|---|---|\n| `WEB_PASSWORD` | Web UI login password |\n\n```\nappdata/code-server/config/    ← extensions, themes, settings\n```\n\n---\n\n### 🏠 Homepage\n**Image:** `ghcr.io/gethomepage/homepage:latest`\n**Port:** `3005`\n**Secrets:** None.\n\nHomelab dashboard. Configuration is file-based inside the config volume. Has read-only access to `docker.sock` for automatic service discovery.\n\n```\nappdata/homepage/config/    ← services, widgets, bookmarks config\n```\n\n---\n\n### 📸 Immich\n**Images:** `immich-server` + `immich-machine-learning` + `postgres` + `valkey`\n**Port:** `2283`\n**Memory:** 2GB (server) + 2GB (ML) + 1GB (postgres) + 256MB (redis)\n**Secrets:** `DB_PASSWORD`, `IMMICH_VERSION`\n\nSelf-hosted photo and video management. Configured with OpenVINO hardware acceleration for the Intel N100 iGPU, covering face recognition, CLIP search, and smart albums. PostgreSQL uses the pgvecto.rs extension required by Immich.\n\n| Variable | Description |\n|---|---|\n| `DB_PASSWORD` | PostgreSQL password |\n| `IMMICH_VERSION` | Image tag (default: `release`) |\n\n```\nappdata/immich/album/         ← photo \u0026 video library\nappdata/immich/model-cache/   ← AI models (face recognition, CLIP)\nappdata/immich/postgres/      ← database\n```\n\n\u003e ⚠️ Immich is under active development. Pin `IMMICH_VERSION` to a specific tag for production stability.\n\n---\n\n### ⚙️ n8n\n**Image:** `docker.n8n.io/n8nio/n8n:latest`\n**Port:** `5678`\n**Secrets:** `N8N_ENCRYPTION_KEY`, `N8N_HOST`, `WEBHOOK_URL`\n\nWorkflow automation platform. All credentials stored in n8n are encrypted with `N8N_ENCRYPTION_KEY` — losing this key means losing access to all stored credentials.\n\n| Variable | Description |\n|---|---|\n| `N8N_ENCRYPTION_KEY` | Encryption key for stored credentials — back this up |\n| `N8N_HOST` | Hostname (e.g. `n8n.bearslions.com`) |\n| `WEBHOOK_URL` | Public webhook base URL (e.g. `https://n8n.bearslions.com/`) |\n\n```\nappdata/n8n/    ← workflows, credentials, settings\n```\n\n---\n\n### 📓 Obsidian Sync (CouchDB)\n**Image:** `couchdb:3.3.3`\n**Port:** `5984`\n**Memory limit:** `256MB`\n**Secrets:** `COUCHDB_USER`, `COUCHDB_PASSWORD`\n\nSelf-hosted CouchDB instance used as a sync backend for Obsidian via the [Self-hosted LiveSync](https://github.com/vrtmrz/obsidian-livesync) plugin.\n\n| Variable | Description |\n|---|---|\n| `COUCHDB_USER` | CouchDB admin username |\n| `COUCHDB_PASSWORD` | CouchDB admin password |\n\n```\nappdata/obsidian-sync/data/      ← CouchDB data\nappdata/obsidian-sync/config/    ← CouchDB local config\n```\n\n---\n\n### 🦎 Pangolin Agent (Newt)\n**Image:** `fosrl/newt:latest`\n**Memory limit:** `128MB`\n**Secrets:** `PANGOLIN_ENDPOINT`, `NEWT_ID`, `NEWT_SECRET`\n\nTunnel agent for [Pangolin](https://github.com/fosrl/pangolin), a self-hosted tunneling and reverse proxy solution.\n\n| Variable | Description |\n|---|---|\n| `PANGOLIN_ENDPOINT` | Pangolin server endpoint URL |\n| `NEWT_ID` | Agent ID |\n| `NEWT_SECRET` | Agent secret |\n\n---\n\n### 🚀 Speedtest Tracker\n**Image:** `lscr.io/linuxserver/speedtest-tracker:latest`\n**Port:** `8080`\n**URL:** `https://speed.bearslions.com`\n**Memory limit:** `512MB`\n**Secrets:** `APP_KEY`\n\nRuns scheduled internet speed tests (every hour) and tracks results over time. Uses SQLite as the local database.\n\n| Variable | Description |\n|---|---|\n| `APP_KEY` | Laravel application key — generate with `echo \"base64:$(openssl rand -base64 32)\"` |\n\n```\nappdata/speedtest-tracker/    ← app config \u0026 SQLite database\n```\n\n---\n\n### 🔒 Tailscale\n**Image:** `tailscale/tailscale:latest`\n**Network:** `host`\n**Secrets:** `TS_AUTHKEY`\n\nMesh VPN for secure remote access. Configured as an exit node and subnet router, advertising `192.168.1.0/24` to allow full LAN access from anywhere.\n\n| Variable | Description |\n|---|---|\n| `TS_AUTHKEY` | Tailscale auth key (generate at tailscale.com/settings/keys) |\n\n```\nappdata/tailscale/    ← Tailscale state\n```\n\n---\n\n### 📡 Uptime Kuma\n**Image:** `louislam/uptime-kuma:1`\n**Port:** `3001`\n**Secrets:** None — authentication is handled internally by the app.\n\nSelf-hosted monitoring tool. Tracks uptime of services, ports, and URLs with alerting support. Has read-only access to `docker.sock` for Docker container monitoring.\n\n```\nappdata/uptime-kuma/    ← monitors config \u0026 data\n```\n\n---\n\n### 🔑 Vaultwarden\n**Image:** `vaultwarden/server:latest`\n**Port:** `8081`\n**Memory limit:** `256MB`\n**Secrets:** `SIGNUPS_ALLOWED`, `ADMIN_TOKEN`\n\nLightweight Bitwarden-compatible password manager server. Signups are disabled by default — enable only when adding new users.\n\n| Variable | Description |\n|---|---|\n| `ADMIN_TOKEN` | Admin panel access token |\n| `SIGNUPS_ALLOWED` | Allow new registrations (`true`/`false`, default: `false`) |\n\n```\nappdata/vaultwarden/    ← vault data\n```\n\n---\n\n### 🔍 WatchYourLAN\n**Image:** `aceberg/watchyourlan:latest`\n**Port:** `8841`\n**Network mode:** `host` (required for ARP scanning)\n**Secrets:** None.\n\nNetwork scanner that detects all devices on the local network. Runs privileged with `NET_ADMIN` and `NET_RAW` capabilities for ARP scanning.\n\n```\nappdata/watchyourlan/   ← device history \u0026 config\n```\n\n---\n\n## 🔐 Secrets Management\n\nSecrets are **never committed** to this repository.\n\n- Each stack with secrets has a `.env.example` documenting the required variables\n- Actual values are set in **Dockhand** (encrypted in its database, injected at deploy time)\n- After a Docker-native restart (not via Dockhand), secrets may be lost — redeploy from Dockhand to re-inject them\n\n---\n\n## 🌐 Network\n\nMost stacks connect to a shared external Docker network:\n\n```bash\ndocker network create bearslions_network\n```\n\nExceptions:\n- **AdGuard** — uses a dedicated `adguard_macvlan` network with a fixed IP (`192.168.1.53`) for DNS\n- **WatchYourLAN**, **Tailscale**, **Beszel Agent** — use `network_mode: host` for low-level network access\n\n---\n\n## 🚀 Deployment\n\n1. Clone this repo to `/volume1/docker/gitops`\n2. Create the shared network:\n   ```bash\n   docker network create bearslions_network\n   ```\n3. Import each stack in **Dockhand** pointing to the corresponding folder\n4. Set secrets in Dockhand for stacks that require them (see `.env.example` in each folder)\n5. Deploy stacks in this order to respect dependencies:\n   - AdGuard → Tailscale → Vaultwarden\n   - PostgreSQL/Redis → Immich\n   - Everything else in any order\n\n---\n\n## 🖥️ Hardware\n\n| Spec | Value |\n|---|---|\n| Device | Ugreen DXP2800 |\n| CPU | Intel N100 |\n| RAM | 8GB |\n| OS | Ugreen UGOS Pro |","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpprodman%2Fugreen-homelab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpprodman%2Fugreen-homelab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpprodman%2Fugreen-homelab/lists"}