After finally getting my R5S running from NVMe, I've been having much better success with Docker. I thought I'd share some of my config. My R5S is running off an internal 500GB NVMe, a 128GB would be adequate. I've setup a 14GB swap partition, but I've never seen its use go over 20%, so I imagine a 4GB swap might be adequate, but there doesn't seem to be any harm having a bigger one. The swap really helps when resources are stretched like when you index photos with Photoprism.
I'm running the following containers:
Nginx acts as a reverse proxy, so I can have subdomains:
I keep all my Docker volumes and media on an external USB3 NVMe. This means if you have to upgrade firmware wiping the internal NVMe, it's easy to pick up where you left off when redeploying the containers.
That's with all the containers running but not much load/traffic.
Note: docker stats shows CPU usage per core, so it's 4x100% = 400%. Like when you index photos with Photoprism, the CPU usage might say something like 271%. And in the image above qBittorrent is using of 36.53 of 400%.
########################################################################
First thing I do is change the ports Luci runs on:
########################################################################
vi /etc/config/uhttpd
########################################################################
opkg update
opkg install docker-compose
########################################################################
docker-compose.yml
########################################################################
########################################################################
nginx.conf
########################################################################
########################################################################
MariaDB
########################################################################
########################################################################
I'm running the following containers:
- nginx
certbot
watchtower
qbittorrent
homeassistant
jellyfin
photoprism
mariadb
adminer
bookstack
Nginx acts as a reverse proxy, so I can have subdomains:
- mywebsite.com
homeassistant.mywebsite.com
jellyfin.mywebsite.com
photoprism.mywebsite.com
bookstack.mywebsite.com
I keep all my Docker volumes and media on an external USB3 NVMe. This means if you have to upgrade firmware wiping the internal NVMe, it's easy to pick up where you left off when redeploying the containers.
That's with all the containers running but not much load/traffic.
Note: docker stats shows CPU usage per core, so it's 4x100% = 400%. Like when you index photos with Photoprism, the CPU usage might say something like 271%. And in the image above qBittorrent is using of 36.53 of 400%.
########################################################################
First thing I do is change the ports Luci runs on:
########################################################################
vi /etc/config/uhttpd
- 8000
8443
########################################################################
opkg update
opkg install docker-compose
########################################################################
docker-compose.yml
########################################################################
Code: Select all
services:
nginx:
image: nginx:latest
restart: unless-stopped
user: "65536"
environment:
TZ: 'Australia/Melbourne'
ports:
- "80:80"
- "443:443"
volumes:
- /mnt/sda1/nginx/config:/etc/nginx/conf.d
- /mnt/sda1/nginx/logs:/var/log/nginx
- /mnt/sda1/nginx/nginx.conf:/etc/nginx/nginx.conf
- /mnt/sda1/nginx/cache:/var/cache/nginx
- /mnt/sda1/nginx/run:/var/run
- /mnt/sda1/nginx/html:/usr/share/nginx/html
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- bookstack
- homeassistant
- jellyfin
- photoprism
networks:
my-network:
ipv4_address: 172.19.0.11
certbot:
image: certbot/certbot:latest
restart: unless-stopped
user: "65536"
environment:
TZ: 'Australia/Melbourne'
volumes:
- /etc/letsencrypt:/etc/letsencrypt
- /var/lib/letsencrypt:/var/lib/letsencrypt
- /mnt/sda1/nginx/html:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
command: certonly --webroot --webroot-path=/var/www/certbot --email bob@mail.com -d mywebsite.com --agree-tos --no-eff-email
networks:
- my-network
mariadb:
image: mariadb:latest
restart: unless-stopped
user: "65536"
environment:
TZ: 'Australia/Melbourne'
MARIADB_ROOT_PASSWORD: "top_secret"
volumes:
- /mnt/sda1/mariadb/data:/var/lib/mysql
networks:
- my-network
adminer:
image: adminer:latest
restart: unless-stopped
ports:
- 8082:8080
networks:
- my-network
qbittorrent:
image: linuxserver/qbittorrent:latest
restart: unless-stopped
user: "root"
environment:
TZ: 'Australia/Melbourne'
ports:
- "8080:8080"
- "6881:6881"
- "6881:6881/udp"
volumes:
- /mnt/sda1/qbittorrent/config:/config
- /mnt/sda1/qbittorrent/downloads:/downloads
networks:
- my-network
homeassistant:
image: homeassistant/home-assistant:latest
restart: unless-stopped
environment:
- TZ=Australia/Melbourne
- PUID=1000
- PGID=1000
- UMASK=007
- PACKAGES=iputils
volumes:
- /mnt/sda1/homeassistant/config:/config
networks:
- my-network
jellyfin:
image: jellyfin/jellyfin:latest
restart: unless-stopped
user: "65536"
environment:
TZ: 'Australia/Melbourne'
volumes:
- /mnt/sda1/jellyfin/config:/config
- /mnt/sda1/jellyfin/cache:/cache
- /mnt/sda1/media:/media
networks:
- my-network
photoprism:
image: photoprism/photoprism:latest
restart: unless-stopped
ports:
- 2342:2342
environment:
TZ: 'Australia/Melbourne'
PHOTOPRISM_ADMIN_USER: "admin"
PHOTOPRISM_ADMIN_PASSWORD: "top_secret"
PHOTOPRISM_DATABASE_DRIVER: "mysql"
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
PHOTOPRISM_DATABASE_NAME: "photoprism"
PHOTOPRISM_DATABASE_USER: "photoprism"
PHOTOPRISM_DATABASE_PASSWORD: "top_secret"
PHOTOPRISM_SITE_URL: "https://photoprism.mywebsite.com/"
PHOTOPRISM_ORIGINALS_LIMIT: 1000
PHOTOPRISM_DEBUG: "false"
PHOTOPRISM_INDEX_WORKERS: 1
PHOTOPRISM_WORKERS: 1
volumes:
- "/mnt/sda1/photos:/photoprism/originals"
- "/mnt/sda1/photoprism/import:/photoprism/import"
- "/mnt/sda1/photoprism/storage:/photoprism/storage"
depends_on:
- mariadb
networks:
- my-network
bookstack:
image: linuxserver/bookstack:latest
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
- TZ=Australia/Melbourne
- APP_URL=https://bookstack.mywebsite.com
- DB_HOST=mariadb:3306
- DB_DATABASE=bookstack
- DB_USERNAME=bookstack
- DB_PASSWORD='top_secret'
volumes:
- /mnt/sda1/bookstack/config:/config
- /mnt/sda1/bookstack/uploads:/var/www/html/public/uploads
depends_on:
- mariadb
ports:
- "6875:80"
networks:
- my-network
watchtower:
image: containrrr/watchtower:latest
restart: unless-stopped
environment:
TZ: 'Australia/Melbourne'
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
networks:
- my-network
networks:
my-network:
driver: bridge
ipam:
config:
- subnet: 172.19.0.0/16
########################################################################
nginx.conf
########################################################################
Code: Select all
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# Upstream servers
upstream bookstack {
server bookstack:80;
}
upstream homeassistant {
server homeassistant:8123;
}
upstream jellyfin {
server jellyfin:8096;
}
upstream photoprism {
server photoprism:2342;
}
server {
listen 80;
server_name *.mywebsite.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
# HTTPS server block for Home Page
server {
listen 443 ssl;
server_name mywebsite.com;
# SSL/TLS configurations
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
# HTTPS server block for BookStack
server {
listen 443 ssl;
server_name bookstack.mywebsite.com;
# SSL/TLS configurations
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
location / {
proxy_pass http://bookstack;
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;
}
}
# HTTPS server block for Home Assistant
server {
listen 443 ssl;
server_name homeassistant.mywebsite.com;
# SSL/TLS configurations
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
location / {
proxy_pass http://homeassistant;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# HTTPS server block for Jellyfin
server {
listen 443 ssl;
server_name jellyfin.mywebsite.com;
# SSL/TLS configurations
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
location / {
proxy_pass http://jellyfin;
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;
}
}
# HTTPS server block for Photoprism
server {
listen 443 ssl;
server_name photoprism.mywebsite.com;
# SSL/TLS configurations
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
location / {
proxy_pass http://photoprism;
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;
}
}
}
########################################################################
MariaDB
########################################################################
Code: Select all
-- Create BookStack database and user
CREATE DATABASE IF NOT EXISTS bookstack;
CREATE USER IF NOT EXISTS 'bookstack'@'%' IDENTIFIED BY 'top_secret';
GRANT ALL PRIVILEGES ON bookstack.* TO 'bookstack'@'%';
-- Create Photoprism database and user
CREATE DATABASE IF NOT EXISTS photoprism;
CREATE USER IF NOT EXISTS 'photoprism'@'%' IDENTIFIED BY 'top_secret';
GRANT ALL PRIVILEGES ON photoprism.* TO 'photoprism'@'%';
FLUSH PRIVILEGES;
ALTER DATABASE bookstack
CHARACTER SET = 'utf8mb4'
COLLATE = 'utf8mb4_unicode_ci';
ALTER DATABASE photoprism
CHARACTER SET = 'utf8mb4'
COLLATE = 'utf8mb4_unicode_ci';
########################################################################