feat: Complete homelab GitOps setup with SSO and SSL
Core Infrastructure: - Add LLDAP for centralized user authentication (lldap.fig.systems) - Configure Tinyauth with LLDAP backend for SSO (auth.fig.systems) - Set up Traefik v3.3 with Let's Encrypt SSL automation - Create homelab Docker network for service isolation Media Services: - Configure Jellyfin with /media folder mappings (flix.fig.systems) - Add Jellyseerr for media requests (requests.fig.systems) - Update Immich with photo library access (photos.fig.systems) - Set up Sonarr for TV automation (sonarr.fig.systems) - Set up Radarr for movie automation (radarr.fig.systems) - Configure SABnzbd for Usenet downloads (sabnzbd.fig.systems) - Add qBittorrent for torrent downloads (qbt.fig.systems) Utility Services: - Update Linkwarden with proper networking (links.fig.systems) - Configure Vikunja task management (tasks.fig.systems) - Set up LubeLogger vehicle tracking (garage.fig.systems) - Configure Calibre-web for ebooks (books.fig.systems) - Add Booklore for book tracking (booklore.fig.systems) - Update FreshRSS reader (rss.fig.systems) - Update RSSHub with internal networking (rsshub.fig.systems) - Update MicroBin pastebin (paste.fig.systems) - Add File Browser for media access (files.fig.systems) Technical Improvements: - Standardize all compose files to compose.yaml (Docker best practice) - Add Traefik labels to all services for SSL termination - Implement proper network isolation (homelab + service-specific networks) - Add health checks to database services - Configure dual domain support (fig.systems + edfig.dev) - Set proper /media folder mappings for all media services - Add comprehensive README with deployment instructions Security: - Enable SSO via Tinyauth for most services - Configure LLDAP with admin user (edfig/admin@edfig.dev) - Services with built-in auth have SSO disabled by default - All traffic secured with automatic Let's Encrypt certificates
This commit is contained in:
parent
cae18a8dba
commit
fd48fed9d8
32 changed files with 921 additions and 306 deletions
219
README.md
219
README.md
|
|
@ -1,3 +1,218 @@
|
|||
# Homelab - Containers
|
||||
# Homelab GitOps Configuration
|
||||
|
||||
This repo contains container related items for deployment in my homelab
|
||||
This repository contains Docker Compose configurations for self-hosted home services.
|
||||
|
||||
## 🏗️ Infrastructure
|
||||
|
||||
### Core Services (Port 80/443)
|
||||
- **Traefik** - Reverse proxy with automatic Let's Encrypt SSL
|
||||
- **LLDAP** - Lightweight LDAP server for user management
|
||||
- Admin: `edfig` (admin@edfig.dev)
|
||||
- Web UI: https://lldap.fig.systems
|
||||
- **Tinyauth** - SSO authentication via Traefik forward auth
|
||||
- Connected to LLDAP for user authentication
|
||||
- Web UI: https://auth.fig.systems
|
||||
|
||||
## 📁 Directory Structure
|
||||
|
||||
```
|
||||
compose/
|
||||
├── core/ # Infrastructure services
|
||||
│ ├── traefik/ # Reverse proxy & SSL
|
||||
│ ├── lldap/ # LDAP user directory
|
||||
│ └── tinyauth/ # SSO authentication
|
||||
├── media/ # Media services
|
||||
│ ├── frontend/ # Media frontends
|
||||
│ │ ├── jellyfin/ # Media server (flix.fig.systems)
|
||||
│ │ ├── jellyseer/ # Request management (requests.fig.systems)
|
||||
│ │ └── immich/ # Photo management (photos.fig.systems)
|
||||
│ └── automation/ # Media automation
|
||||
│ ├── sonarr/ # TV show management
|
||||
│ ├── radarr/ # Movie management
|
||||
│ ├── sabnzbd/ # Usenet downloader
|
||||
│ └── qbittorrent/# Torrent client
|
||||
└── services/ # Utility services
|
||||
├── linkwarden/ # Bookmark manager (links.fig.systems)
|
||||
├── vikunja/ # Task management (tasks.fig.systems)
|
||||
├── lubelogger/ # Vehicle tracker (garage.fig.systems)
|
||||
├── calibre-web/ # Ebook library (books.fig.systems)
|
||||
├── booklore/ # Book tracking (booklore.fig.systems)
|
||||
├── FreshRSS/ # RSS reader (rss.fig.systems)
|
||||
├── rsshub/ # RSS feed generator (rsshub.fig.systems)
|
||||
├── microbin/ # Pastebin (paste.fig.systems)
|
||||
└── filebrowser/ # File manager (files.fig.systems)
|
||||
```
|
||||
|
||||
## 🌐 Domains
|
||||
|
||||
All services are accessible via:
|
||||
- Primary: `*.fig.systems`
|
||||
- Secondary: `*.edfig.dev`
|
||||
|
||||
### Service URLs
|
||||
|
||||
| Service | URL | SSO Protected |
|
||||
|---------|-----|---------------|
|
||||
| Traefik Dashboard | traefik.fig.systems | ✅ |
|
||||
| LLDAP | lldap.fig.systems | ✅ |
|
||||
| Tinyauth | auth.fig.systems | ❌ |
|
||||
| Jellyfin | flix.fig.systems | ❌* |
|
||||
| Jellyseerr | requests.fig.systems | ✅ |
|
||||
| Immich | photos.fig.systems | ❌* |
|
||||
| Sonarr | sonarr.fig.systems | ✅ |
|
||||
| Radarr | radarr.fig.systems | ✅ |
|
||||
| SABnzbd | sabnzbd.fig.systems | ✅ |
|
||||
| qBittorrent | qbt.fig.systems | ✅ |
|
||||
| Linkwarden | links.fig.systems | ✅ |
|
||||
| Vikunja | tasks.fig.systems | ✅ |
|
||||
| LubeLogger | garage.fig.systems | ✅ |
|
||||
| Calibre-web | books.fig.systems | ✅ |
|
||||
| Booklore | booklore.fig.systems | ✅ |
|
||||
| FreshRSS | rss.fig.systems | ✅ |
|
||||
| RSSHub | rsshub.fig.systems | ❌* |
|
||||
| MicroBin | paste.fig.systems | ❌* |
|
||||
| File Browser | files.fig.systems | ✅ |
|
||||
|
||||
*Services marked with ❌* have their own authentication systems
|
||||
|
||||
## 📦 Media Folder Structure
|
||||
|
||||
The VM should have `/media` mounted at the root with this structure:
|
||||
|
||||
```
|
||||
/media/
|
||||
├── audiobooks/
|
||||
├── books/
|
||||
├── comics/
|
||||
├── complete/ # Completed downloads
|
||||
├── downloads/ # Active downloads
|
||||
├── homemovies/
|
||||
├── incomplete/ # Incomplete downloads
|
||||
├── movies/
|
||||
├── music/
|
||||
├── photos/
|
||||
└── tv/
|
||||
```
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **DNS Configuration**: Point `*.fig.systems` and `*.edfig.dev` to your server IP
|
||||
2. **Media Folders**: Ensure `/media` is mounted with the folder structure above
|
||||
3. **Docker Network**: Create the homelab network
|
||||
|
||||
```bash
|
||||
docker network create homelab
|
||||
```
|
||||
|
||||
### Deployment Order
|
||||
|
||||
1. **Core Infrastructure** (must be first):
|
||||
```bash
|
||||
cd compose/core/traefik && docker compose up -d
|
||||
cd compose/core/lldap && docker compose up -d
|
||||
cd compose/core/tinyauth && docker compose up -d
|
||||
```
|
||||
|
||||
2. **Configure LLDAP**:
|
||||
- Visit https://lldap.fig.systems
|
||||
- Login with admin credentials from `.env`
|
||||
- Create an observer user for tinyauth
|
||||
- Add regular users for authentication
|
||||
|
||||
3. **Update Passwords**:
|
||||
- Update `LLDAP_LDAP_USER_PASS` in `core/lldap/.env`
|
||||
- Update `LDAP_BIND_PASSWORD` in `core/tinyauth/.env` to match
|
||||
- Update `SESSION_SECRET` in `core/tinyauth/.env`
|
||||
- Update database passwords in service `.env` files
|
||||
|
||||
4. **Deploy Services**:
|
||||
```bash
|
||||
# Media frontend
|
||||
cd compose/media/frontend/jellyfin && docker compose up -d
|
||||
cd compose/media/frontend/jellyseer && docker compose up -d
|
||||
cd compose/media/frontend/immich && docker compose up -d
|
||||
|
||||
# Media automation
|
||||
cd compose/media/automation/sonarr && docker compose up -d
|
||||
cd compose/media/automation/radarr && docker compose up -d
|
||||
cd compose/media/automation/sabnzbd && docker compose up -d
|
||||
cd compose/media/automation/qbittorrent && docker compose up -d
|
||||
|
||||
# Utility services
|
||||
cd compose/services/linkwarden && docker compose up -d
|
||||
cd compose/services/vikunja && docker compose up -d
|
||||
cd compose/services/lubelogger && docker compose up -d
|
||||
cd compose/services/calibre-web && docker compose up -d
|
||||
cd compose/services/booklore && docker compose up -d
|
||||
cd compose/services/FreshRSS && docker compose up -d
|
||||
cd compose/services/rsshub && docker compose up -d
|
||||
cd compose/services/microbin && docker compose up -d
|
||||
cd compose/services/filebrowser && docker compose up -d
|
||||
```
|
||||
|
||||
## 🔐 Security Considerations
|
||||
|
||||
1. **Change Default Passwords**: All `.env` files contain placeholder passwords marked with `changeme_*`
|
||||
2. **LLDAP Observer User**: Create a readonly user in LLDAP for tinyauth to bind
|
||||
3. **SSL Certificates**: Traefik automatically obtains Let's Encrypt certificates
|
||||
4. **Network Isolation**: Services use internal networks for database/cache communication
|
||||
5. **SSO**: Most services are protected by tinyauth forward authentication
|
||||
|
||||
## 📝 Configuration Files
|
||||
|
||||
Each service has its own `.env` file where applicable. Key files to review:
|
||||
|
||||
- `core/lldap/.env` - LDAP configuration and admin credentials
|
||||
- `core/tinyauth/.env` - LDAP connection and session settings
|
||||
- `media/frontend/immich/.env` - Photo management configuration
|
||||
- `services/linkwarden/.env` - Bookmark manager settings
|
||||
- `services/microbin/.env` - Pastebin configuration
|
||||
|
||||
## 🔧 Maintenance
|
||||
|
||||
### Viewing Logs
|
||||
```bash
|
||||
cd compose/[category]/[service]
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
### Updating Services
|
||||
```bash
|
||||
cd compose/[category]/[service]
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Backing Up Data
|
||||
Important data locations:
|
||||
- LLDAP: `compose/core/lldap/data/`
|
||||
- Service configs: `compose/*/*/config/`
|
||||
- Databases: `compose/*/*/db/` or `compose/*/*/pgdata/`
|
||||
- Media: `/media/` (handle separately)
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Service won't start
|
||||
1. Check logs: `docker compose logs`
|
||||
2. Verify network exists: `docker network ls | grep homelab`
|
||||
3. Check port conflicts: `docker ps -a`
|
||||
|
||||
### SSL certificate issues
|
||||
1. Verify DNS points to your server
|
||||
2. Check Traefik logs: `cd compose/core/traefik && docker compose logs`
|
||||
3. Ensure ports 80 and 443 are open
|
||||
|
||||
### SSO not working
|
||||
1. Verify tinyauth is running: `docker ps | grep tinyauth`
|
||||
2. Check LLDAP connection in tinyauth logs
|
||||
3. Verify LDAP bind credentials match in both services
|
||||
|
||||
## 📄 License
|
||||
|
||||
This is a personal homelab configuration. Use at your own risk.
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
This is a personal repository, but feel free to use it as a reference for your own homelab!
|
||||
|
|
|
|||
25
compose/core/lldap/.env
Normal file
25
compose/core/lldap/.env
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# LLDAP Configuration
|
||||
# Base DN for the LDAP directory
|
||||
LLDAP_LDAP_BASE_DN=dc=fig,dc=systems
|
||||
|
||||
# Admin user configuration
|
||||
LLDAP_LDAP_USER_DN=admin
|
||||
LLDAP_LDAP_USER_EMAIL=admin@edfig.dev
|
||||
LLDAP_LDAP_USER_PASS=changeme_please_set_secure_password
|
||||
|
||||
# JWT secret for session management (change this!)
|
||||
LLDAP_JWT_SECRET=changeme_please_set_random_secret
|
||||
|
||||
# Database URL (SQLite by default)
|
||||
LLDAP_DATABASE_URL=sqlite:///data/users.db
|
||||
|
||||
# Timezone
|
||||
TZ=America/New_York
|
||||
|
||||
# Optional: SMTP configuration for password reset emails
|
||||
# LLDAP_SMTP_OPTIONS__SERVER=smtp.gmail.com
|
||||
# LLDAP_SMTP_OPTIONS__PORT=587
|
||||
# LLDAP_SMTP_OPTIONS__SMTP_ENCRYPTION=STARTTLS
|
||||
# LLDAP_SMTP_OPTIONS__USER=your-email@gmail.com
|
||||
# LLDAP_SMTP_OPTIONS__PASSWORD=your-app-password
|
||||
# LLDAP_SMTP_OPTIONS__FROM=LLDAP Admin <admin@edfig.dev>
|
||||
24
compose/core/lldap/compose.yaml
Normal file
24
compose/core/lldap/compose.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
services:
|
||||
lldap:
|
||||
container_name: lldap
|
||||
image: lldap/lldap:stable
|
||||
ports:
|
||||
- "3890:3890" # LDAP
|
||||
- "17170:17170" # Web UI
|
||||
env_file: .env
|
||||
volumes:
|
||||
- ./data:/data
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.lldap.rule: Host(`lldap.fig.systems`) || Host(`lldap.edfig.dev`)
|
||||
traefik.http.routers.lldap.entrypoints: websecure
|
||||
traefik.http.routers.lldap.tls.certresolver: letsencrypt
|
||||
traefik.http.services.lldap.loadbalancer.server.port: 17170
|
||||
traefik.http.routers.lldap.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,7 +1,27 @@
|
|||
TZ=America/Los_Angeles
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
# Tinyauth Configuration
|
||||
|
||||
MYSQL_DATABASE=librenms
|
||||
MYSQL_USER=librenms
|
||||
MYSQL_PASSWORD=asupersecretpassword
|
||||
# App URL - publicly accessible URL
|
||||
APP_URL=https://auth.fig.systems
|
||||
|
||||
# Timezone
|
||||
TZ=America/Los_Angeles
|
||||
|
||||
# LDAP Configuration - Connect to LLDAP
|
||||
LDAP_ADDRESS=ldap://lldap:3890
|
||||
LDAP_BASE_DN=dc=fig,dc=systems
|
||||
LDAP_BIND_DN=uid=admin,ou=people,dc=fig,dc=systems
|
||||
LDAP_BIND_PASSWORD=changeme_please_set_secure_password
|
||||
LDAP_SEARCH_FILTER=(uid=%s)
|
||||
LDAP_INSECURE=true
|
||||
|
||||
# Optional: Local users (if you want fallback auth)
|
||||
# Format: username:bcrypt_hash:totp_secret (totp_secret is optional)
|
||||
# Generate hash with: docker run --rm -it ghcr.io/steveiliop56/tinyauth:latest hash <password>
|
||||
# USERS=
|
||||
|
||||
# Session configuration
|
||||
SESSION_SECRET=changeme_please_set_random_session_secret
|
||||
SESSION_MAX_AGE=86400
|
||||
|
||||
# Database (optional, uses SQLite by default at /data/tinyauth.db)
|
||||
# DATABASE_URL=sqlite:///data/tinyauth.db
|
||||
|
|
|
|||
|
|
@ -1,54 +1,26 @@
|
|||
services:
|
||||
traefik:
|
||||
container_name: traefik
|
||||
image: traefik:v3.3
|
||||
command: --api.insecure=true --providers.docker
|
||||
ports:
|
||||
- 80:80
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
whoami:
|
||||
container_name: whoami
|
||||
image: traefik/whoami:latest
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.whoami.rule: Host(`whoami.example.com`)
|
||||
traefik.http.routers.whoami.middlewares: tinyauth
|
||||
|
||||
tinyauth-frontend:
|
||||
container_name: tinyauth-frontend
|
||||
build:
|
||||
context: .
|
||||
dockerfile: frontend/Dockerfile.dev
|
||||
volumes:
|
||||
- ./frontend/src:/frontend/src
|
||||
ports:
|
||||
- 5173:5173
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.tinyauth.rule: Host(`tinyauth.example.com`)
|
||||
|
||||
tinyauth-backend:
|
||||
container_name: tinyauth-backend
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
args:
|
||||
- VERSION=development
|
||||
- COMMIT_HASH=development
|
||||
- BUILD_TIMESTAMP=000-00-00T00:00:00Z
|
||||
tinyauth:
|
||||
container_name: tinyauth
|
||||
image: ghcr.io/steveiliop56/tinyauth:latest
|
||||
env_file: .env
|
||||
volumes:
|
||||
- ./internal:/tinyauth/internal
|
||||
- ./cmd:/tinyauth/cmd
|
||||
- ./main.go:/tinyauth/main.go
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./data:/data
|
||||
ports:
|
||||
- 3000:3000
|
||||
- 4000:4000
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth-backend:3000/api/auth/traefik
|
||||
# Web UI routing
|
||||
traefik.http.routers.tinyauth.rule: Host(`auth.fig.systems`) || Host(`auth.edfig.dev`)
|
||||
traefik.http.routers.tinyauth.entrypoints: websecure
|
||||
traefik.http.routers.tinyauth.tls.certresolver: letsencrypt
|
||||
traefik.http.routers.tinyauth.service: tinyauth-ui
|
||||
traefik.http.services.tinyauth-ui.loadbalancer.server.port: 3000
|
||||
# Forward Auth Middleware
|
||||
traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth/traefik
|
||||
traefik.http.middlewares.tinyauth.forwardauth.trustforwardheader: true
|
||||
traefik.http.middlewares.tinyauth.forwardauth.authresponseheaders: X-Forwarded-User
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
|
|||
46
compose/core/traefik/compose.yaml
Normal file
46
compose/core/traefik/compose.yaml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
services:
|
||||
traefik:
|
||||
container_name: traefik
|
||||
image: traefik:v3.3
|
||||
command:
|
||||
# API Settings
|
||||
- --api.dashboard=true
|
||||
# Provider Settings
|
||||
- --providers.docker=true
|
||||
- --providers.docker.exposedbydefault=false
|
||||
- --providers.docker.network=homelab
|
||||
# Entrypoints
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.websecure.address=:443
|
||||
# HTTP to HTTPS redirect
|
||||
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||
- --entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||
# Let's Encrypt Certificate Resolver
|
||||
- --certificatesresolvers.letsencrypt.acme.email=admin@edfig.dev
|
||||
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
|
||||
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
|
||||
# Logging
|
||||
- --log.level=INFO
|
||||
- --accesslog=true
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ./letsencrypt:/letsencrypt
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
# Dashboard routing
|
||||
traefik.http.routers.traefik.rule: Host(`traefik.fig.systems`) || Host(`traefik.edfig.dev`)
|
||||
traefik.http.routers.traefik.entrypoints: websecure
|
||||
traefik.http.routers.traefik.tls.certresolver: letsencrypt
|
||||
traefik.http.routers.traefik.service: api@internal
|
||||
traefik.http.routers.traefik.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
name: homelab
|
||||
driver: bridge
|
||||
34
compose/media/automation/qbittorrent/compose.yaml
Normal file
34
compose/media/automation/qbittorrent/compose.yaml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# qBittorrent - Bittorrent client with WebUI
|
||||
# Docs: https://docs.linuxserver.io/images/docker-qbittorrent/
|
||||
|
||||
services:
|
||||
qbittorrent:
|
||||
container_name: qbittorrent
|
||||
image: lscr.io/linuxserver/qbittorrent:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- WEBUI_PORT=8080
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/downloads:/downloads
|
||||
- /media/complete:/complete
|
||||
- /media/incomplete:/incomplete
|
||||
ports:
|
||||
- "6881:6881" # BitTorrent port
|
||||
- "6881:6881/udp" # BitTorrent DHT
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.qbittorrent.rule: Host(`qbt.fig.systems`) || Host(`qbt.edfig.dev`)
|
||||
traefik.http.routers.qbittorrent.entrypoints: websecure
|
||||
traefik.http.routers.qbittorrent.tls.certresolver: letsencrypt
|
||||
traefik.http.services.qbittorrent.loadbalancer.server.port: 8080
|
||||
traefik.http.routers.qbittorrent.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
33
compose/media/automation/radarr/compose.yaml
Normal file
33
compose/media/automation/radarr/compose.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Radarr - Movie Management and Automation
|
||||
# Docs: https://wiki.servarr.com/radarr
|
||||
|
||||
services:
|
||||
radarr:
|
||||
container_name: radarr
|
||||
image: lscr.io/linuxserver/radarr:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
# Media library
|
||||
- /media/movies:/media/movies
|
||||
# Download folders
|
||||
- /media/downloads:/downloads
|
||||
- /media/complete:/complete
|
||||
- /media/incomplete:/incomplete
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.radarr.rule: Host(`radarr.fig.systems`) || Host(`radarr.edfig.dev`)
|
||||
traefik.http.routers.radarr.entrypoints: websecure
|
||||
traefik.http.routers.radarr.tls.certresolver: letsencrypt
|
||||
traefik.http.services.radarr.loadbalancer.server.port: 7878
|
||||
traefik.http.routers.radarr.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
services:
|
||||
radarr:
|
||||
image:
|
||||
container_name: radarr
|
||||
restart: unless-stopped
|
||||
# ports:
|
||||
# - ":"
|
||||
# volumes:
|
||||
# - ./data:/data
|
||||
# environment:
|
||||
# - VARIABLE=value
|
||||
30
compose/media/automation/sabnzbd/compose.yaml
Normal file
30
compose/media/automation/sabnzbd/compose.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# SABnzbd - Usenet binary newsreader
|
||||
# Docs: https://docs.linuxserver.io/images/docker-sabnzbd/
|
||||
|
||||
services:
|
||||
sabnzbd:
|
||||
container_name: sabnzbd
|
||||
image: lscr.io/linuxserver/sabnzbd:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/downloads:/downloads
|
||||
- /media/complete:/complete
|
||||
- /media/incomplete:/incomplete
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.sabnzbd.rule: Host(`sabnzbd.fig.systems`) || Host(`sabnzbd.edfig.dev`)
|
||||
traefik.http.routers.sabnzbd.entrypoints: websecure
|
||||
traefik.http.routers.sabnzbd.tls.certresolver: letsencrypt
|
||||
traefik.http.services.sabnzbd.loadbalancer.server.port: 8080
|
||||
traefik.http.routers.sabnzbd.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
services:
|
||||
sabnzbd:
|
||||
image:
|
||||
container_name: sabnzbd
|
||||
restart: unless-stopped
|
||||
# ports:
|
||||
# - ":"
|
||||
# volumes:
|
||||
# - ./data:/data
|
||||
# environment:
|
||||
# - VARIABLE=value
|
||||
33
compose/media/automation/sonarr/compose.yaml
Normal file
33
compose/media/automation/sonarr/compose.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Sonarr - TV Show Management and Automation
|
||||
# Docs: https://wiki.servarr.com/sonarr
|
||||
|
||||
services:
|
||||
sonarr:
|
||||
container_name: sonarr
|
||||
image: lscr.io/linuxserver/sonarr:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
# Media library
|
||||
- /media/tv:/media/tv
|
||||
# Download folders
|
||||
- /media/downloads:/downloads
|
||||
- /media/complete:/complete
|
||||
- /media/incomplete:/incomplete
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.sonarr.rule: Host(`sonarr.fig.systems`) || Host(`sonarr.edfig.dev`)
|
||||
traefik.http.routers.sonarr.entrypoints: websecure
|
||||
traefik.http.routers.sonarr.tls.certresolver: letsencrypt
|
||||
traefik.http.services.sonarr.loadbalancer.server.port: 8989
|
||||
traefik.http.routers.sonarr.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
services:
|
||||
sonarr:
|
||||
image:
|
||||
container_name: sonarr
|
||||
restart: unless-stopped
|
||||
# ports:
|
||||
# - ":"
|
||||
# volumes:
|
||||
# - ./data:/data
|
||||
# environment:
|
||||
# - VARIABLE=value
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#
|
||||
# Immich - Self-hosted photo and video management
|
||||
# WARNING: To install Immich, follow our guide: https://docs.immich.app/install/docker-compose
|
||||
#
|
||||
# Make sure to use the docker-compose.yml of the current release:
|
||||
|
|
@ -21,6 +22,8 @@ services:
|
|||
# Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
|
||||
- ${UPLOAD_LOCATION}:/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
# External photo library (optional - can be imported into Immich)
|
||||
- /media/photos:/media/photos:ro
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
|
|
@ -29,8 +32,20 @@ services:
|
|||
- redis
|
||||
- database
|
||||
restart: always
|
||||
networks:
|
||||
- homelab
|
||||
- immich_internal
|
||||
healthcheck:
|
||||
disable: false
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: homelab
|
||||
traefik.http.routers.immich.rule: Host(`photos.fig.systems`) || Host(`photos.edfig.dev`)
|
||||
traefik.http.routers.immich.entrypoints: websecure
|
||||
traefik.http.routers.immich.tls.certresolver: letsencrypt
|
||||
traefik.http.services.immich.loadbalancer.server.port: 2283
|
||||
# Optional: Enable SSO (note: Immich has its own user management)
|
||||
# traefik.http.routers.immich.middlewares: tinyauth
|
||||
|
||||
immich-machine-learning:
|
||||
container_name: immich_machine_learning
|
||||
|
|
@ -45,6 +60,8 @@ services:
|
|||
env_file:
|
||||
- .env
|
||||
restart: always
|
||||
networks:
|
||||
- immich_internal
|
||||
healthcheck:
|
||||
disable: false
|
||||
|
||||
|
|
@ -54,6 +71,8 @@ services:
|
|||
healthcheck:
|
||||
test: redis-cli ping || exit 1
|
||||
restart: always
|
||||
networks:
|
||||
- immich_internal
|
||||
|
||||
database:
|
||||
container_name: immich_postgres
|
||||
|
|
@ -70,6 +89,15 @@ services:
|
|||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||
shm_size: 128mb
|
||||
restart: always
|
||||
networks:
|
||||
- immich_internal
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
immich_internal:
|
||||
name: immich_internal
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
model-cache:
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
services:
|
||||
immich:
|
||||
image:
|
||||
container_name: immich
|
||||
restart: unless-stopped
|
||||
# ports:
|
||||
# - ":"
|
||||
# volumes:
|
||||
# - ./data:/data
|
||||
# environment:
|
||||
# - VARIABLE=value
|
||||
|
|
@ -1,42 +1,50 @@
|
|||
# Compose Docs:
|
||||
# https://jellyfin.org/docs/general/installation/container/?method=docker-compose
|
||||
# Transcoding Docs
|
||||
# https://jellyfin.org/docs/general/post-install/transcoding/hardware-acceleration/nvidia
|
||||
# Jellyfin Media Server
|
||||
# Docs: https://jellyfin.org/docs/general/installation/container/?method=docker-compose
|
||||
# Transcoding: https://jellyfin.org/docs/general/post-install/transcoding/hardware-acceleration/nvidia
|
||||
|
||||
services:
|
||||
jellyfin:
|
||||
image: jellyfin/jellyfin
|
||||
container_name: jellyfin
|
||||
user: uid:gid
|
||||
ports:
|
||||
- 8096:8096/tcp
|
||||
- 7359:7359/udp
|
||||
volumes:
|
||||
- /path/to/config:/config
|
||||
- /path/to/cache:/cache
|
||||
- type: bind
|
||||
source: /path/to/media
|
||||
target: /media
|
||||
- type: bind
|
||||
source: /path/to/media2
|
||||
target: /media2
|
||||
read_only: true
|
||||
# Optional - extra fonts to be used during transcoding with subtitle burn-in
|
||||
- type: bind
|
||||
source: /path/to/fonts
|
||||
target: /usr/local/share/fonts/custom
|
||||
read_only: true
|
||||
restart: 'unless-stopped'
|
||||
# Optional - alternative address used for autodiscovery
|
||||
image: lscr.io/linuxserver/jellyfin:latest
|
||||
environment:
|
||||
- JELLYFIN_PublishedServerUrl=http://example.com
|
||||
# Optional - may be necessary for docker healthcheck to pass if running in host network mode
|
||||
extra_hosts:
|
||||
- 'host.docker.internal:host-gateway'
|
||||
runtime: nvidia
|
||||
deploy:
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: all
|
||||
capabilities: [gpu]
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- JELLYFIN_PublishedServerUrl=https://flix.fig.systems
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- ./cache:/cache
|
||||
# Media folders (read-only)
|
||||
- /media/movies:/media/movies:ro
|
||||
- /media/tv:/media/tv:ro
|
||||
- /media/music:/media/music:ro
|
||||
- /media/photos:/media/photos:ro
|
||||
- /media/homemovies:/media/homemovies:ro
|
||||
ports:
|
||||
- "8096:8096"
|
||||
- "7359:7359/udp" # Optional - for autodiscovery
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.jellyfin.rule: Host(`flix.fig.systems`) || Host(`flix.edfig.dev`)
|
||||
traefik.http.routers.jellyfin.entrypoints: websecure
|
||||
traefik.http.routers.jellyfin.tls.certresolver: letsencrypt
|
||||
traefik.http.services.jellyfin.loadbalancer.server.port: 8096
|
||||
# Note: Jellyfin has its own auth system, SSO middleware disabled by default
|
||||
# Uncomment the line below to enable SSO (requires users to auth via tinyauth first)
|
||||
# traefik.http.routers.jellyfin.middlewares: tinyauth
|
||||
# Uncomment for NVIDIA GPU transcoding
|
||||
# runtime: nvidia
|
||||
# deploy:
|
||||
# resources:
|
||||
# reservations:
|
||||
# devices:
|
||||
# - driver: nvidia
|
||||
# count: all
|
||||
# capabilities: [gpu]
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
|
|||
28
compose/media/frontend/jellyseer/compose.yaml
Normal file
28
compose/media/frontend/jellyseer/compose.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Jellyseerr - Media Request Management for Jellyfin
|
||||
# Docs: https://hub.docker.com/r/fallenbagel/jellyseerr
|
||||
|
||||
services:
|
||||
jellyseerr:
|
||||
container_name: jellyseerr
|
||||
image: fallenbagel/jellyseerr:latest
|
||||
environment:
|
||||
- LOG_LEVEL=info
|
||||
- TZ=America/Los_Angeles
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
volumes:
|
||||
- ./config:/app/config
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.jellyseerr.rule: Host(`requests.fig.systems`) || Host(`requests.edfig.dev`)
|
||||
traefik.http.routers.jellyseerr.entrypoints: websecure
|
||||
traefik.http.routers.jellyseerr.tls.certresolver: letsencrypt
|
||||
traefik.http.services.jellyseerr.loadbalancer.server.port: 5055
|
||||
traefik.http.routers.jellyseerr.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# https://hub.docker.com/r/fallenbagel/jellyseerr
|
||||
services:
|
||||
jellyseerr:
|
||||
image: fallenbagel/jellyseerr:latest
|
||||
container_name: jellyseerr
|
||||
environment:
|
||||
- LOG_LEVEL=debug
|
||||
- TZ=America/Los_Angeles
|
||||
ports:
|
||||
- 8002:5055
|
||||
volumes:
|
||||
- /path/to/appdata/config:/app/config
|
||||
restart: unless-stopped
|
||||
|
||||
27
compose/services/FreshRSS/compose.yaml
Normal file
27
compose/services/FreshRSS/compose.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# FreshRSS - Self-hosted RSS feed aggregator
|
||||
# Docs: https://docs.linuxserver.io/images/docker-freshrss/
|
||||
|
||||
services:
|
||||
freshrss:
|
||||
container_name: freshrss
|
||||
image: lscr.io/linuxserver/freshrss:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.freshrss.rule: Host(`rss.fig.systems`) || Host(`rss.edfig.dev`)
|
||||
traefik.http.routers.freshrss.entrypoints: websecure
|
||||
traefik.http.routers.freshrss.tls.certresolver: letsencrypt
|
||||
traefik.http.services.freshrss.loadbalancer.server.port: 80
|
||||
traefik.http.routers.freshrss.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# https://docs.linuxserver.io/images/docker-freshrss/
|
||||
---
|
||||
services:
|
||||
freshrss:
|
||||
image: lscr.io/linuxserver/freshrss:latest
|
||||
container_name: freshrss
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
volumes:
|
||||
- /path/to/freshrss/config:/config
|
||||
ports:
|
||||
- 8000:80
|
||||
restart: unless-stopped
|
||||
28
compose/services/booklore/compose.yaml
Normal file
28
compose/services/booklore/compose.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Booklore - Book tracking and management
|
||||
# Docs: https://github.com/lorebooks/booklore
|
||||
|
||||
services:
|
||||
booklore:
|
||||
container_name: booklore
|
||||
image: ghcr.io/lorebooks/booklore:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/books:/books:ro
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.booklore.rule: Host(`booklore.fig.systems`) || Host(`booklore.edfig.dev`)
|
||||
traefik.http.routers.booklore.entrypoints: websecure
|
||||
traefik.http.routers.booklore.tls.certresolver: letsencrypt
|
||||
traefik.http.services.booklore.loadbalancer.server.port: 3000
|
||||
traefik.http.routers.booklore.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
30
compose/services/calibre-web/compose.yaml
Normal file
30
compose/services/calibre-web/compose.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# Calibre-web - Web app for browsing, reading and downloading eBooks
|
||||
# Docs: https://hub.docker.com/r/linuxserver/calibre-web
|
||||
|
||||
services:
|
||||
calibre-web:
|
||||
container_name: calibre-web
|
||||
image: lscr.io/linuxserver/calibre-web:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- DOCKER_MODS=linuxserver/mods:universal-calibre
|
||||
- OAUTHLIB_RELAX_TOKEN_SCOPE=1
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- /media/books:/books
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.calibre-web.rule: Host(`books.fig.systems`) || Host(`books.edfig.dev`)
|
||||
traefik.http.routers.calibre-web.entrypoints: websecure
|
||||
traefik.http.routers.calibre-web.tls.certresolver: letsencrypt
|
||||
traefik.http.services.calibre-web.loadbalancer.server.port: 8083
|
||||
traefik.http.routers.calibre-web.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# https://hub.docker.com/r/linuxserver/calibre-web
|
||||
---
|
||||
services:
|
||||
calibre-web:
|
||||
image: lscr.io/linuxserver/calibre-web:latest
|
||||
container_name: calibre-web
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=Etc/UTC
|
||||
- DOCKER_MODS=linuxserver/mods:universal-calibre #optional
|
||||
- OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional
|
||||
volumes:
|
||||
- /path/to/calibre-web/data:/config
|
||||
- /path/to/calibre/library:/books
|
||||
ports:
|
||||
- 8002:8083
|
||||
restart: unless-stopped
|
||||
|
||||
29
compose/services/filebrowser/compose.yaml
Normal file
29
compose/services/filebrowser/compose.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# File Browser - Web-based file manager
|
||||
# Docs: https://filebrowser.org/
|
||||
|
||||
services:
|
||||
filebrowser:
|
||||
container_name: filebrowser
|
||||
image: filebrowser/filebrowser:latest
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./config:/config
|
||||
- ./database:/database
|
||||
- /media:/srv
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.filebrowser.rule: Host(`files.fig.systems`) || Host(`files.edfig.dev`)
|
||||
traefik.http.routers.filebrowser.entrypoints: websecure
|
||||
traefik.http.routers.filebrowser.tls.certresolver: letsencrypt
|
||||
traefik.http.services.filebrowser.loadbalancer.server.port: 80
|
||||
traefik.http.routers.filebrowser.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
services:
|
||||
filebrowser:
|
||||
image:
|
||||
container_name: filebrowser
|
||||
restart: unless-stopped
|
||||
# ports:
|
||||
# - ":"
|
||||
# volumes:
|
||||
# - ./data:/data
|
||||
# environment:
|
||||
# - VARIABLE=value
|
||||
|
|
@ -1,29 +1,64 @@
|
|||
# https://docs.linkwarden.app/self-hosting/installation
|
||||
# Linkwarden - Collaborative bookmark manager
|
||||
# Docs: https://docs.linkwarden.app/self-hosting/installation
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
env_file: .env
|
||||
restart: always
|
||||
volumes:
|
||||
- ./pgdata:/var/lib/postgresql/data
|
||||
linkwarden:
|
||||
container_name: linkwarden
|
||||
image: ghcr.io/linkwarden/linkwarden:latest
|
||||
env_file: .env
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres
|
||||
restart: always
|
||||
# build: . # uncomment to build from source
|
||||
image: ghcr.io/linkwarden/linkwarden:latest # comment to build from source
|
||||
ports:
|
||||
- 3000:3000
|
||||
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@linkwarden-postgres:5432/postgres
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./data:/data/data
|
||||
depends_on:
|
||||
- postgres
|
||||
- meilisearch
|
||||
meilisearch:
|
||||
image: getmeili/meilisearch:v1.12.8
|
||||
- linkwarden-postgres
|
||||
- linkwarden-meilisearch
|
||||
restart: always
|
||||
env_file:
|
||||
- .env
|
||||
networks:
|
||||
- homelab
|
||||
- linkwarden_internal
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: homelab
|
||||
traefik.http.routers.linkwarden.rule: Host(`links.fig.systems`) || Host(`links.edfig.dev`)
|
||||
traefik.http.routers.linkwarden.entrypoints: websecure
|
||||
traefik.http.routers.linkwarden.tls.certresolver: letsencrypt
|
||||
traefik.http.services.linkwarden.loadbalancer.server.port: 3000
|
||||
traefik.http.routers.linkwarden.middlewares: tinyauth
|
||||
|
||||
linkwarden-postgres:
|
||||
container_name: linkwarden-postgres
|
||||
image: postgres:16-alpine
|
||||
env_file: .env
|
||||
environment:
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./pgdata:/var/lib/postgresql/data
|
||||
restart: always
|
||||
networks:
|
||||
- linkwarden_internal
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -h localhost -U postgres"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
linkwarden-meilisearch:
|
||||
container_name: linkwarden-meilisearch
|
||||
image: getmeili/meilisearch:v1.12.8
|
||||
env_file: .env
|
||||
environment:
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- ./meili_data:/meili_data
|
||||
restart: always
|
||||
networks:
|
||||
- linkwarden_internal
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
linkwarden_internal:
|
||||
name: linkwarden_internal
|
||||
driver: bridge
|
||||
|
|
|
|||
30
compose/services/lubelogger/compose.yaml
Normal file
30
compose/services/lubelogger/compose.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# LubeLogger - Vehicle maintenance and fuel tracking
|
||||
# Docs: https://github.com/hargata/lubelogger
|
||||
|
||||
services:
|
||||
lubelogger:
|
||||
container_name: lubelogger
|
||||
image: ghcr.io/hargata/lubelogger:latest
|
||||
environment:
|
||||
- TZ=America/Los_Angeles
|
||||
volumes:
|
||||
- data:/App/data
|
||||
- keys:/root/.aspnet/DataProtection-Keys
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.lubelogger.rule: Host(`garage.fig.systems`) || Host(`garage.edfig.dev`)
|
||||
traefik.http.routers.lubelogger.entrypoints: websecure
|
||||
traefik.http.routers.lubelogger.tls.certresolver: letsencrypt
|
||||
traefik.http.services.lubelogger.loadbalancer.server.port: 8080
|
||||
traefik.http.routers.lubelogger.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
data:
|
||||
keys:
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
|
||||
services:
|
||||
app:
|
||||
image: ghcr.io/hargata/lubelogger:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- data:/App/data
|
||||
- keys:/root/.aspnet/DataProtection-Keys
|
||||
ports:
|
||||
- 8007:8080
|
||||
|
||||
volumes:
|
||||
data:
|
||||
keys:
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
# MicroBin - Encrypted pastebin with file upload support
|
||||
# Docs: https://github.com/szabodanika/microbin
|
||||
|
||||
services:
|
||||
microbin:
|
||||
container_name: microbin
|
||||
image: danielszabo99/microbin:latest
|
||||
restart: always
|
||||
ports:
|
||||
- "${MICROBIN_PORT}:8080"
|
||||
volumes:
|
||||
- ./microbin-data:/app/microbin_data
|
||||
env_file: .env
|
||||
environment:
|
||||
MICROBIN_BASIC_AUTH_USERNAME: ${MICROBIN_BASIC_AUTH_USERNAME}
|
||||
MICROBIN_BASIC_AUTH_PASSWORD: ${MICROBIN_BASIC_AUTH_PASSWORD}
|
||||
|
|
@ -45,4 +45,20 @@ services:
|
|||
MICROBIN_ENCRYPTION_SERVER_SIDE: ${MICROBIN_ENCRYPTION_SERVER_SIDE}
|
||||
MICROBIN_MAX_FILE_SIZE_ENCRYPTED_MB: ${MICROBIN_MAX_FILE_SIZE_ENCRYPTED_MB}
|
||||
MICROBIN_MAX_FILE_SIZE_UNENCRYPTED_MB: ${MICROBIN_MAX_FILE_SIZE_UNENCRYPTED_MB}
|
||||
volumes:
|
||||
- ./microbin-data:/app/microbin_data
|
||||
restart: always
|
||||
networks:
|
||||
- homelab
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.http.routers.microbin.rule: Host(`paste.fig.systems`) || Host(`paste.edfig.dev`)
|
||||
traefik.http.routers.microbin.entrypoints: websecure
|
||||
traefik.http.routers.microbin.tls.certresolver: letsencrypt
|
||||
traefik.http.services.microbin.loadbalancer.server.port: 8080
|
||||
# Note: MicroBin has its own auth, SSO disabled by default
|
||||
# traefik.http.routers.microbin.middlewares: tinyauth
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
|
|
|
|||
|
|
@ -1,61 +1,76 @@
|
|||
# RSSHub - RSS feed generator for everything
|
||||
# Docs: https://docs.rsshub.app/
|
||||
|
||||
services:
|
||||
rsshub:
|
||||
# two ways to enable puppeteer:
|
||||
# * comment out marked lines, then use this image instead: diygod/rsshub:chromium-bundled
|
||||
# * (consumes more disk space and memory) leave everything unchanged
|
||||
container_name: rsshub
|
||||
# Using chromium-bundled image for full puppeteer support
|
||||
image: diygod/rsshub:chromium-bundled
|
||||
restart: always
|
||||
ports:
|
||||
- 1200:1200
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
CACHE_TYPE: redis
|
||||
REDIS_URL: redis://redis:6379/
|
||||
PUPPETEER_WS_ENDPOINT: ws://browserless:3000 # marked
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- curl
|
||||
- -f
|
||||
- http://localhost:1200/healthz
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
REDIS_URL: redis://rsshub-redis:6379/
|
||||
PUPPETEER_WS_ENDPOINT: ws://rsshub-browserless:3000
|
||||
TZ: America/Los_Angeles
|
||||
restart: always
|
||||
networks:
|
||||
- homelab
|
||||
- rsshub_internal
|
||||
depends_on:
|
||||
- redis
|
||||
- browserless # marked
|
||||
browserless:
|
||||
# marked
|
||||
image: browserless/chrome # marked
|
||||
restart: always # marked
|
||||
ulimits:
|
||||
# marked
|
||||
core:
|
||||
# marked
|
||||
hard: 0 # marked
|
||||
soft: 0 # marked
|
||||
- rsshub-redis
|
||||
- rsshub-browserless
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- curl
|
||||
- -f
|
||||
- http://localhost:3000/pressure
|
||||
test: ["CMD", "curl", "-f", "http://localhost:1200/healthz"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
redis:
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: homelab
|
||||
traefik.http.routers.rsshub.rule: Host(`rsshub.fig.systems`) || Host(`rsshub.edfig.dev`)
|
||||
traefik.http.routers.rsshub.entrypoints: websecure
|
||||
traefik.http.routers.rsshub.tls.certresolver: letsencrypt
|
||||
traefik.http.services.rsshub.loadbalancer.server.port: 1200
|
||||
# Optional: enable SSO (may interfere with RSS readers)
|
||||
# traefik.http.routers.rsshub.middlewares: tinyauth
|
||||
|
||||
rsshub-browserless:
|
||||
container_name: rsshub-browserless
|
||||
image: browserless/chrome
|
||||
restart: always
|
||||
networks:
|
||||
- rsshub_internal
|
||||
ulimits:
|
||||
core:
|
||||
hard: 0
|
||||
soft: 0
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000/pressure"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
rsshub-redis:
|
||||
container_name: rsshub-redis
|
||||
image: redis:alpine
|
||||
restart: always
|
||||
networks:
|
||||
- rsshub_internal
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- redis-cli
|
||||
- ping
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 5s
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
rsshub_internal:
|
||||
name: rsshub_internal
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
redis-data: null
|
||||
redis-data:
|
||||
|
|
|
|||
58
compose/services/vikunja/compose.yaml
Normal file
58
compose/services/vikunja/compose.yaml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Vikunja - The open-source, self-hostable to-do app
|
||||
# Docs: https://vikunja.io/docs/full-docker-example/
|
||||
|
||||
services:
|
||||
vikunja:
|
||||
container_name: vikunja
|
||||
image: vikunja/vikunja:latest
|
||||
environment:
|
||||
VIKUNJA_SERVICE_PUBLICURL: https://tasks.fig.systems
|
||||
VIKUNJA_DATABASE_HOST: vikunja-db
|
||||
VIKUNJA_DATABASE_PASSWORD: changeme_please_set_secure_password
|
||||
VIKUNJA_DATABASE_TYPE: postgres
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
VIKUNJA_SERVICE_JWTSECRET: changeme_please_set_random_jwt_secret
|
||||
TZ: America/Los_Angeles
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
depends_on:
|
||||
vikunja-db:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- homelab
|
||||
- vikunja_internal
|
||||
labels:
|
||||
traefik.enable: true
|
||||
traefik.docker.network: homelab
|
||||
traefik.http.routers.vikunja.rule: Host(`tasks.fig.systems`) || Host(`tasks.edfig.dev`)
|
||||
traefik.http.routers.vikunja.entrypoints: websecure
|
||||
traefik.http.routers.vikunja.tls.certresolver: letsencrypt
|
||||
traefik.http.services.vikunja.loadbalancer.server.port: 3456
|
||||
traefik.http.routers.vikunja.middlewares: tinyauth
|
||||
|
||||
vikunja-db:
|
||||
container_name: vikunja-db
|
||||
image: postgres:18
|
||||
environment:
|
||||
POSTGRES_PASSWORD: changeme_please_set_secure_password
|
||||
POSTGRES_USER: vikunja
|
||||
POSTGRES_DB: vikunja
|
||||
TZ: America/Los_Angeles
|
||||
volumes:
|
||||
- ./db:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- vikunja_internal
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"]
|
||||
interval: 2s
|
||||
start_period: 30s
|
||||
|
||||
networks:
|
||||
homelab:
|
||||
external: true
|
||||
vikunja_internal:
|
||||
name: vikunja_internal
|
||||
driver: bridge
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# https://vikunja.io/docs/full-docker-example/#example-without-any-proxy
|
||||
services:
|
||||
vikunja:
|
||||
image: vikunja/vikunja
|
||||
environment:
|
||||
VIKUNJA_SERVICE_PUBLICURL: http://<the public ip or host where Vikunja is reachable>
|
||||
VIKUNJA_DATABASE_HOST: db
|
||||
VIKUNJA_DATABASE_PASSWORD: changeme
|
||||
VIKUNJA_DATABASE_TYPE: postgres
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
VIKUNJA_SERVICE_JWTSECRET: <a super secure random secret>
|
||||
ports:
|
||||
- 3456:3456
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
db:
|
||||
image: postgres:18
|
||||
environment:
|
||||
POSTGRES_PASSWORD: changeme
|
||||
POSTGRES_USER: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"]
|
||||
interval: 2s
|
||||
start_period: 30s
|
||||
Loading…
Reference in a new issue