Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ param_ports:
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).
Access the webui at `http://<docker host ip>:80`. For connecting via OPDS on a mobile device use `http://<docker host ip>:80/index.php/feed` or `http://<docker host ip>:80/feed`. It is strongly suggested that you reverse proxy this prior to exposing to the internet. For more information, such as requiring credentials, check the COPS Wiki (linked above).

The linuxserver version gives you access to `config/local.php` in `/config` to customise your install to suit your needs, it also includes the dependencies required to directly view epub books in your browser.
# init diagram
Expand DownExpand Up@@ -114,6 +114,8 @@ init_diagram: |
"cops:latest" <- Base Images
# changelog
changelogs:
- {date: "10.06.26:", desc: "Existing users should verify: site-confs/default.conf and config/local.php - Update redirect location and use front controller."}
- {date: "08.02.26:", desc: "Existing users should update: site-confs/default.conf - Deny access to all dotfiles."}
- {date: "08.02.26:", desc: "Adding missing php-tokenizer package."}
- {date: "10.10.25:", desc: "Adding missing icu-data-full package."}
- {date: "10.07.25:", desc: "Rebase to Alpine 3.22."}
Expand Down
13 changes: 9 additions & 4 deletions root/defaults/config/local.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,13 @@
*/
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";

/*
* Map /books/ to internal redirect location for COPS 4.2+
*/
$config['cops_x_accel_mapping'] = [
'/books/' => '/_redirect_/',
];

/* Enable cache folder
* especially useful for lower power hosts
*/
Expand DownExpand Up@@ -100,8 +107,6 @@
* - Nginx: nginx.conf
* - PHP built-in: router.php
* - ...
*
* @todo update nginx/site-confs/default.conf.sample to make use of front controller
*/
$config['cops_front_controller'] = '';
//$config['cops_front_controller'] = 'index.php';
//$config['cops_front_controller'] = '';
$config['cops_front_controller'] = 'index.php';
30 changes: 22 additions & 8 deletions root/defaults/nginx/site-confs/default.conf.sample
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
## Version 2025/07/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample
## Version 2026/02/10 - Changelog: https://github.com/linuxserver/docker-cops/commits/master/root/defaults/nginx/site-confs/default.conf.sample

server {
listen 80 default_server;
Expand DownExpand Up@@ -31,11 +31,6 @@ server {
expires 31d;
}

location /books {
root /;
internal;
}

location ~ ^(.+\.php)(.*)$ {
# enable the next two lines for http auth
#auth_basic "Restricted";
Expand All@@ -48,8 +43,27 @@ server {
include /etc/nginx/fastcgi_params;
}

# deny access to .htaccess/.htpasswd files
location ~ /\.ht {
# use internal redirect location for X-Accel-Redirect - do not use /books/ or other COPS urls with front controller
location /_redirect_/ {
internal;
alias /books/;
}

# use front controller for COPS 4.2+
location ~ ^/(?!(index\.php|_redirect_)) {
try_files $uri /index.php$request_uri;
}

# deny access to all dotfiles
location ~ /\. {
deny all;
log_not_found off;
access_log off;
return 404;
}

# Allow access to the ".well-known" directory
location ^~ /.well-known {
allow all;
}
}