Infrastructure & Networking

Chapter Introduction

Overview

This chapter documents the foundational infrastructure layer that all other services depend on. These nine services form the backbone of the Centerpoint stack — handling reverse proxying, TLS, identity, DNS, threat detection, logging, and observability.

Services in This Chapter

Service Container(s) Purpose
Traefik v3 traefik Reverse proxy and TLS termination
Step-CA step-ca Internal ACME certificate authority
Portainer EE portainer Docker container management UI
Authentik authentik-server, authentik-worker, authentik-postgresql, authentik-geoip SSO / identity provider
AdGuard Home adguardhome LAN DNS resolver and ad blocking
CrowdSec crowdsec, crowdsec-bouncer-traefik Collaborative threat detection and blocking
Dozzle dozzle Real-time container log viewer
Uptime-Kuma uptime-kuma Service uptime and endpoint monitoring
Homepage homepage Homelab dashboard

Dependency Order

When starting from scratch, services must come up in this order:

  1. AdGuard Home*.home.local DNS must resolve before anything can find its neighbours
  2. Step-CA — required for Traefik to issue internal certificates on first boot
  3. Traefik — all named HTTPS routes depend on it
  4. Authentik (PostgreSQL → Server → Worker) — required before any externally-accessible service that enforces SSO
  5. CrowdSecCrowdSec Bouncer — bouncer cannot connect to LAPI until CrowdSec is healthy
  6. All other infrastructure services (Portainer, Dozzle, Uptime-Kuma, Homepage) can start in any order

Last Updated: 2026-06-16

Traefik v3

Overview

Traefik is the single ingress point for all named HTTP/HTTPS traffic on Centerpoint. It runs on the traefik-net Docker bridge network and discovers routes automatically from container labels — no manual reload is needed when stacks are added or removed. All TLS termination happens at Traefik; individual application containers serve plain HTTP internally.

Access

Type URL / Endpoint Notes
Dashboard https://traefik.home.local Internal only — LAN access required

The dashboard is exposed only on the internal Step-CA route. There is no external (internet-facing) route for the Traefik dashboard.

Configuration

Image: traefik:v3.6.13 Compose project: traefik (same project as step-ca)

Ports

Port Protocol Purpose
80 TCP HTTP — auto-redirects all traffic to HTTPS
443 TCP HTTPS — primary entrypoint
8080 TCP Traefik API / Dashboard (internal)

Static Configuration — traefik.yml

Location: /home/jeeves/docker/traefik/traefik.yml

Key settings:

api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

providers:
  docker:
    network: traefik-net
    exposedByDefault: false
  file:
    directory: /config
    watch: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: <redacted>
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web
  step-ca:
    acme:
      email: <redacted>
      storage: /letsencrypt/step-ca.json
      caServer: https://ca.home.local:9000/acme/acme/directory
      certificatesDuration: 720

experimental:
  plugins:
    geoblock:
      moduleName: github.com/PascalMinder/geoblock
      version: v0.3.6
    crowdsec-bouncer-traefik-plugin:
      moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
      version: v1.3.0

Certificate Resolvers

Resolver Scope Method CA Duration
letsencrypt External (*.jeeves5454.ddns.net) HTTP challenge Let's Encrypt 90 days
step-ca Internal (*.home.local) ACME Internal Step-CA at ca.home.local:9000 30 days

Plugins

Plugin Version Purpose
PascalMinder/geoblock v0.3.6 Blocks requests from countries not in allowlist
maxlerebourg/crowdsec-bouncer-traefik-plugin v1.3.0 Forwards requests to CrowdSec bouncer for IP checks

Geoblock is configured to allow CA, US, and IN only. The middleware is named plex-geoblock@file and is defined in /home/jeeves/docker/traefik/config/crowdsec.yml.

Dynamic Configuration

Location: /home/jeeves/docker/traefik/config/ (file-watched)

File Contents
crowdsec.yml plex-geoblock and crowdsec-bouncer middleware defs
dynamic.yml Static file-provider routes for Plex (no Docker labels)
middlewares.yml Additional shared middleware definitions

Standard Dual-Route Label Pattern

Each service that requires both internal and external access uses this label pattern in its docker-compose.yml:

labels:
  - "traefik.enable=true"

  # External route — Let's Encrypt TLS + security middleware
  - "traefik.http.routers.<name>-ext.rule=Host(`<svc>.jeeves5454.ddns.net`)"
  - "traefik.http.routers.<name>-ext.entrypoints=websecure"
  - "traefik.http.routers.<name>-ext.tls.certresolver=letsencrypt"
  - "traefik.http.routers.<name>-ext.middlewares=authentik-auth@docker,plex-geoblock@file,crowdsec-bouncer@file"

  # Internal route — Step-CA TLS, no SSO middleware
  - "traefik.http.routers.<name>-int.rule=Host(`<svc>.home.local`)"
  - "traefik.http.routers.<name>-int.entrypoints=websecure"
  - "traefik.http.routers.<name>-int.tls.certresolver=step-ca"

  # Backend
  - "traefik.http.services.<name>-svc.loadbalancer.server.port=<port>"

Volumes / Bind Mounts

Host Path Container Path Purpose
/home/jeeves/docker/traefik/traefik.yml /traefik.yml Static config
/home/jeeves/docker/traefik/config /config Dynamic config (file-watched)
/home/jeeves/docker/traefik/letsencrypt /letsencrypt ACME certificate storage
/var/log/traefik /var/log/traefik Access logs (JSON)
/var/run/docker.sock /var/run/docker.sock Docker label discovery

Dependencies

Notes / Gotchas


Last Updated: 2026-06-16

Step-CA (Internal Certificate Authority)

Overview

Step-CA is an internal ACME-compatible certificate authority that issues TLS certificates for all *.home.local domains. It allows Traefik to provision and auto-renew trusted certificates for internal services without relying on Let's Encrypt or exposing any ports to the internet.

Clients and browsers on the LAN trust *.home.local certificates because the Step-CA root certificate has been manually installed as a trusted CA on each device.

Access

Type URL / Endpoint Notes
ACME API https://ca.home.local:9000/acme/acme/directory Used by Traefik only
Step-CA UI N/A No web UI — CLI managed only

Step-CA does not have a browser-accessible dashboard. Management is via the step CLI tool.

Configuration

Image: smallstep/step-ca:latest Compose project: traefik (same project as traefik container)

Ports

Port Protocol Purpose
9000 TCP ACME API (host-bound: 0.0.0.0:9000)

Port 9000 is bound directly to the host so that Traefik (and any other ACME client on the LAN) can reach it at ca.home.local:9000.

CA Configuration — ca.json

Location: /home/jeeves/docker/step-ca/config/config/ca.json

Key settings (secrets redacted):

{
  "root": "/home/step/certs/root_ca.crt",
  "crt": "/home/step/certs/intermediate_ca.crt",
  "key": "/home/step/secrets/intermediate_ca_key",
  "address": "0.0.0.0:9000",
  "dnsNames": ["ca.home.local"],
  "db": {
    "type": "badger",
    "dataSource": "/home/step/db"
  },
  "authority": {
    "provisioners": [
      {
        "type": "ACME",
        "name": "acme"
      }
    ]
  }
}

Certificate duration for ACME-issued certs is set to 720 hours (30 days) in Traefik's step-ca resolver config. Traefik renews automatically before expiry.

Volumes / Bind Mounts

Host Path Container Path Purpose
/home/jeeves/docker/step-ca/config /home/step CA configuration, certificates, database

Directory Layout Inside the Volume

/home/jeeves/docker/step-ca/config/
├── config/
│   ├── ca.json          ← Main CA configuration
│   └── defaults.json    ← Step CLI defaults
├── certs/
│   ├── root_ca.crt      ← Root CA certificate (install this on client devices)
│   └── intermediate_ca.crt
├── secrets/             ← Private keys — never expose these
│   ├── root_ca_key
│   ├── intermediate_ca_key
│   └── password         ← Key encryption password (REDACTED)
└── db/                  ← BadgerDB certificate issuance database

Dependencies

Trusting the Root CA on Client Devices

Every device that accesses *.home.local URLs in a browser must trust the Step-CA root certificate. The root cert is at:

/home/jeeves/docker/step-ca/config/certs/root_ca.crt

Also available at /home/jeeves/docker/traefik/step-ca-root.crt (Traefik keeps a copy for its own ACME client trust store).

macOS

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain root_ca.crt

Windows

Import-Certificate -FilePath root_ca.crt -CertStoreLocation Cert:\LocalMachine\Root

Ubuntu / Debian

sudo cp root_ca.crt /usr/local/share/ca-certificates/step-ca.crt
sudo update-ca-certificates

Notes / Gotchas


Last Updated: 2026-06-16

Portainer EE

Overview

Portainer Enterprise Edition is the primary container management interface for Centerpoint. It provides a web UI for deploying stacks, viewing container logs, managing volumes and networks, and monitoring resource usage across the Docker environment.

All compose stacks are deployed and managed through Portainer rather than by running docker compose directly on the host. Portainer stores stack definitions internally (under /data/compose/) and rebuilds containers from those definitions when updated.

Access

Type URL Notes
Internal https://portainer.home.local LAN access via Step-CA TLS
HTTPS UI https://192.168.1.85:9443 Direct IP fallback
Tunnel Port 8001 (agent) For Edge Agent / remote access

Portainer does not have an external (internet-facing) Traefik route. Access is LAN-only or via Tailscale.

Configuration

Image: portainer/portainer-ee:latest Compose project: portainer

Ports

Port Protocol Purpose
8001 TCP Edge Agent tunnel port
9443 TCP HTTPS management UI (host-bound)

Traefik Labels

traefik.enable: "true"
traefik.http.routers.portainer.rule: Host(`portainer.home.local`)
traefik.http.routers.portainer.entrypoints: websecure
traefik.http.routers.portainer.tls.certresolver: step-ca
traefik.http.services.portainer.loadbalancer.server.port: 9443

Internal-only route — no external Traefik router.

Volumes / Bind Mounts

Host Path / Volume Container Path Purpose
portainer_portainer_data /data Portainer state and stack data (named volume, external)
/var/run/docker.sock /var/run/docker.sock Direct Docker socket access

The portainer_portainer_data volume is declared external: true — it must exist before the stack is started.

Note: Portainer mounts the Docker socket directly. This is intentional for Portainer EE; it is the only service with direct socket access.

Dependencies

Notes / Gotchas

FUTURE WORK


Last Updated: 2026-06-16

Authentik (SSO / Identity Provider)

Overview

Authentik is the identity provider and single sign-on (SSO) gateway for all externally-accessible services on Centerpoint. It implements ForwardAuth middleware for Traefik, meaning that any request arriving at an external route tagged with authentik-auth@docker is intercepted and validated by Authentik before being forwarded to the backend service.

Authentik also serves as an OAuth2/OIDC provider — services like BookStack use OIDC for native user login rather than ForwardAuth.

Access

Type URL Notes
Internal https://auth.home.local LAN access via Step-CA TLS
External https://auth.jeevesconsults.ca Internet-facing — OIDC redirect target

The external URL (auth.jeevesconsults.ca) is the one registered as the OIDC issuer with downstream services. It must be reachable by browsers completing OAuth2 flows.

Containers in This Stack

Container Image Role
authentik-server ghcr.io/goauthentik/server:2026.5.x HTTP server + ForwardAuth endpoint
authentik-worker ghcr.io/goauthentik/server:2026.5.x Background task worker (Rust entry)
authentik-postgresql postgres:16-alpine Primary database
authentik-geoip ghcr.io/maxmind/geoipupdate:v7.x GeoIP database updater (MaxMind)

Startup Order

authentik-postgresql must reach a healthy state before authentik-server and authentik-worker start. The authentik-geoip sidecar runs independently.

Configuration

Compose project: authentik

Key Environment Variables

Variable Value / Notes
AUTHENTIK_SECRET_KEY REDACTED — long random string, must stay constant
AUTHENTIK_POSTGRESQL__HOST authentik-postgresql
AUTHENTIK_POSTGRESQL__NAME authentik
AUTHENTIK_POSTGRESQL__USER authentik
AUTHENTIK_POSTGRESQL__PASSWORD REDACTED
AUTHENTIK_REDIS__HOST redis (internal sidecar or external Redis)
AUTHENTIK_LISTEN__HTTP 0.0.0.0:9000 — explicit bind required for Docker bridge
AUTHENTIK_ERROR_REPORTING__ENABLED false

Important: AUTHENTIK_LISTEN__HTTP: "0.0.0.0:9000" is required in Authentik 2026.5+. Newer versions default to [::] (IPv6 wildcard) which Docker bridge networks cannot reach via IPv4. Without this override, ForwardAuth requests from Traefik fail silently.

ForwardAuth Middleware

The Authentik ForwardAuth middleware is defined on the authentik-server container labels and is available to all services on traefik-net as:

authentik-auth@docker

Example usage on a protected external route:

labels:
  - "traefik.http.routers.<name>-ext.middlewares=authentik-auth@docker,plex-geoblock@file,crowdsec-bouncer@file"

OIDC Configuration (for native OIDC apps)

Applications using OIDC (e.g. BookStack) configure Authentik as their provider with the following settings:

Setting Value
Issuer URL https://auth.jeevesconsults.ca/application/o/<app-slug>/
JWKS URL <issuer>/.well-known/jwks.json
Client ID Per-application (set in Authentik admin UI)
Client Secret REDACTED — set per-application
email_verified Requires custom Scope Mapping returning true (2026.5+ change)

Volumes / Bind Mounts

Host Path / Volume Container Path Purpose
authentik_media /media Uploaded assets (logos, avatars)
authentik_custom-templates /templates Custom email / flow templates
authentik_postgresql_data /var/lib/postgresql/data PostgreSQL data directory
authentik_geoip_data /usr/share/GeoIP MaxMind GeoIP databases

All volumes are named Docker volumes managed by Portainer.

Sub-section: PostgreSQL

The authentik-postgresql container is a dedicated Postgres 16 sidecar that stores all Authentik state: users, groups, policies, flows, tokens, and audit logs. It is not shared with any other service.

Database credentials are passed to the server via AUTHENTIK_POSTGRESQL__* environment variables. The container is on the authentik-internal network only — it is never exposed to traefik-net or the host.

Sub-section: GeoIP Updater

authentik-geoip runs the MaxMind GeoIPUpdate daemon, which downloads and refreshes the GeoLite2-City and GeoLite2-ASN databases on a schedule. The databases are shared into authentik-server via the authentik_geoip_data volume.

A MaxMind account and licence key (REDACTED) are required for the GeoIP databases.

Sub-section: Worker

authentik-worker runs as the same container image as authentik-server but with the worker entrypoint. It handles background tasks: email delivery, outpost health checks, blueprint application, and event cleanup. Since Authentik 2025.10+, the worker uses a Rust-based entrypoint for improved performance.

Dependencies

Notes / Gotchas


Last Updated: 2026-06-16

AdGuard Home

Overview

AdGuard Home serves as the primary LAN-wide DNS resolver for the entire homelab network. All devices on the 192.168.1.0/24 subnet use it as their primary DNS server (192.168.1.85:53). It provides:

A secondary AdGuard Home instance runs on the CorSec server (Home Assistant machine at 192.168.1.64). DNS rewrites are also maintained there so that name resolution continues during Centerpoint maintenance or restarts. Client devices should have both IPs configured as DNS resolvers.

Access

Type URL Notes
Internal https://adguard.home.local LAN access via Step-CA TLS
Direct http://192.168.1.85:80 Plain HTTP UI (AdGuard internal port)

DNS service itself runs on port 53 (TCP + UDP), bound to the host IP.

Configuration

Image: adguard/adguardhome:v0.107.71 Compose project: adguardhome (managed via Portainer)

Ports

Port Protocol Purpose
53 TCP+UDP DNS resolver (host-bound)
80 TCP AdGuard web UI (HTTP, internal)
443 TCP DNS-over-HTTPS
853 TCP DNS-over-TLS
3000 TCP Initial setup port

Only port 53 is bound to the host. Other ports are exposed only within traefik-net.

Traefik Labels

traefik.enable: "true"
traefik.http.routers.adguard.rule: Host(`adguard.home.local`)
traefik.http.routers.adguard.entrypoints: websecure
traefik.http.routers.adguard.tls.certresolver: step-ca
traefik.http.services.adguard.loadbalancer.server.port: 80

Internal-only route — no external Traefik router.

Critical Wildcard DNS Entry

AdGuard Home (both primary and secondary) must have a DNS Rewrite configured as:

*.home.local → 192.168.1.85

This single wildcard record means Traefik receives all *.home.local HTTP requests and routes them by hostname. Without it, no internal service domain resolves.

All custom DNS rewrites (for individual hostnames outside the wildcard) must be kept in sync between the Centerpoint and CorSec instances.

Upstream DNS Resolvers

Upstream DNS (for forwarding public queries) is configured in AdGuard's settings UI. Common configuration:

Volumes / Bind Mounts

Host Path Container Path Purpose
/home/jeeves/docker/adguard/conf /opt/adguardhome/conf Configuration (AdGuardHome.yaml)
/home/jeeves/docker/adguard/work /opt/adguardhome/work Query logs and statistics database

Networks

AdGuard Home is on traefik-net for its web UI route and has port 53 bound directly to the host for DNS service.

Dependencies

High Availability

Instance Host IP Role
Primary Centerpoint 192.168.1.85 Primary — full config, rewrites, logging
Secondary CorSec (Home Assistant) 192.168.1.64 Backup — same rewrites, ad-block lists

Client devices should configure both DNS servers in priority order. The secondary takes over automatically if the primary becomes unreachable.

DNS rewrites must be manually kept in sync between the two instances — there is no automated synchronisation.

Notes / Gotchas

FUTURE WORK


Last Updated: 2026-06-16

CrowdSec

Overview

CrowdSec is a collaborative intrusion detection and prevention system integrated directly into Traefik. It analyses Traefik access logs in real time, detects attack patterns (brute force, CVE exploitation, bad bots, etc.), and instructs Traefik to block flagged IPs before they reach any backend service.

The stack consists of two containers:

Access

Neither CrowdSec container has a web UI. Management is via the cscli CLI inside the crowdsec container:

docker exec -it crowdsec cscli decisions list
docker exec -it crowdsec cscli alerts list
docker exec -it crowdsec cscli metrics

Configuration

Compose project: crowdsec (managed via Portainer)

Containers

crowdsec — Security Engine

Image: crowdsecurity/crowdsec:latest

Property Value
Network traefik-net
Restart policy unless-stopped

Key environment variables:

Variable Value / Notes
GID 1000
COLLECTIONS crowdsecurity/traefik crowdsecurity/http-cve crowdsecurity/whitelist-good-actors
BOUNCER_KEY_TRAEFIK REDACTED — shared secret used by the bouncer to authenticate with LAPI

Collections installed:

Collection Purpose
crowdsecurity/traefik Detects attack patterns in Traefik access logs
crowdsecurity/http-cve Detects exploitation of known HTTP CVEs
crowdsecurity/whitelist-good-actors Whitelists known-good crawlers and services

crowdsec-bouncer-traefik — Traefik Bouncer

Image: fbonalair/traefik-crowdsec-bouncer:latest

Property Value
Network traefik-net
Internal port 8080 (ForwardAuth endpoint)

Key environment variables:

Variable Value / Notes
GIN_MODE release
CROWDSEC_AGENT_HOST crowdsec:8080 — CrowdSec LAPI endpoint
CROWDSEC_BOUNCER_API_KEY REDACTED — must match BOUNCER_KEY_TRAEFIK

How the Bouncer Integrates with Traefik

The middleware is defined in /home/jeeves/docker/traefik/config/crowdsec.yml:

http:
  middlewares:
    crowdsec-bouncer:
      forwardAuth:
        address: http://crowdsec-bouncer-traefik:8080/api/v1/forwardAuth
        trustForwardHeader: true

This middleware is referenced on external Traefik routes as crowdsec-bouncer@file.

Log Ingestion

CrowdSec reads Traefik access logs from two bind-mounted paths:

Host Path Container Path Notes
/var/log/traefik /var/log/traefik:ro Primary log location
/home/jeeves/docker/traefik/logs /logs/traefik:ro Secondary / rotated logs

The acquis.yaml config file at /home/jeeves/docker/crowdsec/config/acquis.yaml defines which log files to tail and in what format.

Volumes / Bind Mounts

Host Path Container Path Purpose
/home/jeeves/docker/crowdsec/data /var/lib/crowdsec/data Decision database and GeoIP data
/home/jeeves/docker/crowdsec/config /etc/crowdsec Scenarios, parsers, config
/var/log/traefik /var/log/traefik:ro Traefik access log (read-only)
/home/jeeves/docker/traefik/logs /logs/traefik:ro Traefik rotated logs (read-only)

Dependencies

Notes / Gotchas


Last Updated: 2026-06-16

Dozzle

Overview

Dozzle is a lightweight, real-time log viewer for Docker containers. It provides a web UI to stream, search, and follow container logs without needing to SSH into the host and run docker logs. It is configured to monitor containers on both Centerpoint and Lusankya (the second homelab server at 192.168.1.114).

Access

Type URL Notes
Internal https://dozzle.home.local LAN access via Step-CA TLS

No external (internet-facing) Traefik route — LAN and Tailscale access only.

Configuration

Image: amir20/dozzle:latest (v10.6.0 at time of writing) Compose project: dozzle (managed via Portainer)

Environment Variables

Variable Value Purpose
DOZZLE_HOSTNAME Centerpoint Display name for the local host
DOZZLE_REMOTE_HOST tcp://192.168.1.114:2375|Lusankya Adds Lusankya as a remote Docker host
DOZZLE_ENABLE_ACTIONS false Disables container start/stop from UI
DOZZLE_ENABLE_SHELL true Enables shell access to containers

DOZZLE_ENABLE_SHELL=true allows executing shell commands inside any container from the Dozzle UI. This is a powerful capability — ensure Dozzle is not accessible externally.

Traefik Labels

traefik.enable: "true"
traefik.http.routers.dozzle.rule: Host(`dozzle.home.local`)
traefik.http.routers.dozzle.entrypoints: websecure
traefik.http.routers.dozzle.tls.certresolver: step-ca
traefik.http.services.dozzle.loadbalancer.server.port: 8080

Internal-only route. No Authentik ForwardAuth on this route — access is controlled at the network level (LAN + Tailscale only).

Volumes / Bind Mounts

Host Path Container Path Purpose
/var/run/docker.sock /var/run/docker.sock:ro Read-only Docker socket access

Dozzle mounts the Docker socket read-only. No persistent data volume is required — Dozzle streams logs directly from the Docker daemon and does not store them.

Networks

Network Purpose
traefik-net Exposes the Dozzle web UI

Remote Hosts

Dozzle connects to Lusankya's Docker daemon at tcp://192.168.1.114:2375. This requires Lusankya's Docker daemon to have TCP exposure enabled. Logs from both Centerpoint and Lusankya containers are visible in a single Dozzle instance.

Dependencies

Notes / Gotchas


Last Updated: 2026-06-16

Uptime-Kuma

Overview

Uptime-Kuma is a self-hosted uptime monitoring tool that tracks the availability of services and endpoints, sends alerts on downtime, and displays historical uptime statistics. It serves as the primary observability dashboard for the homelab — monitoring both internal services and external URLs.

Access

Type URL Notes
Internal (via Tailscale or LAN direct) Port 3001 on 192.168.1.85
External https://uptime.jeeves5454.ddns.net Internet-facing, protected by Authentik + GeoBlock + CrowdSec

Configuration

Image: louislam/uptime-kuma:2 Compose project: uptime-kuma (managed via Portainer; local file at /home/jeeves/docker/uptime_kuma/docker-compose.yml)

Ports

Port Protocol Purpose
3001 TCP Web UI (also bound to host for direct access)

Traefik Labels

traefik.enable: "true"
traefik.http.routers.uptime.rule: Host(`uptime.jeeves5454.ddns.net`)
traefik.http.routers.uptime.entrypoints: websecure
traefik.http.routers.uptime.tls.certresolver: letsencrypt
traefik.http.routers.uptime.middlewares: authentik-auth@docker,plex-geoblock@file,crowdsec-bouncer@file,uptime-headers
traefik.http.middlewares.uptime-headers.headers.customrequestheaders.X-Forwarded-Proto: https
traefik.http.services.uptime.loadbalancer.server.port: 3001

The uptime-headers middleware injects X-Forwarded-Proto: https — required because Uptime-Kuma needs to know the original scheme for correct redirect handling.

External access is gated behind Authentik SSO, GeoBlock (CA/US/IN), and CrowdSec.

Volumes / Bind Mounts

Host Path Container Path Purpose
/home/jeeves/docker/uptime_kuma/uptime-kuma-data /app/data SQLite DB, config, logs

The data directory stores:

Networks

Network Purpose
traefik-net External Traefik route
uptime-kuma_monitoring Internal per-stack network

Dependencies

Notes / Gotchas


Last Updated: 2026-06-16

Homepage.Dev

Overview

Homepage (gethomepage.dev) is the self-hosted service dashboard for Centerpoint. It provides a single-pane-of-glass view of all running services, organised into three tabs that reflect the different access methods available for each service. It also displays live Docker container status by connecting directly to the Docker socket.

Access

Type URL Notes
Internal https://centerpoint.home.local LAN access via Step-CA TLS
Direct http://192.168.1.85:3003 Plain HTTP fallback

No external (internet-facing) Traefik route.

Configuration

Image: ghcr.io/gethomepage/homepage:latest (v1.13.2 at time of writing) Compose project: homepage (Portainer-managed; local file at /home/jeeves/docker/homepage/docker-compose.yml)

Ports

Port Protocol Purpose
3003 TCP Web UI (mapped from internal 3000)

Traefik Labels

traefik.enable: "true"
traefik.http.routers.homepage.rule: Host(`centerpoint.home.local`)
traefik.http.routers.homepage.entrypoints: websecure
traefik.http.routers.homepage.tls.certresolver: step-ca
traefik.http.services.homepage.loadbalancer.server.port: 3000

Internal-only route on centerpoint.home.local.

Environment Variables

Variable Value
PUID 1000
PGID 1000
LOG_TARGETS stdout
HOMEPAGE_ALLOWED_HOSTS gethomepage.dev,192.168.1.64:3003,localhost:3003

Dashboard Structure

Homepage is configured with three tabs:

Tab Service suffix Description
External Secure (plain names) Services via *.jeeves5454.ddns.net or *.jeevesconsults.ca
Internal Secure (LAN) Services via *.home.local through Traefik
Internal Unsecured (IP) Services via direct http://IP:port

The default tab is set to Internal Secure.

Services can appear in multiple tabs if they have multiple access routes. Docker container status widgets (server: centerpoint, container: <name>) are applied to services where applicable.

Configuration Files

All config files live under /home/jeeves/docker/homepage/config/:

File Purpose
settings.yaml Dashboard title, theme, background, tab layout
services.yaml All service entries grouped by tab and category
widgets.yaml Top-bar info widgets (system stats, weather, etc.)
bookmarks.yaml Bookmark groups (if used)
docker.yaml Docker socket connection config for container status

Volumes / Bind Mounts

Host Path Container Path Purpose
/home/jeeves/docker/homepage/config /app/config All dashboard config files
/var/run/docker.sock /var/run/docker.sock:ro Read-only Docker socket for container status

Dependencies

Notes / Gotchas


Last Updated: 2026-06-16