5cd70169c1fba3c44ef1e1e86778c5f9ee415591
Docker Compose Infrastructure Documentation
Overview
This infrastructure manages a comprehensive self-hosted environment including media management (Jellyfin, *arr stack), document management (Paperless-ngx), AI services (Open WebUI), photo management (Immich), and various utilities.
The deployment is split into 5 independent compose stacks sharing a common .env file and Docker networks.
Compose Stacks
| Stack | File | Services |
|---|---|---|
| Infrastructure | docker-compose.infra.yml |
portainer, ntopng, wud, homepage, dockerproxy, newt, npm, npm-db |
| Media | docker-compose.media.yml |
prowlarr, flaresolverr, qbittorrent, radarr, sonarr, lidarr, bazarr, seerr, jellyfin, slskd, metube, maloja, multi-scrobbler |
| Documents | docker-compose.documents.yml |
onlyoffice, paperless-ngx (db, broker, tika, gotenberg, webserver, ai), stirling-pdf, open-webui |
| Photo & ROM Library | docker-compose.photo-roms.yml |
immich (server, postgres, ml, redis), syncthing, retrom (db, adminer, service, jaeger) |
| Utilities | docker-compose.utils.yml |
gitea (server + db), tandoor (db + web), speedtest-tracker (app + db), rustdesk (hbbs + hbbr), redbot, iperf3-server, neolink, linkwarden (app + db + meilisearch), ntfy, mailrise |
Architecture
Internal Docker Services
| Stack | Service | Role | Port |
|---|---|---|---|
| Infrastructure | Nginx Proxy Manager | SSL termination & reverse proxy | 80, 443, 81 |
| Infrastructure | Portainer | Container management UI | 9443 |
| Infrastructure | Homepage | Service dashboard | 7575 |
| Infrastructure | WUD | Docker image update monitoring | 3666 |
| Infrastructure | ntopng | Network traffic monitoring | 3939 |
| Infrastructure | Docker Socket Proxy | Secure Docker API access | 2375 |
| Infrastructure | Newt | Pangolin tunnel client | - |
| Media | Jellyfin | Media server (HW transcoding) | 8096 |
| Media | Jellyseerr (seerr) | Media request management | 5055 |
| Media | Radarr | Movie management | 7878 |
| Media | Sonarr | TV show management | 8989 |
| Media | Lidarr | Music management | 8686 |
| Media | Bazarr | Subtitle management | 6767 |
| Media | Prowlarr | Indexer manager | 9696 |
| Media | FlareSolverr | Cloudflare bypass | 8191 |
| Media | qBittorrent | Download client | 7070 |
| Media | Slskd | Soulseek file sharing | 5030, 5031 |
| Media | Metube | YouTube downloader | 8081 |
| Media | Maloja | Music scrobbling | 42010 |
| Media | Multi-Scrobbler | Cross-platform scrobbler | 9078 |
| Documents | Paperless-ngx | Document management | 8100 |
| Documents | Paperless-AI | AI document processing | 3040 |
| Documents | Stirling-PDF | PDF manipulation | 8090 |
| Documents | OnlyOffice | Document collaboration | 8091 |
| Documents | Open WebUI | LLM interface | 3000 |
| Photo & ROM | Immich | Photo management | 2283 |
| Photo & ROM | Syncthing | File synchronization | 8384 |
| Photo & ROM | Retrom | ROM library management | 5111 |
| Utilities | Gitea | Git service | 8418 |
| Utilities | Tandoor Recipes | Recipe management | 8450 |
| Utilities | Speedtest Tracker | Network monitoring | 8180 |
| Utilities | RustDesk | Remote desktop (host mode) | - |
| Utilities | RedBot | Discord bot | - |
| Utilities | iperf3-server | Network performance test | 5201 |
| Utilities | Neolink | Reolink camera bridge | 8554 |
| Utilities | Linkwarden | Bookmark manager | 3400 |
| Utilities | Ntfy | Push notification service | 8086 |
| Utilities | Mailrise | SMTP-to-ntfy notification bridge | 8025 |
Network Segmentation
- media_net: Media services and *arr applications
- db_net: Database services (internal only)
- web_net: Web-accessible services
- internal_net: Internal service communication
Networks are created by infra.yml and referenced as external by all other stacks.
Storage Structure
Local Docker Configs (/docker/)
/docker/
├── Arrs/ (Prowlarr, Radarr, Sonarr, Lidarr, Bazarr, Jellyfin, Jellyseerr)
├── Homepage/
├── immich/
├── paperless/
├── discord-agent/ (Separate stack)
├── gitea/
├── gramps-jamie/ (Separate stack)
├── gramps-helen/ (Separate stack)
├── kasm/ (Separate stack)
├── foundry-watcher/ (Separate stack)
├── litellm/ (Separate stack)
├── linkwarden/
├── maloja/
├── neolink/
├── npm/
├── ntopng/
├── qBittorrent/
├── redbot/
├── retrom/
├── rustdesk/
├── scrobble/ (Multi-scrobbler)
├── slskd/
├── speedtest-tracker/
├── stirling/
├── surmai/
├── syncthing/
├── tandoor/
├── ntfy/ (notification configs)
├── wud/
└── .env (shared environment variables)
NAS Storage (/mnt/nas-storage/data/)
/mnt/nas-storage/data/
├── media/
│ ├── movies/
│ ├── tv/
│ ├── music/
│ └── romms/
└── torrents/
├── metube/
└── soulsync/
Deployment
First-time deploy (or after network cleanup)
# Deploy infrastructure first (creates shared networks)
docker compose -f docker-compose.infra.yml up -d
# Then deploy remaining stacks in any order
docker compose -f docker-compose.media.yml up -d
docker compose -f docker-compose.documents.yml up -d
docker compose -f docker-compose.photo-roms.yml up -d
docker compose -f docker-compose.utils.yml up -d
Deploy all stacks
for f in docker-compose.*.yml; do
if [ "$f" != "docker-compose.full.yaml.bak" ]; then
docker compose -f "$f" up -d
fi
done
Stop/start individual stacks
docker compose -f docker-compose.media.yml down
docker compose -f docker-compose.media.yml up -d
View logs
docker compose -f docker-compose.media.yml logs -f jellyfin
Prerequisites
Required Environment Variables (.env file)
# System
PUID=1000
PGID=1000
TZ=Pacific/Auckland
# URLs
JELLYFIN_URL=https://your-jellyfin-domain.com
PAPERLESS_URL=https://your-paperless-domain.com
HOMEPAGE_ALLOWED_HOSTS=your-homepage-domain.com
# Nginx Proxy Manager
NPM_PASSWORD=your_secure_password
# Paperless
PAPERLESS_DB_ROOT_PASSWORD=your_secure_password
PAPERLESS_DB_NAME=paperless
PAPERLESS_DB_USER=paperless
PAPERLESS_DB_PASSWORD=your_secure_password
PAPERLESS_SECRET_KEY=your_secret_key
# Immich
IMMICH_POSTGRES_PASSWORD=your_secure_password
# Slskd
SLSKD_USERNAME=your_username
SLSKD_PASSWORD=your_secure_password
# Speedtest Tracker
SPEEDTEST_DB_NAME=speedtest
SPEEDTEST_DB_USER=speedtest
SPEEDTEST_DB_PASSWORD=your_secure_password
SPEEDTEST_APP_KEY=base64:your_generated_key
# RedBot
REDBOT_TOKEN=your_discord_bot_token
# Tandoor
TANDOOR_SECRET_KEY=your_secret_key
TANDOOR_POSTGRES_DB=tandoor
TANDOOR_POSTGRES_USER=tandoor
TANDOOR_POSTGRES_PASSWORD=your_secure_password
# Linkwarden
LINKWARDEN_DB_PASSWORD=your_secure_password
NEXTAUTH_SECRET=your_secret
NEXTAUTH_URL=https://your-linkwarden-domain.com
# WUD
WUD_REGISTRY_HUB_0_LOGIN=your_dockerhub_username
WUD_REGISTRY_HUB_0_TOKEN=your_dockerhub_token
# OnlyOffice
OO_JWT_SECRET=your_secret
# Maloja
MALOJA_FORCE_PASSWORD=your_password
MALOJA_URL=http://maloja:42010
MALOJA_API_KEY=your_key
# Jellyfin
JELLYFIN_APIKEY_MS=your_api_key_for_multiscrobbler
JELLYFIN_USER=your_username
System Requirements
- Docker Engine 20.10+
- Docker Compose V2
- Sufficient storage for media and databases
- Intel GPU for Jellyfin hardware transcoding (optional)
Installation
- Clone this repository
- Create
.envfrom.env.exampleand fill in values - Run infrastructure:
docker compose -f docker-compose.infra.yml up -d - Deploy desired stacks:
docker compose -f docker-compose.media.yml up -d
Maintenance
Backup Strategy
Critical Data to Backup:
/docker/— all service configurations- Named volumes:
portainer_data,docker_dbdata,open-webui .envfile (contains secrets)
Optional (can be regenerated):
- Media files on NAS
Updates
for f in docker-compose.infra.yml docker-compose.media.yml docker-compose.documents.yml docker-compose.photo-roms.yml docker-compose.utils.yml; do
docker compose -f "$f" pull
docker compose -f "$f" up -d
done
Resource Limits
- Portainer: 512MB RAM limit
- Log rotation: 10MB max, 3 files (on services with logging config)
Hardware Acceleration
Jellyfin is configured for Intel GPU transcoding:
- Device:
/dev/dri/renderD128 - Group:
104(render group)
Verify GPU access:
ls -l /dev/dri/renderD128
Security Considerations
- Secrets Management: Store
.envsecurely, never commit to version control - Network Segmentation: Database network is internal-only (
db_net) - Container Security:
no-new-privileges:trueon supported services - Reverse Proxy: Use NPM for SSL termination and authentication
- Updates: Regularly update containers as shown above
Troubleshooting
Service won't start
docker compose -f docker-compose.media.yml logs service_name
docker compose -f docker-compose.media.yml restart service_name
Database connection issues
docker compose -f docker-compose.documents.yml ps
docker compose -f docker-compose.documents.yml exec paperless-webserver ping paperless-db
Permission errors
ls -la /docker/service_name/
sudo chown -R $PUID:$PGID /docker/service_name/
Storage full
docker system df
docker system prune -a
Contributing Services
To add new services:
- Add service definition to the appropriate compose file
- Assign to correct network(s)
- Add volume mounts under
/docker/[service]/ - Update this README with service description
- Add required environment variables to
.env.example
Independent Stacks
The following services have their own compose files (not part of the main split):
- discord-agent/ — Discord Agent Bot
- foundry-watcher/ — Foundry VTT monitoring
- gramps-jamie/ — Genealogy (Jamie)
- gramps-helen/ — Genealogy (Helen)
- kasm/ — Browser workspace
- litellm/ — AI gateway
- mbi-poller/ — MBI poller service
License
This is a personal infrastructure setup. Adapt as needed for your use case.
Last Updated: May 2026
Description
Languages
Python
99.2%
Dockerfile
0.8%