A complete solution for your personal media server needs, including automatic download, media organization, and streaming capabilities.
- Plex Media Server: Stream your media anywhere
- Automated Downloads: Integration with Sonarr (TV Shows) and Radarr (Movies)
- Torrent Management: Transmission client with VPN integration
- Optional Secure Access: SWAG reverse proxy with optional Cloudflare integration
- Download Management: Jackett for torrent indexing
- Analytics: Tautulli for Plex statistics and monitoring
- Built-in VPN: NORDVPN integration using WireGuard (https://github.com/bubuntux/nordlynx)
- Linux-based system (Ubuntu/Debian recommended)
- At least 8GB RAM
- Minimum 20GB storage space (recommended: 100GB+)
- Active internet connection
- (Optional) Domain name and Cloudflare account for SWAG integration
- (Optional) NordVPN subscription for VPN protection
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
sudo apt update && sudo apt install git
git clone https://github.com/angolo40/dpms.git
cd dpms
cp .env.example .env
Edit the .env
file with your preferred text editor and configure all the required variables:
nano .env
The VPN container uses NordLynx (WireGuard) protocol. You'll need:
- NordVPN account email
- NordVPN private key (follow the procedure at (https://github.com/bubuntux/nordlynx?tab=readme-ov-file#how-to-get-your-private_key) to generate it)
Configure these in your .env file:
[email protected]
NORDVPN_PRIVATE_KEY=your-private-key
If you don't want to use NordVPN:
- Remove the VPN service from docker-compose.yml
- For each service using
network_mode: service:vpn
, replace with:networks: - compose_default
- Modify each .conf file in swag/config/nginx/proxy-conf/:
# Change from set $upstream_app vpn; # To set $upstream_app service_name; # (radarr, sonarr, etc.)
- Remove the VPN-related environment variables from your .env file
SWAG (Secure Web Application Gateway) is an Nginx-based container that provides:
- Automatic SSL/TLS certificate management via Let's Encrypt
- Reverse proxy for all services
- Pre-configured application proxy files
- Basic protection against common attacks
- Fail2ban integration for protection against malicious login attempts
Cloudflare integration adds:
- Secure tunnel between Cloudflare and your server (no port forwarding needed)
- Real IP masking
- DDoS protection
- End-to-end SSL
- Automatic DNS management via Cloudflare API
If you want to use SWAG with Cloudflare integration:
-
Keep the SWAG service in docker-compose.yml
-
Configure the Cloudflare-related variables in your .env file
-
Set up the required configuration files:
a. Configure tunnelconfig.yml:
# Copy the example file to swag/config/tunnelconfig.yml cp tunnelconfig.yml /path/to/swag/config/ # Edit the file and replace yourdomain.com with your actual domain nano /path/to/swag/config/tunnelconfig.yml
Example configuration:
ingress: - hostname: plex.yourdomain.com service: https://localhost:443 originRequest: connectTimeout: 10s noTLSVerify: true # Repeat for other services - service: http_status:404
b. Configure Cloudflare DNS authentication:
# Copy the example file to swag/config/dns-conf/cloudflare.ini cp cloudflare.ini /path/to/swag/config/dns-conf/ # Edit the file and add your Cloudflare API token nano /path/to/swag/config/dns-conf/cloudflare.ini
-
Set up proxy configurations:
# Create proxy-conf directory if it doesn't exist mkdir -p /path/to/swag/config/nginx/proxy-conf/ # Copy the provided proxy configuration files cp *.subdomain.conf /path/to/swag/config/nginx/proxy-conf/
Provided configuration files:
- jackett.subdomain.conf
- plex.subdomain.conf
- radarr.subdomain.conf
- sonarr.subdomain.conf
- tautulli.subdomain.conf
- transmission.subdomain.conf
Cloudflare offers additional security features through access configuration, such as:
- Team access controls
- GeoIP blocking
- Additional authentication layers
- Access policies
- Traffic filtering
The following optional configuration can be added to each service in your tunnelconfig.yml to enable these features:
access:
required: true
teamName: yourdomain.com
Detailed instructions for setting up and configuring these advanced security features will be provided in future updates.
To run without Cloudflare:
- Comment out or remove the SWAG service from docker-compose.yml
- Uncomment the port mappings in each service
- Remove Cloudflare-related variables from your .env file
docker compose up -d
Your Server
Internet +--------------------------+
| | |
| +-------------+ | +-----------------+ |
+----| Cloudflare |------------------|----| SWAG (Reverse | |
| | (Optional) | | | Proxy + SSL) | |
| +-------------+ | +-----------------+ |
| | | |
| +-------------+ | +-----------------+ |
+----| NordVPN |------------------|----| VPN Container | |
| | | | | |
+-------------+ | +-----------------+ |
| | |
| +-----------------+ |
| | Service Layer | |
| | | |
| | - Radarr | |
| | - Sonarr | |
| | - Jackett | |
| | - Transmission | |
| +-----------------+ |
| |
+--------------------------+
Internet User -> Request Movie
|
v
[Cloudflare] (optional)
|
v
[SWAG Reverse Proxy]
|
v
[Radarr] --- Search Request ---> [Jackett]
| |
| v
| [Search Indexers]
| |
| v
+<---- Search Results ---------+
|
v
[Decision & Selection]
|
v
[VPN Container]
|
v
[Transmission] --- Download ---> [Internet]
|
v
[Downloaded File]
|
v
[Radarr Processing]
|
v
[Final Media Folder]
|
v
[Plex Library]
Access your services through their subdomains:
- Plex: https://plex.yourdomain.com
- Radarr: https://radarr.yourdomain.com
- Sonarr: https://sonarr.yourdomain.com
- Jackett: https://jackett.yourdomain.com
- Transmission: https://torrent.yourdomain.com
- Tautulli: https://tautulli.yourdomain.com
Access your services through their direct ports:
- Plex: http://your-server-ip:32400
- Radarr: http://your-server-ip:7878
- Sonarr: http://your-server-ip:8989
- Jackett: http://your-server-ip:9117
- Transmission: http://your-server-ip:9091
- Tautulli: http://your-server-ip:8181
/config
βββ plex # Plex configuration and metadata
βββ sonarr # Sonarr configuration
βββ radarr # Radarr configuration
βββ transmission # Transmission settings and watch folder
βββ jackett # Jackett configuration
βββ tautulli # Tautulli configuration
βββ swag # SWAG configuration and SSL certificates
βββ config
β βββ nginx
β β βββ proxy-conf # Nginx proxy configurations
β β βββ jackett.subdomain.conf
β β βββ plex.subdomain.conf
β β βββ radarr.subdomain.conf
β β βββ sonarr.subdomain.conf
β β βββ tautulli.subdomain.conf
β β βββ transmission.subdomain.conf
β βββ dns-conf # Cloudflare DNS configuration
β β βββ cloudflare.ini # Cloudflare API credentials
β βββ tunnelconfig.yml # Cloudflare tunnel configuration
- All traffic is routed through NordVPN for downloading services
- SWAG provides SSL encryption for all services
- Cloudflare provides additional security features (optional):
- GeoIP blocking for restricting access by geographic location
- Advanced authentication policies
- Traffic filtering and rate limiting
- DDoS protection
- Basic authentication is still enforced for all services
- Consider using your router's firewall rules
- Recommend using HTTPS when possible
- Note: Advanced security features won't be available without Cloudflare integration
docker compose pull
docker compose up -d
docker compose logs -f [service_name]
Regular backups of the /config
directory are recommended:
tar -czf dpms_backup_$(date +%Y%m%d).tar.gz /path/to/config
-
VPN Connection Issues
- Check NordVPN credentials
- Verify VPN container logs
- Ensure ports are not blocked
-
Media Not Appearing in Plex
- Verify file permissions (PGID/PUID)
- Check path mappings
- Scan library manually
-
Download Problems
- Verify Jackett indexers are working
- Check Transmission connection through VPN
- Verify path permissions
-
SWAG/Proxy Issues
- Verify proxy configuration files are in the correct location
- Check SWAG logs for specific errors
- Verify cloudflare.ini contains the correct API token
- Check tunnelconfig.yml has the correct domain names configured
- Environment variables configured in .env
- NordVPN configured with email and private key
- tunnelconfig.yml copied to correct location and domain name updated (if using Cloudflare)
- cloudflare.ini copied to dns-conf directory and API token configured (if using Cloudflare)
- Proxy configuration files copied to the correct location
- All required directories created and permissions set
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
For issues and feature requests, please use the GitHub issues page.
β If you find this project useful, please consider giving it a star on GitHub!