Advanced configuration
Everyday setup happens in the web UI. Nothing on this page is required for a normal install. These are deployment concerns: how the container is reached, what it may reach, and how it identifies clients.
Environment variables
Section titled “Environment variables”Every variable is optional. The defaults are what the container ships with.
| Variable | Default | What it does |
|---|---|---|
ALLOW_PRIVATE_IPS | unset | Turns the SSRF guard off, so badges and widgets may reach private, LAN and loopback addresses. Most homelab installs need it. |
SOCKET_PROXY_URL | unset | A Docker socket proxy, for container health monitoring. |
TRUST_PROXY | unset | Believe X-Forwarded-Proto, so a request through a TLS-terminating proxy gets a Secure cookie. |
TRUSTED_PROXY | unset | Where a front proxy sits, so nginx can resolve the real client for rate limiting. |
SESSION_MAX_AGE_DAYS | 12h | Idle session lifetime before re-login. Accepts a fraction. A session in use is extended. |
PASSWORD_HASH_MEMORY | 16mib | Memory per password hash. One of 8mib, 16mib, 32mib, 64mib, 128mib. |
LOG_LEVEL | info | debug, info, warn or error. warn and error behave the same. The General settings page also sets this, and that wins once the config has loaded. |
DEMO_MODE | unset | Run as a read-only public showcase. |
CONFIG_PATH | /data/apps.json | Where the config file lives. |
ICONS_PATH | /icons | Where uploaded icons are written. |
WIDGETS_PATH | /usr/share/nginx/html/widgets | Where widget folders are read from. A wrong path loads an empty registry and every widget reports as unknown. |
PORT | 3000 | The port the API listens on. Nginx proxies to it, so changing it means changing the nginx config too. |
The repo’s docker-compose.yml carries each of these as a commented line.
Reaching services on private IPs
Section titled “Reaching services on private IPs”The SSRF guard blocks requests to private, loopback and link-local addresses. Most homelab services live on private IPs, so most installs need the guard off:
environment: - ALLOW_PRIVATE_IPS=trueRead Security before setting it. Two things work without it: dotless hostnames such as Docker container names, and the host IP you set in General settings.
Reaching services on the Docker host
Section titled “Reaching services on the Docker host”On Linux a container cannot reach the host’s LAN IP by default. Add:
extra_hosts: - "host.docker.internal:host-gateway"host-gateway is a Docker built-in that resolves to the host machine’s IP.
Behind a reverse proxy
Section titled “Behind a reverse proxy”Two variables apply, and they do different things.
TRUST_PROXY=true makes Stackyard believe X-Forwarded-Proto: https, so the session cookie gets its Secure flag. Set it only when a proxy you control is actually in front of the app.
TRUSTED_PROXY tells nginx where the front proxy sits, so it can resolve the real client address for rate limiting:
TRUSTED_PROXY=172.18.0.0/16TRUSTED_PROXY="172.18.0.0/16 10.0.0.5"Without it, every request through the proxy counts as the same client and rate limiting becomes one shared bucket.
Rate-limit counters are held in memory and are not shared across replicas. Run a single instance behind any proxy.
Docker container health checks
Section titled “Docker container health checks”The health-check badge can read a container’s state from the Docker daemon. This needs a Docker socket proxy, a separate container that exposes a narrowed read-only view of the socket.
tecnativa/docker-socket-proxy is the usual choice:
services: socket-proxy: image: tecnativa/docker-socket-proxy environment: - CONTAINERS=1 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: - socket_proxy restart: unless-stopped
stackyard: environment: - SOCKET_PROXY_URL=http://socket-proxy:2375 networks: - socket_proxy
networks: socket_proxy:Then turn on Docker Container Health Checks in General.
Ping-based health checks need none of this. See Badges.
Optional host mounts
Section titled “Optional host mounts”Two mounts extend what the System Summary widget can read when its source is This Machine:
volumes: # CPU temperature sensors - /sys/class/thermal:/sys/class/thermal:ro # Disk usage for a mount path - /mnt/your-drive:/mnt/your-drive:roStackyard does not terminate TLS and serves plain HTTP only. Put it behind a reverse proxy that terminates TLS. See Security.