From f19385bb81f693bff06e12dcc2a080899355e870 Mon Sep 17 00:00:00 2001 From: Matthew Pomes Date: Mon, 18 Aug 2025 17:22:16 -0500 Subject: [PATCH] Initial commit with working services --- .gitignore | 1 + docker-compose.yaml | 65 +++++++++ karakeep-compose.yaml | 89 ++++++++++++ nginx.dockerfile | 4 + nginx/mime.types | 101 +++++++++++++ nginx/nginx.conf | 82 +++++++++++ nginx/sites-available/5d-diplomacy | 60 ++++++++ nginx/sites-available/default | 219 +++++++++++++++++++++++++++++ nginx/sites-enabled/jellyfin | 66 +++++++++ nginx/sites-enabled/karakeep | 52 +++++++ nginx/sites-enabled/ollama | 52 +++++++ nginx/sites-enabled/primary | 55 ++++++++ 12 files changed, 846 insertions(+) create mode 100644 .gitignore create mode 100644 docker-compose.yaml create mode 100644 karakeep-compose.yaml create mode 100644 nginx.dockerfile create mode 100644 nginx/mime.types create mode 100644 nginx/nginx.conf create mode 100644 nginx/sites-available/5d-diplomacy create mode 100644 nginx/sites-available/default create mode 100644 nginx/sites-enabled/jellyfin create mode 100644 nginx/sites-enabled/karakeep create mode 100644 nginx/sites-enabled/ollama create mode 100644 nginx/sites-enabled/primary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..167dedd --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,65 @@ +include: + - ./karakeep-compose.yaml +services: + web: + image: "nginx" + restart: unless-stopped + ports: + - 80:80 + - 443:443 + volumes: + - ./nginx:/etc/nginx + - /etc/letsencrypt:/etc/letsencrypt + - /data/site:/data/site + networks: + - karakeep + - ollama + - jellyfin + depends_on: + - jellyfin + - ollama-webui + - karakeep-web + jellyfin: + image: "jellyfin/jellyfin" + restart: unless-stopped + environment: + - JELLYFIN_PublishedServerUrl=http://jellyfin.loadingm.xyz + volumes: + - /var/lib/jellyfin:/data + - /etc/jellyfin:/config + - /var/cache/jellyfin:/cache + - type: bind + source: /data/library/ + target: /data/library + read_only: true + networks: + - jellyfin + # Optional - extra fonts to be used during transcoding with subtitle burn-in + # - type: bind + # source: /usr/local/share/fonts/cu + # target: /usr/local/share/fonts/custom + # read_only: true + # webdav: + # image: "" + # minecraft: + # image: "" + # calibre: + # image: "linuxserver/calibre-web" + # 5d-diplomacy-frontend: + # image: "" + # 5d-diplomacy-backend: + # image: "" +volumes: + meilisearch: + karakeep: +networks: + karakeep: + external: false + karakeep-int: + external: false + ollama: + external: false + ollama-int: + external: false + jellyfin: + external: false diff --git a/karakeep-compose.yaml b/karakeep-compose.yaml new file mode 100644 index 0000000..0827a16 --- /dev/null +++ b/karakeep-compose.yaml @@ -0,0 +1,89 @@ +services: + karakeep-web: + image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release} + restart: unless-stopped + volumes: + # By default, the data is stored in a docker volume called "data". + # If you want to mount a custom directory, change the volume mapping to: + # - /path/to/your/directory:/data + - /data/karakeep:/data + # ports: + # - 3000:3000 + env_file: + - .env + environment: + MEILI_ADDR: http://meilisearch:7700 + BROWSER_WEB_URL: http://karakeep-chrome:9222 + OLLAMA_BASE_URL: http://ollama:11434 #comma separated ollama hosts + INFERENCE_TEXT_MODEL: gemma3 + INFERENCE_IMAGE_MODEL: llava + INFERENCE_OUTPUT_SCHEMA: json + INFERENCE_CONTEXT_LENGTH: 1024 + INFERENCE_JOB_TIMEOUT_SEC: 120 + + # You almost never want to change the value of the DATA_DIR variable. + # If you want to mount a custom directory, change the volume mapping above instead. + DATA_DIR: /data # DON'T CHANGE THIS + networks: + - karakeep + - karakeep-int + - ollama-int + karakeep-chrome: + image: gcr.io/zenika-hub/alpine-chrome:123 + restart: unless-stopped + command: + - --no-sandbox + - --disable-gpu + - --disable-dev-shm-usage + - --remote-debugging-address=0.0.0.0 + - --remote-debugging-port=9222 + - --hide-scrollbars + networks: + - karakeep-int + meilisearch: + image: getmeili/meilisearch:v1.13.3 + restart: unless-stopped + env_file: + - .env + environment: + MEILI_NO_ANALYTICS: "true" + volumes: + - /data/meilisearch:/meili_data + networks: + - karakeep-int + ollama: + image: docker.io/ollama/ollama:latest + volumes: + - .:/code + - /data/library/ollama/ollama:/root/.ollama + container_name: ollama + pull_policy: always + tty: true + restart: always + environment: + - OLLAMA_KEEP_ALIVE=24h + - OLLAMA_HOST=0.0.0.0 + - OLLAMA_DEBUG=1 + networks: + - ollama-int + + ollama-webui: + image: ghcr.io/open-webui/open-webui:main + container_name: ollama-webui + volumes: + - /data/library/ollama/ollama-webui:/app/backend/data + depends_on: + - ollama + environment: # https://docs.openwebui.com/getting-started/env-configuration#default_models + - OLLAMA_BASE_URLS=http://host.docker.internal:7869 #comma separated ollama hosts + - ENV=dev + - WEBUI_AUTH=True + - WEBUI_NAME=valiantlynx AI + - WEBUI_URL=http://localhost:8080 + - WEBUI_SECRET_KEY=t0p-s3cr3t + extra_hosts: + - host.docker.internal:host-gateway + restart: unless-stopped + networks: + - ollama + - ollama-int diff --git a/nginx.dockerfile b/nginx.dockerfile new file mode 100644 index 0000000..09c83a2 --- /dev/null +++ b/nginx.dockerfile @@ -0,0 +1,4 @@ +FROM nginx +COPY ./nginx/nginx.conf /etc/nginx/ +COPY ./nginx/mime.types /etc/nginx/ +COPY ./nginx/sites-available /etc/nginx/ diff --git a/nginx/mime.types b/nginx/mime.types new file mode 100644 index 0000000..cf968c0 --- /dev/null +++ b/nginx/mime.types @@ -0,0 +1,101 @@ +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/javascript js; + application/atom+xml atom; + application/rss+xml rss; + + text/mathml mml; + text/plain txt; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/x-component htc; + + image/avif avif; + image/png png; + image/svg+xml svg svgz; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/webp webp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + + font/woff woff; + font/woff2 woff2; + + application/java-archive jar war ear; + application/json json; + application/mac-binhex40 hqx; + application/msword doc; + application/pdf pdf; + application/postscript ps eps ai; + application/rtf rtf; + application/vnd.apple.mpegurl m3u8; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/vnd.ms-excel xls; + application/vnd.ms-fontobject eot; + application/vnd.ms-powerpoint ppt; + application/vnd.oasis.opendocument.graphics odg; + application/vnd.oasis.opendocument.presentation odp; + application/vnd.oasis.opendocument.spreadsheet ods; + application/vnd.oasis.opendocument.text odt; + application/vnd.openxmlformats-officedocument.presentationml.presentation + pptx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + xlsx; + application/vnd.openxmlformats-officedocument.wordprocessingml.document + docx; + application/vnd.wap.wmlc wmlc; + application/wasm wasm; + application/x-7z-compressed 7z; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/xslt+xml xsl xslt; + application/xspf+xml xspf; + application/zip zip; + + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream iso img; + application/octet-stream msi msp msm; + + audio/midi mid midi kar; + audio/mpeg mp3; + audio/ogg ogg; + audio/x-m4a m4a; + audio/x-realaudio ra; + + video/3gpp 3gpp 3gp; + video/mp2t ts; + video/mp4 mp4; + video/mpeg mpeg mpg; + video/ogg ogv; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-m4v m4v; + video/x-matroska mkv; + video/x-mng mng; + video/x-ms-asf asx asf; + video/x-ms-wmv wmv; + video/x-msvideo avi; +} diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..b6ce2d2 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,82 @@ +user www-data; +worker_processes auto; +worker_cpu_affinity auto; +pid /run/nginx.pid; +error_log /var/log/nginx/error.log; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + types_hash_max_size 2048; + server_tokens off; # Recommended practice is to turn this off + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3 (POODLE), TLS 1.0, 1.1 + ssl_prefer_server_ciphers off; # Don't force server cipher order. + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + + ## + # Gzip Settings + ## + + gzip on; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/sites-enabled/*; +} + + +#mail { +# # See sample authentication script at: +# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript +# +# # auth_http localhost/auth.php; +# # pop3_capabilities "TOP" "USER"; +# # imap_capabilities "IMAP4rev1" "UIDPLUS"; +# +# server { +# listen localhost:110; +# protocol pop3; +# proxy on; +# } +# +# server { +# listen localhost:143; +# protocol imap; +# proxy on; +# } +#} diff --git a/nginx/sites-available/5d-diplomacy b/nginx/sites-available/5d-diplomacy new file mode 100644 index 0000000..88f9773 --- /dev/null +++ b/nginx/sites-available/5d-diplomacy @@ -0,0 +1,60 @@ +server { + if ($host = 5d-diplomacy.loadingm.xyz) { + return 301 https://$host$request_uri; + } # managed by Certbot + + + listen 80; + listen [::]:80; + server_name 5d-diplomacy.loadingm.xyz; + + # Uncomment to redirect HTTP to HTTPS + return 301 https://$host$request_uri; + + +} + +server { + # Nginx versions 1.25+ + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + + server_name 5d-diplomacy.loadingm.xyz; + + ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. + client_max_body_size 20M; + + ssl_certificate /etc/letsencrypt/live/5d-diplomacy.loadingm.xyz/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/5d-diplomacy.loadingm.xyz/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + ssl_trusted_certificate /etc/letsencrypt/live/5d-diplomacy.loadingm.xyz/chain.pem; + + # Security / XSS Mitigation Headers + add_header X-Content-Type-Options "nosniff"; + + # Permissions policy. May cause issues with some clients + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; + + # Content Security Policy + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + # Enforces https content and restricts JS/CSS to origin + # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; font-src 'self'"; + + location / { + # Proxy main traffic + proxy_pass http://localhost:5173; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + + # Disable buffering when the nginx proxy gets very resource heavy upon streaming + proxy_buffering off; + } + +} diff --git a/nginx/sites-available/default b/nginx/sites-available/default new file mode 100644 index 0000000..6e5bc7c --- /dev/null +++ b/nginx/sites-available/default @@ -0,0 +1,219 @@ +## +# You should look at the following URL's in order to grasp a solid understanding +# of Nginx configuration files in order to fully unleash the power of Nginx. +# https://www.nginx.com/resources/wiki/start/ +# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/ +# https://wiki.debian.org/Nginx/DirectoryStructure +# +# In most cases, administrators will remove this file from sites-enabled/ and +# leave it as reference inside of sites-available where it will continue to be +# updated by the nginx packaging team. +# +# This file will automatically load configuration files provided by other +# applications, such as Drupal or Wordpress. These applications will be made +# available underneath a path with that package name, such as /drupal8. +# +# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. +## + +# Default server configuration +# +server { + listen 80 default_server; + listen [::]:80 default_server; + + # SSL configuration + # + # listen 443 ssl default_server; + # listen [::]:443 ssl default_server; + # + # Note: You should disable gzip for SSL traffic. + # See: https://bugs.debian.org/773332 + # + # Read up on ssl_ciphers to ensure a secure configuration. + # See: https://bugs.debian.org/765782 + # + # Self signed certs generated by the ssl-cert package + # Don't use them in a production server! + # + # include snippets/snakeoil.conf; + + root /var/www/html; + + # Add index.php to the list if you are using PHP + index index.html index.htm index.nginx-debian.html; + + server_name _; + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # pass PHP scripts to FastCGI server + # + #location ~ \.php$ { + # include snippets/fastcgi-php.conf; + # + # # With php-fpm (or other unix sockets): + # fastcgi_pass unix:/run/php/php7.4-fpm.sock; + # # With php-cgi (or other tcp sockets): + # fastcgi_pass 127.0.0.1:9000; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} +} + + +# Virtual Host configuration for example.com +# +# You can move that to a different file under sites-available/ and symlink that +# to sites-enabled/ to enable it. +# +#server { +# listen 80; +# listen [::]:80; +# +# server_name example.com; +# +# root /var/www/example.com; +# index index.html; +# +# location / { +# try_files $uri $uri/ =404; +# } +#} + +server { + + # SSL configuration + # + # listen 443 ssl default_server; + # listen [::]:443 ssl default_server; + # + # Note: You should disable gzip for SSL traffic. + # See: https://bugs.debian.org/773332 + # + # Read up on ssl_ciphers to ensure a secure configuration. + # See: https://bugs.debian.org/765782 + # + # Self signed certs generated by the ssl-cert package + # Don't use them in a production server! + # + # include snippets/snakeoil.conf; + + root /var/www/html; + + # Add index.php to the list if you are using PHP + index index.html index.htm index.nginx-debian.html; + server_name jellyfin.loadingm.xyz; # managed by Certbot + + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # pass PHP scripts to FastCGI server + # + #location ~ \.php$ { + # include snippets/fastcgi-php.conf; + # + # # With php-fpm (or other unix sockets): + # fastcgi_pass unix:/run/php/php7.4-fpm.sock; + # # With php-cgi (or other tcp sockets): + # fastcgi_pass 127.0.0.1:9000; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} + + + listen [::]:443 ssl ipv6only=on; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/jellyfin.loadingm.xyz/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/jellyfin.loadingm.xyz/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot + + + add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot + + + ssl_trusted_certificate /etc/letsencrypt/live/jellyfin.loadingm.xyz/chain.pem; # managed by Certbot + ssl_stapling on; # managed by Certbot + ssl_stapling_verify on; # managed by Certbot + +} +server { + if ($host = jellyfin.loadingm.xyz) { + return 301 https://$host$request_uri; + } # managed by Certbot + + + listen 80 ; + listen [::]:80 ; + + # SSL configuration + # + # listen 443 ssl default_server; + # listen [::]:443 ssl default_server; + # + # Note: You should disable gzip for SSL traffic. + # See: https://bugs.debian.org/773332 + # + # Read up on ssl_ciphers to ensure a secure configuration. + # See: https://bugs.debian.org/765782 + # + # Self signed certs generated by the ssl-cert package + # Don't use them in a production server! + # + # include snippets/snakeoil.conf; + + root /var/www/html; + + # Add index.php to the list if you are using PHP + index index.html index.htm index.nginx-debian.html; + server_name jellyfin.loadingm.xyz; # managed by Certbot + + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # pass PHP scripts to FastCGI server + # + #location ~ \.php$ { + # include snippets/fastcgi-php.conf; + # + # # With php-fpm (or other unix sockets): + # fastcgi_pass unix:/run/php/php7.4-fpm.sock; + # # With php-cgi (or other tcp sockets): + # fastcgi_pass 127.0.0.1:9000; + #} + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} + + + + + +} \ No newline at end of file diff --git a/nginx/sites-enabled/jellyfin b/nginx/sites-enabled/jellyfin new file mode 100644 index 0000000..e65f94b --- /dev/null +++ b/nginx/sites-enabled/jellyfin @@ -0,0 +1,66 @@ +server { + listen 80; + listen [::]:80; + server_name jellyfin.loadingm.xyz; + + # Uncomment to redirect HTTP to HTTPS + return 301 https://$host$request_uri; +} + +server { + # Nginx versions 1.25+ + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + + server_name jellyfin.loadingm.xyz; + + ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. + client_max_body_size 20M; + + ssl_certificate /etc/letsencrypt/live/jellyfin.loadingm.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/jellyfin.loadingm.xyz/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + ssl_trusted_certificate /etc/letsencrypt/live/jellyfin.loadingm.xyz/chain.pem; + + # Security / XSS Mitigation Headers + add_header X-Content-Type-Options "nosniff"; + + # Permissions policy. May cause issues with some clients + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; + + # Content Security Policy + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + # Enforces https content and restricts JS/CSS to origin + # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; font-src 'self'"; + + location / { + # Proxy main Jellyfin traffic + proxy_pass http://jellyfin:8096; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + + # Disable buffering when the nginx proxy gets very resource heavy upon streaming + proxy_buffering off; + } + + location /socket { + # Proxy Jellyfin Websockets traffic + proxy_pass http://jellyfin:8096; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } +} diff --git a/nginx/sites-enabled/karakeep b/nginx/sites-enabled/karakeep new file mode 100644 index 0000000..7ea96cd --- /dev/null +++ b/nginx/sites-enabled/karakeep @@ -0,0 +1,52 @@ +server { + listen 80; + listen [::]:80; + server_name karakeep.loadingm.xyz; + + # Uncomment to redirect HTTP to HTTPS + return 301 https://$host$request_uri; +} + +server { + # Nginx versions 1.25+ + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + + server_name karakeep.loadingm.xyz; + + ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. + client_max_body_size 20M; + + ssl_certificate /etc/letsencrypt/live/karakeep.loadingm.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/karakeep.loadingm.xyz/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + ssl_trusted_certificate /etc/letsencrypt/live/karakeep.loadingm.xyz/chain.pem; + + # Security / XSS Mitigation Headers + add_header X-Content-Type-Options "nosniff"; + + # Permissions policy. May cause issues with some clients + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; + + # Content Security Policy + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + # Enforces https content and restricts JS/CSS to origin + # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; font-src 'self'"; + + location / { + # Proxy main karakeep traffic + proxy_pass http://karakeep-web:3000; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + + # Disable buffering when the nginx proxy gets very resource heavy upon streaming + proxy_buffering off; + } +} diff --git a/nginx/sites-enabled/ollama b/nginx/sites-enabled/ollama new file mode 100644 index 0000000..1d74794 --- /dev/null +++ b/nginx/sites-enabled/ollama @@ -0,0 +1,52 @@ +server { + listen 80; + listen [::]:80; + server_name ollama.loadingm.xyz; + + # Uncomment to redirect HTTP to HTTPS + return 301 https://$host$request_uri; +} + +server { + # Nginx versions 1.25+ + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + + server_name ollama.loadingm.xyz; + + ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. + client_max_body_size 20M; + + ssl_certificate /etc/letsencrypt/live/ollama.loadingm.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/ollama.loadingm.xyz/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + ssl_trusted_certificate /etc/letsencrypt/live/ollama.loadingm.xyz/chain.pem; + + # Security / XSS Mitigation Headers + add_header X-Content-Type-Options "nosniff"; + + # Permissions policy. May cause issues with some clients + add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always; + + # Content Security Policy + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP + # Enforces https content and restricts JS/CSS to origin + # External Javascript (such as cast_sender.js for Chromecast) must be whitelisted. + add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; font-src 'self'"; + + location / { + # Proxy main ollama traffic + proxy_pass http://ollama-webui:8080; + 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; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + + # Disable buffering when the nginx proxy gets very resource heavy upon streaming + proxy_buffering off; + } +} diff --git a/nginx/sites-enabled/primary b/nginx/sites-enabled/primary new file mode 100644 index 0000000..9a323e6 --- /dev/null +++ b/nginx/sites-enabled/primary @@ -0,0 +1,55 @@ +## +# You should look at the following URL's in order to grasp a solid understanding +# of Nginx configuration files in order to fully unleash the power of Nginx. +# https://www.nginx.com/resources/wiki/start/ +# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/ +# https://wiki.debian.org/Nginx/DirectoryStructure +# +# In most cases, administrators will remove this file from sites-enabled/ and +# leave it as reference inside of sites-available where it will continue to be +# updated by the nginx packaging team. +# +# This file will automatically load configuration files provided by other +# applications, such as Drupal or Wordpress. These applications will be made +# available underneath a path with that package name, such as /drupal8. +# +# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. +## + +# Default server configuration +# +server { + + # SSL configuration + listen 443 ssl default_server; + listen [::]:443 ssl default_server; + http2 on; + + server_name loadingm.xyz; + + ssl_certificate /etc/letsencrypt/live/loadingm.xyz/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/loadingm.xyz/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + ssl_trusted_certificate /etc/letsencrypt/live/loadingm.xyz/chain.pem; + + root /data/site; + + location /hosted { + index index.html; + autoindex on; + } + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + #location ~ /\.ht { + # deny all; + #} +}