This commit is contained in:
2025-09-21 18:48:48 +05:30
commit 0e30e55923
4 changed files with 347 additions and 0 deletions

10
.env Normal file
View 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
View 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
View 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
View 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;
}
}