init
This commit is contained in:
10
.env
Normal file
10
.env
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Environment variables
|
||||||
|
TZ=Asia/Kolkata
|
||||||
|
PUID=1000
|
||||||
|
PGID=1000
|
||||||
|
MONGO_USER=aetos
|
||||||
|
MONGO_PASS=vishesh23
|
||||||
|
|
||||||
|
# Host paths for volume binds
|
||||||
|
CONFIGS_PATH=/mnt/machine-spirit/configs
|
||||||
|
DATA_PATH=/mnt/machine-spirit/data
|
40
README.md
Normal file
40
README.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Server Pi
|
||||||
|
|
||||||
|
This Raspberry Pi hosts a full media management stack for personal use. It runs multiple Dockerized services and serves as the primary server for *arr stack operations and media requests.
|
||||||
|
|
||||||
|
The main purpose of this Pi is to handle media management, indexing, and user requests via a self-hosted gateway.
|
||||||
|
|
||||||
|
The services currently running are:
|
||||||
|
|
||||||
|
- **Nginx**: Reverse proxy and main landing page for available services. It routes requests to local services and handles path and host headers.
|
||||||
|
|
||||||
|
- **Ombi**: Media request management. Accessible at `http://<server-pi-ip>:3579`.
|
||||||
|
|
||||||
|
- **Sonarr**: TV show management and automation. Accessible internally on port `8989`.
|
||||||
|
|
||||||
|
- **Radarr**: Movie management and automation. Accessible internally on port `7878`.
|
||||||
|
|
||||||
|
- **Prowlarr**: Indexer management for *arr stack. Accessible internally on port `9696`.
|
||||||
|
|
||||||
|
- **Jellyseerr**: Media request interface for Plex. Accessible internally on port `5055`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Start services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Check Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose logs -f nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exec COntainer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it <container_name> bash
|
||||||
|
```
|
||||||
|
|
182
docker-compose.yaml
Normal file
182
docker-compose.yaml
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
# Shared storage configuration
|
||||||
|
x-shared-storage: &shared_data_volume
|
||||||
|
type: bind
|
||||||
|
source: /mnt/machine-spirit/data/media-manager
|
||||||
|
target: /data
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
|
|
||||||
|
# Service-specific volume configurations
|
||||||
|
x-volume-configs:
|
||||||
|
jellyseerr: &jellyseerr_volumes
|
||||||
|
- type: bind
|
||||||
|
source: /mnt/machine-spirit/configs/jellyseerr
|
||||||
|
target: /app/config
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
|
|
||||||
|
prowlarr: &prowlarr_volumes
|
||||||
|
- type: bind
|
||||||
|
source: /mnt/machine-spirit/configs/prowlarr
|
||||||
|
target: /config
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
|
- <<: *shared_data_volume
|
||||||
|
|
||||||
|
sonarr: &sonarr_volumes
|
||||||
|
- type: bind
|
||||||
|
source: /mnt/machine-spirit/configs/sonarr
|
||||||
|
target: /config
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
|
- <<: *shared_data_volume
|
||||||
|
|
||||||
|
radarr: &radarr_volumes
|
||||||
|
- type: bind
|
||||||
|
source: /mnt/machine-spirit/configs/radarr
|
||||||
|
target: /config
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
|
- <<: *shared_data_volume
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: nginx-media-proxy
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
networks:
|
||||||
|
- media-net
|
||||||
|
depends_on:
|
||||||
|
- prowlarr
|
||||||
|
- sonarr
|
||||||
|
- radarr
|
||||||
|
- ombi
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
restart: unless-stopped
|
||||||
|
dns:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
jellyseerr:
|
||||||
|
image: fallenbagel/jellyseerr:latest
|
||||||
|
container_name: jellyseerr
|
||||||
|
expose: ["5055:5055"]
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes: *jellyseerr_volumes
|
||||||
|
networks:
|
||||||
|
- media-net
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
restart: unless-stopped
|
||||||
|
dns:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
prowlarr:
|
||||||
|
image: lscr.io/linuxserver/prowlarr:latest
|
||||||
|
container_name: prowlarr
|
||||||
|
expose: ["9696"]
|
||||||
|
volumes: *prowlarr_volumes
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
networks:
|
||||||
|
- media-net
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "-f", "http://localhost:9696" ]
|
||||||
|
interval: 1m
|
||||||
|
retries: 3
|
||||||
|
restart: unless-stopped
|
||||||
|
dns:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
sonarr:
|
||||||
|
image: lscr.io/linuxserver/sonarr:latest
|
||||||
|
container_name: sonarr
|
||||||
|
expose: ["8989"]
|
||||||
|
volumes: *sonarr_volumes
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
networks:
|
||||||
|
- media-net
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "-f", "http://localhost:8989" ]
|
||||||
|
interval: 1m
|
||||||
|
retries: 3
|
||||||
|
restart: unless-stopped
|
||||||
|
dns:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
radarr:
|
||||||
|
image: lscr.io/linuxserver/radarr:latest
|
||||||
|
container_name: radarr
|
||||||
|
expose: ["7878"]
|
||||||
|
volumes: *radarr_volumes
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
networks:
|
||||||
|
- media-net
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "-f", "http://localhost:7878" ]
|
||||||
|
interval: 1m
|
||||||
|
retries: 3
|
||||||
|
restart: unless-stopped
|
||||||
|
dns:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
ombi:
|
||||||
|
image: lscr.io/linuxserver/ombi:latest
|
||||||
|
container_name: ombi
|
||||||
|
environment:
|
||||||
|
- PUID=${PUID}
|
||||||
|
- PGID=${PGID}
|
||||||
|
- TZ=${TZ}
|
||||||
|
volumes:
|
||||||
|
- /mnt/machine-spirit/configs/ombi:/config
|
||||||
|
ports: ["3579:3579"]
|
||||||
|
networks:
|
||||||
|
- media-net
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "-f", "http://localhost:3579" ]
|
||||||
|
interval: 1m
|
||||||
|
retries: 3
|
||||||
|
restart: unless-stopped
|
||||||
|
dns:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
networks:
|
||||||
|
media-net:
|
||||||
|
driver: bridge
|
||||||
|
labels:
|
||||||
|
- "com.media-stack.network=main"
|
||||||
|
- "com.media-stack.description=Primary network for *arr stack communication with IPv6"
|
115
nginx.conf
Normal file
115
nginx.conf
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# Simple reverse proxy configuration
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
|
||||||
|
# Client settings
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
location /ombi {
|
||||||
|
proxy_pass http://ombi:3579;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /sonarr {
|
||||||
|
proxy_pass http://sonarr:8989;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /radarr {
|
||||||
|
proxy_pass http://radarr:7878;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /prowlarr {
|
||||||
|
proxy_pass http://prowlarr:9696;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main landing page
|
||||||
|
location = / {
|
||||||
|
return 200 '<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Media Server</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background: #1a1a1a; color: #fff; }
|
||||||
|
.container { max-width: 800px; margin: 0 auto; }
|
||||||
|
h1 { text-align: center; color: #4CAF50; }
|
||||||
|
.services { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-top: 40px; }
|
||||||
|
.service { background: #2d2d2d; padding: 20px; border-radius: 8px; text-align: center; }
|
||||||
|
.service a { color: #4CAF50; text-decoration: none; font-size: 18px; font-weight: bold; }
|
||||||
|
.service p { margin: 10px 0 0 0; color: #ccc; font-size: 14px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Media Server</h1>
|
||||||
|
<div class="services">
|
||||||
|
<div class="service">
|
||||||
|
<a href="/ombi">Ombi</a>
|
||||||
|
<p>Request movies & TV shows</p>
|
||||||
|
</div>
|
||||||
|
<div class="service">
|
||||||
|
<a href="/sonarr">Sonarr</a>
|
||||||
|
<p>TV show management</p>
|
||||||
|
</div>
|
||||||
|
<div class="service">
|
||||||
|
<a href="/radarr">Radarr</a>
|
||||||
|
<p>Movie management</p>
|
||||||
|
</div>
|
||||||
|
<div class="service">
|
||||||
|
<a href="/prowlarr">Prowlarr</a>
|
||||||
|
<p>Indexer management</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
|
add_header Content-Type text/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user