- Add service management prompts (review, standardize, troubleshoot, integration) - Add Docker Swarm migration and tutoring workflows (swarm-migration, swarm-tutor) - Add SSO onboarding guide for Authentik integration (sso-onboarding) - Add session lifecycle prompts (start, end, status) for context continuity - Add node bootstrap scripts for Debian Trixie (day0bootstrap.sh) and Ubuntu/Debian (pi_init.sh) These prompts implement gated, step-by-step workflows with explicit confirmation requirements to prevent accidental changes during service operations. Bootstrap scripts standardize IP configuration (10.0.0.200) and install Docker + Ansible on new nodes.
15 KiB
description
| description |
|---|
| Import and adapt roles from davestephens/ansible-nas into distributed homelab architecture with proper group placement, documentation, and testing. |
ansible-nas Role Importer
Context (Pre-Loaded Analysis)
This prompt contains embedded knowledge from a prior deep analysis of the davestephens/ansible-nas repository. No re-scanning is required for basic operations.
Repository Overview
- Source: https://github.com/davestephens/ansible-nas
- Branch: main
- Role Count: 90+ Docker application roles
- Pattern: Toggle-based (
<app>_enabled: true/false) - Limitation: Single-host design (
hosts: all) — requires adaptation for distributed architecture
Target Environment (Chester's Homelab)
| Group | Purpose | Example Hosts |
|---|---|---|
docker_hosts |
General compute, web apps | docker-01 (10.0.0.251) |
ai_grid |
GPU workloads, LLM inference | ai-lenovo (10.0.0.220) |
storage |
NAS, backup agents | synology, terramaster |
swarm_managers |
Docker Swarm cluster | pve-01 through pve-04 |
Role Structure Pattern (ansible-nas)
All roles follow this pattern:
# roles/<app>/tasks/main.yml
- name: Start <App>
block:
- name: Create <App> Directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
with_items:
- "{{ <app>_config_directory }}"
- name: Create <App> Docker Container
community.docker.docker_container:
name: "{{ <app>_container_name }}"
image: "{{ <app>_image_name }}:{{ <app>_image_version }}"
# ... container config
labels:
traefik.enable: "{{ <app>_available_externally | string }}"
when: <app>_enabled is true
- name: Stop <App>
block:
- name: Stop <App>
community.docker.docker_container:
name: "{{ <app>_container_name }}"
state: absent
when: <app>_enabled is false
Default Variables Pattern
# roles/<app>/defaults/main.yml
<app>_enabled: false
<app>_container_name: "<app>"
<app>_image_name: "vendor/<app>"
<app>_image_version: "latest" # We will pin this
<app>_config_directory: "{{ docker_home }}/<app>/config"
<app>_data_directory: "{{ docker_home }}/<app>/data"
<app>_port: "8080"
<app>_hostname: "<app>"
<app>_memory: "1g"
<app>_available_externally: false
<app>_user_id: "{{ ansible_nas_user_id }}"
<app>_group_id: "{{ ansible_nas_group_id }}"
Available Applications (Categorized)
Media & Streaming
| App | Description | Complexity |
|---|---|---|
plex |
Media server (proprietary) | Medium |
jellyfin |
Media server (FOSS) | Medium |
emby |
Media server | Medium |
airsonic |
Music streaming | Low |
navidrome |
Music streaming (modern) | Low |
booksonic |
Audiobook server | Low |
komga |
Comic/manga server | Low |
ubooquity |
Book/comic server | Low |
minidlna |
DLNA server | Low |
Media Management (Arr Stack)
| App | Description | Complexity |
|---|---|---|
sonarr |
TV show management | Medium |
radarr |
Movie management | Medium |
lidarr |
Music management | Medium |
bazarr |
Subtitle management | Low |
prowlarr |
Indexer aggregator | Medium |
jackett |
Torrent indexer API | Medium |
overseerr |
Request management | Medium |
ombi |
Request management | Medium |
Download Clients
| App | Description | Complexity |
|---|---|---|
transmission |
BitTorrent client | Low |
transmission-with-openvpn |
BitTorrent + VPN | High |
deluge |
BitTorrent client | Low |
sabnzbd |
Usenet downloader | Medium |
nzbget |
Usenet downloader | Medium |
pyload |
Download manager | Low |
youtubedlmaterial |
YouTube downloader | Low |
Reverse Proxy & Networking
| App | Description | Complexity |
|---|---|---|
traefik |
Reverse proxy + SSL | High |
cloudflare_ddns |
Dynamic DNS (Cloudflare) | Low |
ddns_updater |
Multi-provider DDNS | Low |
route53_ddns |
Dynamic DNS (AWS) | Low |
guacamole |
Remote desktop gateway | High |
Home Automation
| App | Description | Complexity |
|---|---|---|
homeassistant |
Home automation hub | High |
homebridge |
HomeKit bridge | Medium |
openhab |
Home automation | High |
esphome |
ESP device management | Medium |
mosquitto |
MQTT broker | Low |
Monitoring & Observability
| App | Description | Complexity |
|---|---|---|
stats |
Grafana + Prometheus stack | High |
grafana |
Dashboards (via stats) | - |
prometheus |
Metrics (via stats) | - |
netdata |
System monitoring | Low |
glances |
System monitoring | Low |
speedtest-tracker |
Internet speed logging | Low |
healthchecks.io |
Uptime monitoring | Low |
Logging
| App | Description | Complexity |
|---|---|---|
logging |
Loki + Promtail stack | High |
loki |
Log aggregation | Medium |
promtail |
Log shipping agent | Medium |
Dashboards
| App | Description | Complexity |
|---|---|---|
homepage |
Modern dashboard | Low |
heimdall |
Application dashboard | Low |
dashy |
Customizable dashboard | Low |
organizr |
Tab-based dashboard | Medium |
Development & CI/CD
| App | Description | Complexity |
|---|---|---|
gitea |
Lightweight Git server | Medium |
gitlab |
Full Git platform | High |
code-server |
VS Code in browser | Medium |
drone-ci |
CI/CD platform | High |
woodpecker-ci |
CI/CD (Drone fork) | High |
Documents & Notes
| App | Description | Complexity |
|---|---|---|
nextcloud |
Cloud storage/office | High |
paperless_ng |
Document management | High |
dokuwiki |
Wiki | Low |
tiddlywiki |
Personal wiki | Low |
silverbullet |
Markdown notes | Low |
wallabag |
Read-it-later | Medium |
freshrss |
RSS reader | Low |
miniflux |
RSS reader (minimal) | Low |
Backup & Sync
| App | Description | Complexity |
|---|---|---|
duplicati |
Backup to cloud | Medium |
duplicacy |
Deduplication backup | Medium |
syncthing |
File sync | Low |
timemachine |
Mac backup server | Medium |
Security & Identity
| App | Description | Complexity |
|---|---|---|
bitwarden |
Password manager (Vaultwarden) | Medium |
Utilities
| App | Description | Complexity |
|---|---|---|
portainer |
Docker management UI | Low |
watchtower |
Container auto-update | Low |
cloudcmd |
File manager (web) | Low |
krusader |
File manager (desktop) | Low |
wireshark |
Network analysis | Medium |
netbootxyz |
PXE boot server | High |
n8n |
Workflow automation | Medium |
minio |
S3-compatible storage | Medium |
Communication
| App | Description | Complexity |
|---|---|---|
gotify |
Push notifications | Low |
thelounge |
IRC client | Low |
znc |
IRC bouncer | Medium |
mumble |
Voice chat | Medium |
Gaming
| App | Description | Complexity |
|---|---|---|
minecraft-server |
Java edition server | Medium |
minecraft-bedrock-server |
Bedrock server | Medium |
valheim |
Valheim server | Medium |
romm |
ROM manager | Low |
Other
| App | Description | Complexity |
|---|---|---|
piwigo |
Photo gallery | Medium |
calibre |
E-book management | Medium |
calibreweb |
E-book web UI | Low |
octoprint |
3D printer control | Medium |
virtual_desktop |
Remote desktop | High |
mealie |
Recipe manager | Low |
firefly |
Personal finance | High |
apcupsd |
UPS monitoring | Low |
threadfin |
IPTV proxy | Medium |
tautulli |
Plex monitoring | Low |
NOT in ansible-nas (Build Yourself)
| App | Description | Notes |
|---|---|---|
ollama |
LLM inference | Requires custom role |
localai |
OpenAI-compatible API | Requires custom role |
stable-diffusion |
Image generation | Requires GPU role |
whisper |
Speech-to-text | Requires custom role |
Workflow
Gate 0 — Select Application
Present the categorized list above. Ask user to select ONE application.
Required confirmation phrase:
User must reply exactly: IMPORT: <app-name>
Do not proceed until this is received.
Step 1 — Fetch Current Role Definition
Fetch the role from ansible-nas:
https://raw.githubusercontent.com/davestephens/ansible-nas/main/roles/<app>/tasks/main.ymlhttps://raw.githubusercontent.com/davestephens/ansible-nas/main/roles/<app>/defaults/main.yml
Summarize:
- Required variables
- Docker image and version
- Ports exposed
- Volumes/bind mounts
- Dependencies (databases, other services)
- Traefik labels present
Gate 1 — Confirm Role Analysis
User must reply exactly: CONFIRM ANALYSIS: <app-name>
Step 2 — Determine Target Group
Based on app category and user input, recommend placement:
| Category | Recommended Group |
|---|---|
| Media, Arr Stack, Dashboards | docker_hosts |
| Monitoring agents, Logging agents | All hosts |
| Backup | storage or docker_hosts |
| GPU workloads | ai_grid |
| Development tools | docker_hosts |
Ask user to confirm or override placement.
Gate 2 — Confirm Placement
User must reply exactly: PLACE: <app-name> -> <group-name>
Step 3 — Adapt Role for Distributed Architecture
Transform the role:
- Pin image version (replace
:latest) - Adapt paths for Chester's environment:
- Config:
/opt/docker/<app>/config - Data:
/opt/docker/<app>/data
- Config:
- Add group conditional:
when: - <app>_enabled | default(false) - "'<target-group>' in group_names" - Update Traefik labels for Chester's domain
- Add resource limits if missing
- Remove NAS-specific paths (e.g.,
/mnt/Volume3)
Output the adapted role files:
roles/<app>/tasks/main.ymlroles/<app>/defaults/main.ymlroles/<app>/meta/main.yml(dependencies)
Gate 3 — Approve Adapted Role
User must reply exactly: APPROVE ROLE: <app-name>
Step 4 — Generate Group Variables
Create or update group_vars/<target-group>.yml with:
# <app> Configuration
<app>_enabled: true
<app>_container_name: "<app>"
<app>_image_version: "<pinned-version>"
<app>_port: "<port>"
<app>_hostname: "<app>"
<app>_available_externally: false
Gate 4 — Approve Variables
User must reply exactly: APPROVE VARS: <app-name>
Step 5 — Create Deployment Playbook
Generate ansible/playbooks/deploy_<app>.yml:
---
- name: Deploy <App>
hosts: <target-group>
become: true
roles:
- role: <app>
tags:
- <app>
Or append to existing group playbook.
Step 6 — Generate Documentation
Create documentation/roles/<app>.md:
# <App> Role
## Overview
- **Source:** Adapted from ansible-nas
- **Target Group:** <target-group>
- **Image:** <image>:<version>
- **Port:** <port>
## Variables
| Variable | Default | Description |
| :--- | :--- | :--- |
## Usage
\`\`\`bash
ansible-playbook -i inventory/hosts.ini ansible/playbooks/deploy_<app>.yml
\`\`\`
## Verification
\`\`\`bash
# Check container status
ansible <target-group> -m shell -a "docker ps --filter name=<app>"
# Check logs
ansible <target-group> -m shell -a "docker logs --tail=50 <app>"
\`\`\`
## Traefik Access
- Internal: `http://<host-ip>:<port>`
- External: `https://<app>.<domain>` (if enabled)
Gate 5 — Approve Documentation
User must reply exactly: APPROVE DOCS: <app-name>
Step 7 — Deploy and Test
Provide copy/paste commands:
# Syntax check
ansible-playbook -i inventory/hosts.ini ansible/playbooks/deploy_<app>.yml --syntax-check
# Dry run
ansible-playbook -i inventory/hosts.ini ansible/playbooks/deploy_<app>.yml --check
# Deploy
ansible-playbook -i inventory/hosts.ini ansible/playbooks/deploy_<app>.yml
# Verify
ansible <target-group> -m shell -a "docker ps --filter name=<app>"
ansible <target-group> -m shell -a "docker logs --tail=100 <app>"
# Health check (if applicable)
curl -s http://<host-ip>:<port>/health || curl -s http://<host-ip>:<port>/
Gate 6 — Confirm Healthy
User must reply exactly: HEALTHY: <app-name>
If NOT healthy, troubleshoot using:
- Container logs
- Port conflicts
- Volume permissions
- Network connectivity
Step 8 — Commit
Generate conventional commit message:
feat(roles): add <app> role adapted from ansible-nas
- Source: davestephens/ansible-nas
- Target group: <target-group>
- Image pinned to <version>
- Traefik integration included
Remind user:
- Do not commit
.envfiles - Verify no secrets in group_vars
Required phrase to finish:
User must reply: COMPLETE: <app-name>
Quick Reference Commands
List All ansible-nas Roles
curl -sL "https://api.github.com/repos/davestephens/ansible-nas/contents/roles" | grep '"name"' | cut -d'"' -f4 | sort
Fetch Role Files
APP="plex"
curl -sL "https://raw.githubusercontent.com/davestephens/ansible-nas/main/roles/${APP}/tasks/main.yml"
curl -sL "https://raw.githubusercontent.com/davestephens/ansible-nas/main/roles/${APP}/defaults/main.yml"
Check for Updates
curl -sL "https://api.github.com/repos/davestephens/ansible-nas/commits?per_page=5" | grep '"message"' | head -5
Non-Negotiables
- One app at a time. Do not batch imports.
- Pin image versions. Never deploy
:latestin production. - Test before production. Always run
--checkfirst. - Document everything. Every imported role gets a doc file.
- Respect group boundaries. Don't deploy media apps to AI nodes.
- Never expose secrets. Redact any credentials found in roles.
Adaptation Checklist
For each imported role, verify:
- Image version pinned
- Paths updated for Chester's structure (
/opt/docker/<app>/) - Group conditional added
- Traefik labels updated for Chester's domain
- Resource limits added (memory, CPU)
- PUID/PGID aligned with Chester's user
- Dependencies documented (databases, other services)
- Health check included
- Documentation generated
- Deployment tested
Session Memory
When resuming this workflow, the AI should:
- Check
roles/directory for already-imported roles - Check
group_vars/for enabled applications - Avoid re-importing existing roles unless upgrading
Related Prompts
service-new.prompt.md— For services NOT in ansible-nasservice-review.prompt.md— For auditing imported rolesservice-standardize.prompt.md— For pinning image versions
Related Documentation
- Inventory — Host groups
- Docker Management — Base Docker playbook
- Onboarding — New host setup