docs: create Netgrimoire/Infrastructure/Docker_Template
This commit is contained in:
parent
4c97703fab
commit
860725a9bb
1 changed files with 205 additions and 0 deletions
205
Netgrimoire/Infrastructure/Docker_Template.md
Normal file
205
Netgrimoire/Infrastructure/Docker_Template.md
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
---
|
||||||
|
title: Docker Template
|
||||||
|
description: Swarm and Compose Template
|
||||||
|
published: true
|
||||||
|
date: 2026-04-10T19:53:21.433Z
|
||||||
|
tags:
|
||||||
|
editor: markdown
|
||||||
|
dateCreated: 2026-04-10T19:53:21.433Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Docker Swarm Template Standard — Netgrimoire
|
||||||
|
|
||||||
|
## Template
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Run with docker stack deploy -c <service>.yaml <service>
|
||||||
|
services:
|
||||||
|
<servicename>:
|
||||||
|
image: <image>:latest
|
||||||
|
environment:
|
||||||
|
TZ: America/Chicago
|
||||||
|
volumes:
|
||||||
|
- /DockerVol/<servicename>:/config # use WITH placement constraint
|
||||||
|
# - /data/nfs/znas/Docker/<servicename>:/data # use for bulk/data or no constraint
|
||||||
|
networks:
|
||||||
|
- netgrimoire
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: any
|
||||||
|
delay: 5s
|
||||||
|
max_attempts: 3
|
||||||
|
window: 120s
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.platform.arch != aarch64
|
||||||
|
- node.platform.arch != arm
|
||||||
|
labels:
|
||||||
|
# --- Caddy ---
|
||||||
|
caddy: <servicename>.netgrimoire.com
|
||||||
|
caddy.reverse_proxy: <servicename>:<PORT>
|
||||||
|
caddy.import: crowdsec
|
||||||
|
caddy.import_1: authentik
|
||||||
|
|
||||||
|
# --- Uptime Kuma ---
|
||||||
|
kuma.<servicename>.http.name: <Service Name>
|
||||||
|
kuma.<servicename>.http.url: https://<servicename>.netgrimoire.com
|
||||||
|
|
||||||
|
# --- Homepage ---
|
||||||
|
homepage.group: <Group>
|
||||||
|
homepage.name: <Service Name>
|
||||||
|
homepage.icon: <service>.png
|
||||||
|
homepage.href: https://<servicename>.netgrimoire.com
|
||||||
|
homepage.description: <Description>
|
||||||
|
|
||||||
|
# --- DIUN ---
|
||||||
|
diun.enable: "true"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
netgrimoire:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### Forbidden Fields
|
||||||
|
Never use these at the service level:
|
||||||
|
- `version:` — deprecated in Compose v2+
|
||||||
|
- `container_name:` — incompatible with Swarm replicas
|
||||||
|
- `restart:` — use `deploy.restart_policy` instead
|
||||||
|
- `depends_on:` — not supported in Swarm mode
|
||||||
|
|
||||||
|
### Volume Path Rules
|
||||||
|
|
||||||
|
| Path | When to Use |
|
||||||
|
|------|------------|
|
||||||
|
| `/DockerVol/<service>` | Config/state files. **Only valid when a placement constraint pins the service to a specific host.** |
|
||||||
|
| `/data/nfs/znas/Docker/<service>` | Data/bulk volumes, or any service without a specific hostname constraint |
|
||||||
|
|
||||||
|
### Caddy Labels
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
caddy: service.netgrimoire.com
|
||||||
|
caddy.reverse_proxy: servicename:PORT
|
||||||
|
caddy.import: crowdsec
|
||||||
|
caddy.import_1: authentik
|
||||||
|
```
|
||||||
|
|
||||||
|
- `caddy.import_1` is required for the second import — duplicate YAML keys cause deploy errors
|
||||||
|
- `caddy.reverse_proxy` uses `servicename:PORT` (internal Docker DNS), never `{{upstreams PORT}}`
|
||||||
|
- No `https://` prefix on the `caddy:` address line
|
||||||
|
- Services managed by Caddyfile (static config) must **not** also have Caddy Docker labels — mixing causes caddy-docker-proxy to merge them into a malformed upstream pool
|
||||||
|
|
||||||
|
### Networking
|
||||||
|
|
||||||
|
- Default VIP mode for services that publish ports
|
||||||
|
- `endpoint_mode: dnsrr` for internal-only services (no published ports) — avoids Swarm VIP stale DNS
|
||||||
|
- **Never use `dnsrr` on services with published ports** — incompatible with ingress mesh routing
|
||||||
|
|
||||||
|
### Placement Constraints
|
||||||
|
|
||||||
|
**Architecture exclusions** (always include unless ARM-specific):
|
||||||
|
```yaml
|
||||||
|
constraints:
|
||||||
|
- node.platform.arch != aarch64 # Pi 4 reports aarch64
|
||||||
|
- node.platform.arch != arm # Pi 3 reports arm
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Docker Swarm uses the kernel's arch string. Pi 4 reports `aarch64` not `arm64`. The constraint `!= arm64` does **not** exclude Pi 4s.
|
||||||
|
|
||||||
|
Verified node architectures in Netgrimoire:
|
||||||
|
```
|
||||||
|
DockerPi1: linux/aarch64
|
||||||
|
docker3: linux/x86_64
|
||||||
|
docker4: linux/x86_64
|
||||||
|
docker5: linux/x86_64
|
||||||
|
znas: linux/x86_64
|
||||||
|
```
|
||||||
|
|
||||||
|
### Label Sections
|
||||||
|
|
||||||
|
Labels are organized with comment dividers in this order:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
labels:
|
||||||
|
# --- Caddy ---
|
||||||
|
# --- Uptime Kuma ---
|
||||||
|
# --- Homepage ---
|
||||||
|
# --- DIUN ---
|
||||||
|
```
|
||||||
|
|
||||||
|
Use map syntax (not list syntax) for labels. List syntax (`- key=value`) and map syntax (`key: value`) both work, but map syntax is the standard.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Services Without a UI
|
||||||
|
|
||||||
|
Some services have no web interface and need no Caddy, Homepage, or Kuma labels:
|
||||||
|
|
||||||
|
**Example: DIUN**
|
||||||
|
```yaml
|
||||||
|
deploy:
|
||||||
|
labels:
|
||||||
|
# --- DIUN ---
|
||||||
|
diun.enable: "true"
|
||||||
|
```
|
||||||
|
|
||||||
|
Services in this category: DIUN, background workers, one-shot jobs.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kuma Label Format
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
kuma.<unique-id>.<monitor-type>.<field>: <value>
|
||||||
|
```
|
||||||
|
|
||||||
|
- `unique-id` — must be unique across all services in the entire Swarm
|
||||||
|
- `monitor-type` — `http`, `tcp`, `ping`, `dns`
|
||||||
|
- Common fields: `name`, `url`, `interval`, `maxretries`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
kuma.forgejo.http.name: Forgejo
|
||||||
|
kuma.forgejo.http.url: https://git.netgrimoire.com
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Homepage Label Format
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
homepage.group: Group Name
|
||||||
|
homepage.name: Display Name
|
||||||
|
homepage.icon: icon.png
|
||||||
|
homepage.href: https://service.netgrimoire.com
|
||||||
|
homepage.description: Short description
|
||||||
|
```
|
||||||
|
|
||||||
|
For services with widgets:
|
||||||
|
```yaml
|
||||||
|
homepage.widget.type: radarr
|
||||||
|
homepage.widget.url: http://radarr:7878
|
||||||
|
homepage.widget.key: apikey
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** Every `homepage.group` value must have a matching entry in `settings.yaml` with `style: column`, or the group will render full-width.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secrets Approach
|
||||||
|
|
||||||
|
Docker Swarm native secrets are preferred. For services that support `_FILE` env vars:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
MY_PASSWORD_FILE: /run/secrets/my_password
|
||||||
|
secrets:
|
||||||
|
- my_password
|
||||||
|
```
|
||||||
|
|
||||||
|
Plain credentials in environment vars are acceptable as an interim approach for services that don't support `_FILE`.
|
||||||
|
|
||||||
|
**Never use `env_file:` in Swarm stacks** — it's read by the Docker client at deploy time from the deploying machine, not injected into the container at runtime. Use `environment:` directly.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue