init
This commit is contained in:
32
docs/adguard.md
Normal file
32
docs/adguard.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# AdGuard Home
|
||||
|
||||
**Purpose:** Network-wide DNS-based ad and tracker blocking.
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | ------------------------------ |
|
||||
| Status | Running |
|
||||
| Image | `adguard/adguardhome:latest` |
|
||||
| Ports | `53:53/tcp`, `53:53/udp` (DNS) |
|
||||
| Created by | jens |
|
||||
| Restart policy | `unless-stopped` |
|
||||
| Web UI | <https://adguard.home.jens.pub> |
|
||||
| Compose file | [`../services/adguard/docker-compose.yml`](../services/adguard/docker-compose.yml) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
- Exposed as DNS server on port 53 (TCP + UDP)
|
||||
- Web UI proxied through Traefik at `adguard.home.jens.pub`
|
||||
- Traefik routes to container port 80 (AdGuard's HTTP UI)
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount |
|
||||
| -------------- | --------------------------------------- |
|
||||
| `adguard_work` | `/opt/adguardhome/work` — working data |
|
||||
| `adguard_conf` | `/opt/adguardhome/conf` — configuration |
|
||||
|
||||
## Networks
|
||||
|
||||
- `proxy` (external)
|
||||
48
docs/beszel.md
Normal file
48
docs/beszel.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Beszel
|
||||
|
||||
**Purpose:** Lightweight container and host metrics monitoring (CPU, memory, disk, network).
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | ------------------------------ |
|
||||
| Status | Running |
|
||||
| Hub image | `henrygd/beszel:latest` |
|
||||
| Agent image | `henrygd/beszel-agent:latest` |
|
||||
| Web UI | <https://beszel.home.jens.pub> |
|
||||
| Compose file | [`../services/beszel/docker-compose.yml`](../services/beszel/docker-compose.yml) |
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
Beszel uses a **hub + agent** model:
|
||||
- **Hub** — web UI and data store, proxied via Traefik at `beszel.home.jens.pub`
|
||||
- **Agent** — runs in host network mode, collects metrics and communicates with the hub via a shared Unix socket (`/beszel_socket/beszel.sock`)
|
||||
|
||||
## Setup
|
||||
|
||||
On first run, open `beszel.home.jens.pub`, create an admin account, then add the local system:
|
||||
1. Go to **Systems → Add system**
|
||||
2. Set host to the Unix socket path: `/beszel_socket/beszel.sock`
|
||||
3. Copy the generated public key
|
||||
4. Set `BESZEL_KEY` in Portainer's stack env vars and redeploy
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description | Source |
|
||||
| ------------- | ---------------------------------- | ------ |
|
||||
| `APP_URL` | `https://beszel.home.jens.pub` | hardcoded |
|
||||
| `LISTEN` | `/beszel_socket/beszel.sock` | hardcoded |
|
||||
| `BESZEL_KEY` | Hub public key for agent auth | `.env` |
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount |
|
||||
| ---------------- | ------------------- |
|
||||
| `beszel_data` | `/beszel_data` — hub database and config |
|
||||
| `beszel_socket` | `/beszel_socket` — shared Unix socket between hub and agent |
|
||||
| `/var/run/docker.sock` | `:ro` — Docker socket for container metrics (agent) |
|
||||
|
||||
## Networks
|
||||
|
||||
- Hub: `proxy` (external)
|
||||
- Agent: `host`
|
||||
28
docs/dozzle.md
Normal file
28
docs/dozzle.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Dozzle
|
||||
|
||||
**Purpose:** Real-time Docker container log viewer.
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | --------------------------- |
|
||||
| Status | Running |
|
||||
| Image | `amir20/dozzle:latest` |
|
||||
| Web UI | <https://logs.home.jens.pub> |
|
||||
| Compose file | [`../services/dozzle/docker-compose.yml`](../services/dozzle/docker-compose.yml) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
- Live log streaming for all containers
|
||||
- No credentials required by default — consider enabling auth if exposed publicly
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount |
|
||||
| ------------- | ------------------------------------------- |
|
||||
| `dozzle_data` | `/data` — notification settings and config |
|
||||
| `/var/run/docker.sock` | `:ro` — Docker socket for log access |
|
||||
|
||||
## Networks
|
||||
|
||||
- `proxy` (external)
|
||||
123
docs/index.md
Normal file
123
docs/index.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Portainer — Homelab Documentation
|
||||
|
||||
> Generated: 2026-04-02
|
||||
> Source: <https://portainer.home.jens.pub>
|
||||
|
||||
---
|
||||
|
||||
## Instance Overview
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | --------------------------------- |
|
||||
| Edition | Portainer EE (Enterprise Edition) |
|
||||
| Image | `portainer/portainer-ee:lts` |
|
||||
| URL | <https://portainer.home.jens.pub> |
|
||||
| Container port | 9443 (HTTPS) |
|
||||
| Uptime | Running |
|
||||
|
||||
---
|
||||
|
||||
## Portainer Settings
|
||||
|
||||
| Setting | Value |
|
||||
| ----------------------- | ---------------------------- |
|
||||
| Authentication | Internal (username/password) |
|
||||
| Minimum password length | 12 characters |
|
||||
| User session timeout | 8 hours |
|
||||
| Snapshot interval | 5 minutes |
|
||||
| Edge compute | Disabled |
|
||||
| OAuth / LDAP | Not configured |
|
||||
|
||||
### Users
|
||||
|
||||
| Username | Role |
|
||||
| -------- | ------------- |
|
||||
| `jens` | Administrator |
|
||||
|
||||
---
|
||||
|
||||
## Environment (Endpoint)
|
||||
|
||||
Single environment: **local**
|
||||
|
||||
| Property | Value |
|
||||
| ------------------ | ----------------------------- |
|
||||
| Type | Docker standalone |
|
||||
| Connection | `unix:///var/run/docker.sock` |
|
||||
| Docker version | 29.3.0 |
|
||||
| CPUs | 6 |
|
||||
| Memory | ~15.5 GB |
|
||||
| Running containers | 3 |
|
||||
| Volumes | 4 |
|
||||
| Images | 7 |
|
||||
| Stacks | 2 (traefik, adguard) |
|
||||
| Swarm | No |
|
||||
|
||||
### Security Settings
|
||||
|
||||
- Bind mounts for regular users: **disabled**
|
||||
- Privileged mode for regular users: **disabled**
|
||||
- Host namespace for regular users: **disabled**
|
||||
- Stack management for regular users: **allowed**
|
||||
|
||||
---
|
||||
|
||||
## Docker Networks
|
||||
|
||||
| Name | Driver | Scope | Notes |
|
||||
| -------- | ------ | ----- | --------------------------------- |
|
||||
| `proxy` | bridge | local | Shared network used by all stacks |
|
||||
| `bridge` | bridge | local | Docker default |
|
||||
| `host` | host | local | Docker default |
|
||||
| `none` | null | local | Docker default |
|
||||
|
||||
The `proxy` network is an **external** bridge network created manually. All services that need Traefik routing must be attached to it.
|
||||
|
||||
---
|
||||
|
||||
## Running Stacks
|
||||
|
||||
| Stack | Purpose | Docs |
|
||||
| ---------- | ------------------------------ | ------------------------ |
|
||||
| `traefik` | Reverse proxy + TLS | [traefik.md](traefik.md) |
|
||||
| `adguard` | DNS ad/tracker blocking | [adguard.md](adguard.md) |
|
||||
| `portainer` | Container management UI | [portainer.md](portainer.md) |
|
||||
| `vaultwarden` | Password manager | [vaultwarden.md](vaultwarden.md) |
|
||||
| `watchtower` | Automatic image updates | [watchtower.md](watchtower.md) |
|
||||
| `beszel` | Container & host metrics | [beszel.md](beszel.md) |
|
||||
| `dozzle` | Container log viewer | [dozzle.md](dozzle.md) |
|
||||
|
||||
---
|
||||
|
||||
## Service Map
|
||||
|
||||
```
|
||||
Internet
|
||||
│
|
||||
▼
|
||||
[Host :80/:443]
|
||||
│
|
||||
▼
|
||||
[traefik:v3.6] ──── TLS wildcard cert (*.home.jens.pub via Namecheap DNS-01)
|
||||
│
|
||||
├── traefik.home.jens.pub ──→ Traefik dashboard (api@internal)
|
||||
├── adguard.home.jens.pub ──→ adguard:80 (AdGuard web UI)
|
||||
├── portainer.home.jens.pub ──→ portainer:9000
|
||||
├── vault.home.jens.pub ──→ vaultwarden:80 (password manager)
|
||||
├── beszel.home.jens.pub ──→ beszel:8090 (metrics)
|
||||
└── logs.home.jens.pub ──→ dozzle:8080 (log viewer)
|
||||
|
||||
[adguard/adguardhome] ──── DNS :53 (TCP/UDP)
|
||||
[portainer/portainer-ee] ──── Portainer UI :9443
|
||||
|
||||
All services share the external `proxy` bridge network.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes & Considerations
|
||||
|
||||
- **Sensitive credentials in stack definitions:** The `traefik` stack has the Namecheap API key and source IP hardcoded in the compose environment. Consider moving these to a `.env` file or Portainer's secret/environment variable management.
|
||||
- **AdGuard image tag:** Using `latest` — consider pinning to a specific version for reproducibility.
|
||||
- **Portainer not in a stack:** The Portainer container itself is not managed as a Portainer stack (typical self-managed setup).
|
||||
- **Access control:** The `traefik` stack is admin-only. The `adguard` stack grants explicit access to user `jens` (ID 1).
|
||||
32
docs/portainer.md
Normal file
32
docs/portainer.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Portainer (service)
|
||||
|
||||
**Purpose:** Docker container management UI.
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | --------------------------------- |
|
||||
| Status | Running |
|
||||
| Image | `portainer/portainer-ee:lts` |
|
||||
| Ports | `9443:9443` (HTTPS, direct) |
|
||||
| Restart policy | `unless-stopped` |
|
||||
| Web UI | <https://portainer.home.jens.pub> |
|
||||
| Compose file | [`../services/portainer/docker-compose.yml`](../services/portainer/docker-compose.yml) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
- Port 9443 published directly to the host for HTTPS access
|
||||
- Port 9000 (HTTP) used internally — Traefik proxies `portainer.home.jens.pub` to it
|
||||
- Port 8000 (Edge agent tunnel) not exposed
|
||||
- Not managed as a Portainer stack — deployed manually from `/home/jens/portainer/`
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount |
|
||||
| ---------------- | ------- |
|
||||
| `portainer_data` | `/data` |
|
||||
| `/var/run/docker.sock` | `:rw` — Docker socket for container management |
|
||||
|
||||
## Networks
|
||||
|
||||
- `proxy` (external)
|
||||
43
docs/traefik.md
Normal file
43
docs/traefik.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Traefik
|
||||
|
||||
**Purpose:** Reverse proxy and TLS termination for all homelab services.
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | ------------------ |
|
||||
| Status | Running |
|
||||
| Image | `traefik:v3.6` |
|
||||
| Ports | `80:80`, `443:443` |
|
||||
| Created by | jens |
|
||||
| Restart policy | `unless-stopped` |
|
||||
| Compose file | [`../services/traefik/docker-compose.yml`](../services/traefik/docker-compose.yml) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
- HTTP (port 80) → automatically redirects to HTTPS
|
||||
- HTTPS (port 443) → TLS termination via Let's Encrypt
|
||||
- TLS wildcard certificate for `*.home.jens.pub` and `home.jens.pub`
|
||||
- Certificate resolver: **Let's Encrypt** via **DNS-01 challenge** (Namecheap provider)
|
||||
- DNS resolvers used for challenge: `1.1.1.1`, `8.8.8.8`
|
||||
- Docker provider: auto-discovers containers via socket (opt-in with `traefik.enable=true`)
|
||||
- Dashboard: enabled, exposed at `traefik.home.jens.pub` (secured, no insecure mode)
|
||||
|
||||
## Environment Variables (sensitive)
|
||||
|
||||
| Variable | Description |
|
||||
| --------------------- | --------------------------------------- |
|
||||
| `NAMECHEAP_API_USER` | Namecheap account username |
|
||||
| `NAMECHEAP_API_KEY` | Namecheap API key for DNS challenge |
|
||||
| `NAMECHEAP_SOURCE_IP` | Whitelisted IP for Namecheap API access |
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount |
|
||||
| ---------------------- | ------------------------------------------- |
|
||||
| `/var/run/docker.sock` | `:ro` — Docker socket for service discovery |
|
||||
| `traefik_acme` | `/acme` — Let's Encrypt certificate storage |
|
||||
|
||||
## Networks
|
||||
|
||||
- `proxy` (external)
|
||||
45
docs/vaultwarden.md
Normal file
45
docs/vaultwarden.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Vaultwarden
|
||||
|
||||
**Purpose:** Self-hosted password manager (Bitwarden-compatible server).
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | -------------------------------- |
|
||||
| Status | Deployed (env vars pending) |
|
||||
| Image | `vaultwarden/server:latest` |
|
||||
| Ports | None (Traefik only) |
|
||||
| Restart policy | `unless-stopped` |
|
||||
| Web UI | <https://vault.home.jens.pub> |
|
||||
| Admin UI | <https://vault.home.jens.pub/admin> |
|
||||
| Compose file | [`../services/vaultwarden/docker-compose.yml`](../services/vaultwarden/docker-compose.yml) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
- Web UI and API proxied through Traefik at `vault.home.jens.pub`
|
||||
- Traefik routes to container port 80
|
||||
- Admin panel available at `/admin` (requires `ADMIN_TOKEN`)
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description | Source |
|
||||
| --------------- | ------------------------------------ | -------- |
|
||||
| `ADMIN_TOKEN` | Token to access the `/admin` UI | `.env` |
|
||||
| `SMTP_HOST` | `smtp.mailbox.org` | hardcoded |
|
||||
| `SMTP_PORT` | `587` | hardcoded |
|
||||
| `SMTP_SECURITY` | `starttls` | hardcoded |
|
||||
| `SMTP_FROM` | `mail@jens.pub` | hardcoded |
|
||||
| `SMTP_USERNAME` | `mail@jens.pub` | hardcoded |
|
||||
| `SMTP_PASSWORD` | mailbox.org account password | `.env` |
|
||||
|
||||
> `ADMIN_TOKEN` and `SMTP_PASSWORD` must be set in Portainer's stack env vars before starting the container.
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount |
|
||||
| ----------------- | ------- |
|
||||
| `vaultwarden_data` | `/data` — database, attachments, config |
|
||||
|
||||
## Networks
|
||||
|
||||
- `proxy` (external)
|
||||
54
docs/watchtower.md
Normal file
54
docs/watchtower.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Watchtower
|
||||
|
||||
**Purpose:** Automatically updates Docker container images on a schedule and sends email notifications.
|
||||
|
||||
| Property | Value |
|
||||
| -------------- | ------------------------------ |
|
||||
| Status | Running |
|
||||
| Image | `nickfedor/watchtower:latest` |
|
||||
| Ports | None |
|
||||
| Restart policy | `unless-stopped` |
|
||||
| Schedule | Daily at 03:00 |
|
||||
| Compose file | [`../services/watchtower/docker-compose.yml`](../services/watchtower/docker-compose.yml) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
- Checks for updated images daily at 03:00 (`0 0 3 * * *`)
|
||||
- Automatically pulls and restarts containers with updated images
|
||||
- Removes old images after updating (`WATCHTOWER_CLEANUP=true`)
|
||||
- Sends an email summary to `mail@jens.pub` after each run
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Value | Source |
|
||||
| ------------------------------------------- | ---------------------- | --------- |
|
||||
| `WATCHTOWER_SCHEDULE` | `0 0 3 * * *` | hardcoded |
|
||||
| `WATCHTOWER_CLEANUP` | `true` | hardcoded |
|
||||
| `WATCHTOWER_NOTIFICATIONS` | `email` | hardcoded |
|
||||
| `WATCHTOWER_NOTIFICATION_EMAIL_FROM` | `mail@jens.pub` | hardcoded |
|
||||
| `WATCHTOWER_NOTIFICATION_EMAIL_TO` | `mail@jens.pub` | hardcoded |
|
||||
| `WATCHTOWER_NOTIFICATION_EMAIL_SERVER` | `smtp.mailbox.org` | hardcoded |
|
||||
| `WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT` | `587` | hardcoded |
|
||||
| `WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER` | `mail@jens.pub` | hardcoded |
|
||||
| `WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD` | mailbox.org password | `.env` |
|
||||
|
||||
## Excluding Containers
|
||||
|
||||
To exclude a container from being updated by Watchtower, add this label to it:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- "com.centurylinklabs.watchtower.enable=false"
|
||||
```
|
||||
|
||||
## Volumes
|
||||
|
||||
| Volume | Mount |
|
||||
| ---------------------- | ------------------------------------------- |
|
||||
| `/var/run/docker.sock` | `:ro` — Docker socket for container monitoring |
|
||||
|
||||
## Networks
|
||||
|
||||
- `proxy` (external)
|
||||
Reference in New Issue
Block a user