Skip to content

Commit

Permalink
Merge pull request #23 from westsurname/plex-request-nginx
Browse files Browse the repository at this point in the history
Add nginx docker container
  • Loading branch information
westsurname authored Jul 23, 2024
2 parents de2e36a + 2419b73 commit a9bb42e
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 58 deletions.
12 changes: 9 additions & 3 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
# ╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚══════╝ #
#------------------------------------------------------#

#------------------------------#
# SERVER - PLEX AUTHENTICATION #
#------------------------------#
#--------#
# SERVER #
#--------#

SERVER_DOMAIN=<server_domain>

Expand Down Expand Up @@ -123,6 +123,12 @@ BLACKHOLE_RD_MOUNT_REFRESH_SECONDS=200
BLACKHOLE_WAIT_FOR_TORRENT_TIMEOUT=60
BLACKHOLE_HISTORY_PAGE_SIZE=500

#------------------------------#
# PLEX REQUEST - PLEX REQUEST #
#------------------------------#

PLEX_REQUEST_SSL_PATH=

#-----------------------------------------------------------------------------------------------#
# DISCORD - BLACKHOLE, WATCHLIST, PLEX AUTHENTICATION, PLEX REQUEST, MONITOR RAM, RECLAIM SPACE #
#-----------------------------------------------------------------------------------------------#
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/docker-build-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
image: ghcr.io/${{ github.repository }}/plex_request
- dockerfile: ./Dockerfile.scripts
image: ghcr.io/${{ github.repository }}/scripts
- dockerfile: ./Dockerfile.plex_request_nginx
image: ghcr.io/${{ github.repository }}/plex_request_nginx
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand Down
19 changes: 19 additions & 0 deletions Dockerfile.plex_request_nginx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM nginx:alpine

# Metadata labels
LABEL org.opencontainers.image.source="https://github.com/westsurname/scripts"
LABEL org.opencontainers.image.description="Docker image for the plex_request_nginx service"

COPY plex_request_nginx_variables.conf /etc/nginx/templates/10-variables.conf.template
COPY plex_request_nginx.conf /etc/nginx/conf.d/default.conf

RUN if [ -n "$PLEX_REQUEST_SSL_PATH" ]; then \
sed -i '/# SSL_DISABLED_BEGIN/,/# SSL_DISABLED_END/d' /etc/nginx/conf.d/default.conf; \
else \
sed -i '/# SSL_ENABLED_BEGIN/,/# SSL_ENABLED_END/d' /etc/nginx/conf.d/default.conf; \
fi

# Expose port 8000 to the outside world
EXPOSE 8000

CMD ["nginx", "-g", "daemon off;"]
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
```
4. Copy `.env.template` to `.env` and populate the (applicable) variables:

- **Server** - Plex Authentication:
- **Server**:
- `SERVER_DOMAIN`: The domain name of your server.

- **Plex** - Watchlist, Plex Authentication, Plex Request, Plex Refresh:
Expand Down Expand Up @@ -85,6 +85,13 @@
- `BLACKHOLE_WAIT_FOR_TORRENT_TIMEOUT`: The timeout in seconds to wait for a torrent to be successful before failing.
- `BLACKHOLE_HISTORY_PAGE_SIZE`: The number of history items to pull at once when attempting to mark a download as failed.
- **Plex Request** - Plex Request:
- `PLEX_REQUEST_SSL_PATH` (Optional): The path to SSL certificates for Plex Request. If provided, this directory should contain the following files:
- `fullchain.pem`: The full certificate chain file.
- `privkey.pem`: The private key file.
- `chain.pem`: The certificate chain file.
- `dhparam.pem`: The Diffie-Hellman parameters file.
- **Discord** - Blackhole, Watchlist, Plex Authentication, Plex Request, Monitor Ram, Reclaim Space:
- `DISCORD_ENABLED`: Set to `true` to enable Discord error notifications.
- `DISCORD_UPDATE_ENABLED`: Set to `true` to enable update notifications as well on Discord.
Expand Down
26 changes: 21 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,11 @@ services:
volumes:
- ./shared/tokens.json:/app/shared/tokens.json
ports:
- 8000:8000
- 8010:8000
env_file:
- .env
environment:
- SERVER_DOMAIN=${SERVER_DOMAIN}:8000
restart: unless-stopped
profiles: [plex_authentication, all]
profiles: [plex_authentication, watchlist, plex_request, all]

plex_request:
build:
Expand All @@ -178,11 +176,29 @@ services:
volumes:
- ./shared/tokens.json:/app/shared/tokens.json
ports:
- 8001:8000
- 8011:8000
env_file:
- .env
restart: unless-stopped
profiles: [plex_request, all]

plex_request_nginx:
build:
context: .
dockerfile: Dockerfile.plex_request_nginx
container_name: plex_request_nginx_service
image: ghcr.io/westsurname/scripts/plex_request_nginx:latest
pull_policy: always
volumes:
- ${PLEX_REQUEST_SSL_PATH:-/dev/null}:${PLEX_REQUEST_SSL_PATH:-/dev/null}:ro
ports:
- 8012:8000
env_file:
- .env
restart: unless-stopped
profiles: [plex_request, all]
depends_on:
- plex_request

networks:
default:
Expand Down
16 changes: 8 additions & 8 deletions plex_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@
import json
import urllib.parse
from flask import Flask, jsonify, redirect, url_for
from shared.shared import server, watchlist, plexHeaders, tokensFilename
from shared.shared import watchlist, plexHeaders, tokensFilename
from shared.overseerr import getUserForPlexToken
from shared.plex import getServerToken
from werkzeug.serving import run_simple
from werkzeug.middleware.dispatcher import DispatcherMiddleware

host = server['host']
from werkzeug.middleware.proxy_fix import ProxyFix

# instantiate the app
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SERVER_NAME'] = f"{host}"


@app.route('/', methods=['GET'])
Expand Down Expand Up @@ -42,9 +38,13 @@ def setupComplete(pin):

with open(tokensFilename, 'r+') as tokensFile:
tokens = json.load(tokensFile)
token = tokens.get(user['id'], { 'etag': '' })
token = tokens.get(userId, { 'etag': '' })
token['token'] = authToken
token['serverToken'] = serverToken

if serverToken == authToken:
token['owner'] = True

tokens[userId] = token
tokensFile.seek(0)
json.dump(tokens, tokensFile)
Expand All @@ -54,7 +54,7 @@ def setupComplete(pin):

return jsonify('There was an error, please try again.')

# app.wsgi_app = DispatcherMiddleware(run_simple, {'/plexAuthentication': app.wsgi_app})
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1, x_prefix=1)

if __name__ == '__main__':
app.run('127.0.0.1', 12598)
1 change: 1 addition & 0 deletions plex_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ def requestRatingKey(mediaType, mediaTypeNum, ratingKey, season=None):
# return response

# response = jsonify(json.loads(blankMediaContainer))
response = Response('', status=204)
response.headers.add('Access-Control-Allow-Origin', 'https://app.plex.tv')

return response
Expand Down
84 changes: 43 additions & 41 deletions plex_request_nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,47 @@ ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

server {
listen 12598 ssl http2;

server_name <REVERESE_PROXY_DOMAIN>;

send_timeout 100m; #Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause (e.g. Chrome)

#Faster resolving, improves stapling time. Timeout and nameservers may need to be adjusted for your location Google's have been used here.
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;

# ssl
# ssl on; on;
ssl_certificate /path/to/ssl/fullchain.pem;
ssl_certificate_key /path/to/ssl/key.pem;
# ssl_certificate /etc/nginx/cert.pem;
# ssl_certificate_key /etc/nginx/key.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
#Intentionally not hardened for security for player support and encryption video streams has a lot of overhead with something like AES-256-GCM-SHA384.
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

#Why this is important: https://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30/
ssl_stapling on;
ssl_stapling_verify on;
#For letsencrypt.org you can get your chain like this: https://esham.io/2016/01/ocsp-stapling
ssl_trusted_certificate /path/to/ssl/chain.pem;

#Reuse ssl sessions, avoids unnecessary handshakes
#Turning this on will increase performance, but at the cost of security. Read below before making a choice.
#https://github.com/mozilla/server-side-tls/issues/135
#https://wiki.mozilla.org/Security/Server_Side_TLS#TLS_tickets_.28RFC_5077.29
#ssl_session_tickets on;
ssl_session_tickets off;

#Use: openssl dhparam -out dhparam.pem 2048 - 4096 is better but for overhead reasons 2048 is enough for Plex.
ssl_dhparam /path/to/ssl/dhparam.pem;
ssl_ecdh_curve secp384r1;
# SSL_DISABLED_BEGIN
listen 8000;
# SSL_DISABLED_END

# SSL_ENABLED_BEGIN
listen 8000 ssl http2;
# ssl
# ssl on; on;
ssl_certificate ${plex_request_ssl_path}/fullchain.pem;
ssl_certificate_key ${plex_request_ssl_path}/privkey.pem;
# ssl_certificate /etc/nginx/cert.pem;
# ssl_certificate_key /etc/nginx/key.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
#Intentionally not hardened for security for player support and encryption video streams has a lot of overhead with something like AES-256-GCM-SHA384.
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

#Why this is important: https://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30/
ssl_stapling on;
ssl_stapling_verify on;
#For letsencrypt.org you can get your chain like this: https://esham.io/2016/01/ocsp-stapling
ssl_trusted_certificate ${plex_request_ssl_path}/chain.pem;

#Reuse ssl sessions, avoids unnecessary handshakes
#Turning this on will increase performance, but at the cost of security. Read below before making a choice.
#https://github.com/mozilla/server-side-tls/issues/135
#https://wiki.mozilla.org/Security/Server_Side_TLS#TLS_tickets_.28RFC_5077.29
#ssl_session_tickets on;
ssl_session_tickets off;

#Use: openssl dhparam -out dhparam.pem 2048 - 4096 is better but for overhead reasons 2048 is enough for Plex.
ssl_dhparam ${plex_request_ssl_path}/dhparam.pem;
ssl_ecdh_curve secp384r1;
# SSL_ENABLED_END

#Plex has A LOT of javascript, xml and html. This helps a lot, but if it causes playback issues with devices turn it off. (Haven't encountered any yet)
gzip on;
Expand Down Expand Up @@ -92,7 +95,7 @@ server {
proxy_buffering off;

location / {
proxy_pass <PLEX_HOST>;
proxy_pass ${plex_server_host};
proxy_read_timeout 86400;

# add_header 'Access-Control-Allow-Origin' '*';
Expand All @@ -111,7 +114,7 @@ server {

# return 302 https://<PLEX_PUBLIC_HOST>$request_uri;

access_log logs/plex.access.log;
# access_log logs/plex.access.log;

# # enable the next two lines for http auth
# auth_basic "Restricted";
Expand All @@ -123,21 +126,20 @@ server {
}

location /library/all {
proxy_pass http://localhost:8001;
proxy_pass http://plex_request:8000;

access_log logs/plex.access.log;
# access_log logs/plex.access.log;
}

location ~ ^/library/metadata/[^/]+/children$ {
proxy_pass http://localhost:8001;
proxy_pass http://plex_request:8000;

access_log logs/plex.access.log;
# access_log logs/plex.access.log;
}

location /library/request/ {
proxy_pass http://localhost:8001;
proxy_pass http://plex_request:8000;

access_log logs/plex.access.log;
# access_log logs/plex.access.log;
}
}

7 changes: 7 additions & 0 deletions plex_request_nginx_variables.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
map $host $plex_request_ssl_path {
default "$PLEX_REQUEST_SSL_PATH";
}

map $host $plex_server_host {
default "$PLEX_SERVER_HOST";
}

0 comments on commit a9bb42e

Please sign in to comment.