Solved NGINX dokuwiki template rewrite rule for serving media library files

mmerlin

Verified User
Joined
Jul 26, 2004
Messages
76
Location
Melbourne, Australia
I am trying to migrate a Dokuwiki website from CPanel to DirectAdmin,

but nginx rewrites are partially failing, for the static images in the media library.

We have standalone nginx on Directadmin

I chose the Dokuwiki nginx template, and Dokuwiki internally is set to use nice URL's provided by NGINX

The nginx dokuwiki template looks OK, and most rewrites seem work, EXCEPT the static files in the media library fail to load with rewritten URL.

I have fully expanded my .conf file as shown below at the bottom of this post

NOTE: I commented out each include
and pasted in their actual text contents,
so we can see the full nginx.conf in it's entirety.


QUESTION #1:

Is one of the earlier nginx.conf "locations" that occur before the Dokuwiki rules, preventing the media library images rewrites from working?


QUESTION #2:

I think one possible over-ride to fix this is

Admin -> Server Manager -> Custom HTTPD Configurations

and then go to the line for the domain
-> nginx.conf proxy

and add some rules equivalent to the ones in
/etc/nginx/templates/dokuwiki.conf

NGINX:
#INFO=name=Dokuwiki

if (!-f $request_filename) {

    rewrite /_media/(.*) ${template_location}lib/exe/fetch.php?media=$relative_location last;

    rewrite /_detail/(.*) ${template_location}lib/exe/detail.php?media=$relative_location last;

    rewrite /_export/([^/]+)/(.*) ${template_location}doku.php?do=export_$1&id=$2 last;

    rewrite ^ ${template_location}doku.php?id=$relative_location last;

}

HOWEVER, using DirectAdmin "Custom HTTPD Configurations" is a bit different because |TOKENS| are required?

Is there an easy way to convert those 4 rewrite rules above,
into valid DirectAdmin Custom HTTPD Configurations syntax,
with the appropriate |TOKENS|




P.S. Here is the fully-expanded nginx.conf below as reference for Question #1

i.e. which "location" is serving the static files from media library,
before the following nginx template Dokuwiki rewrite rule can take effect:

rewrite /_media/(.*) ${template_location}lib/exe/fetch.php?media=$relative_location last;

NGINX:
# Auto generated nginx config file by DirectAdmin version 1.656
# Modifying this file is not recommended as any changes you make will be
# overwritten when the user makes any changes to their website
# For global config changes that affect all Users, see this guide:
# http://help.directadmin.com/item.php?id=558
# For local config changes that only affect one User, see this guide:
# http://help.directadmin.com/item.php?id=3

server
{
    listen 11.22.33.44:80;
    server_name help-center.example.com www.help-center.example.com ;
    access_log /var/log/nginx/domains/help-center.example.com.log;
    error_log /var/log/nginx/domains/help-center.example.com.error.log;
    root /home/helpcenter/domains/help-center.example.com/public_html;
    index index.php index.html index.htm;
    if ($http_x_forwarded_proto != 'https') {
        return 301 https://$host$request_uri;
    }
    if ($host = www.help-center.example.com){
        return 301 https://help-center.example.com$request_uri;
    }
####include /usr/local/directadmin/data/users/helpcenter/nginx_php.conf;
        # use fastcgi for all php files
        location ~ \.php$
        {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
  
            #include /etc/nginx/fastcgi_params;
            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
            fastcgi_param  REQUEST_SCHEME     $scheme;
            fastcgi_param  HTTPS              $https if_not_empty;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;

            # PHP only, required if PHP was built with --enable-force-cgi-redirect
            fastcgi_param  REDIRECT_STATUS    200;

  
  
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            if ( $skip_cache ~ "^$" ) {
                set $skip_cache 1;
            }
            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache $skip_cache;
            fastcgi_cache FASTCGICACHE;
            fastcgi_cache_valid 60m;
  
            #include /etc/nginx/nginx_limits.conf;
            fastcgi_buffer_size 128k;
            fastcgi_buffers 256 16k;
            fastcgi_busy_buffers_size 256k;
            fastcgi_temp_file_write_size 256k;
            fastcgi_send_timeout 600;
            fastcgi_read_timeout 600;
            fastcgi_intercept_errors on;
            fastcgi_param HTTP_PROXY "";

  
  
            if (-f $request_filename)
            {
                fastcgi_pass unix:/usr/local/php81/sockets/helpcenter.sock;
            }
        }



    # Mail auto configuration (Thunderbird)
    location = "/.well-known/autoconfig/mail/config-v1.1.xml" {
        proxy_pass http://unix:/usr/local/directadmin/shared/internal.sock;
        proxy_set_header X-Forwarded-For  $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
    }
 
    #include /etc/nginx/webapps.conf;
    location ~ /(\.htaccess|\.htpasswd|\.user\.ini|\.env|\.git) {
        deny all;
    }
    location ^~ /.well-known/acme-challenge {
        root /var/www/html/;
        index index.php index.html index.htm;
        location ~ ^/.well-known/acme-challenge/ {
            access_log off;
        set $my_server_addr $server_addr;
        if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
            proxy_pass http://$my_server_addr:8080;
            proxy_set_header X-Client-IP      $remote_addr;
            proxy_set_header X-Accel-Internal /.well-known/acme-challenge/nginx_static_files;
            proxy_set_header Host         $host;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_hide_header Upgrade;
        }
        location ~ ^/.well-known/acme-challenge/nginx_static_files/ {
            access_log  /var/log/nginx/access_log_proxy;
            alias       /var/www/html/;
            internal;
        }
    }
    location ^~ /roundcube {
        root /var/www/html/;
        index index.php index.html index.htm;
        location ~ ^/roundcube/ {
            access_log off;
        set $my_server_addr $server_addr;
        if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
            proxy_pass http://$my_server_addr:8080;
            proxy_set_header X-Client-IP      $remote_addr;
            proxy_set_header X-Accel-Internal /roundcube/nginx_static_files;
            proxy_set_header Host         $host;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_hide_header Upgrade;
        }
        location ~ ^/roundcube/nginx_static_files/ {
            access_log  /var/log/nginx/access_log_proxy;
            alias       /var/www/html/;
            internal;
        }
    }
    location ^~ /phpMyAdmin {
        root /var/www/html/;
        index index.php index.html index.htm;
        location ~ ^/phpMyAdmin/ {
            access_log off;
        set $my_server_addr $server_addr;
        if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
            proxy_pass http://$my_server_addr:8080;
            proxy_set_header X-Client-IP      $remote_addr;
            proxy_set_header X-Accel-Internal /phpMyAdmin/nginx_static_files;
            proxy_set_header Host         $host;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_hide_header Upgrade;
        }
        location ~ ^/phpMyAdmin/nginx_static_files/ {
            access_log  /var/log/nginx/access_log_proxy;
            alias       /var/www/html/;
            internal;
        }
    }
    location ~ ^/phpmyadmin {
        rewrite ^/* /phpMyAdmin last;
    }
    location ~ ^/pma {
        rewrite ^/* /phpMyAdmin last;
    }
    location ~ ^/webmail {
        rewrite ^/* /roundcube last;
    }

 
 
    location ~ "^()(/.*)?$"
    {
        set $template_location "$1/";
        set $relative_location "$2";

    ####include /etc/nginx/templates/dokuwiki.conf;
        #INFO=name=Dokuwiki
        if (!-f $request_filename) {
            rewrite /_media/(.*) ${template_location}lib/exe/fetch.php?media=$relative_location last;
            rewrite /_detail/(.*) ${template_location}lib/exe/detail.php?media=$relative_location last;
            rewrite /_export/([^/]+)/(.*) ${template_location}doku.php?do=export_$1&id=$2 last;
            rewrite ^ ${template_location}doku.php?id=$relative_location last;
        }



    ####include /usr/local/directadmin/data/users/helpcenter/nginx_php.conf;
        # use fastcgi for all php files
        location ~ \.php$
        {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
        ####include /etc/nginx/fastcgi_params;

            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
            fastcgi_param  REQUEST_SCHEME     $scheme;
            fastcgi_param  HTTPS              $https if_not_empty;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;

            # PHP only, required if PHP was built with --enable-force-cgi-redirect
            fastcgi_param  REDIRECT_STATUS    200;

            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            if ( $skip_cache ~ "^$" ) {
                set $skip_cache 1;
            }
            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache $skip_cache;
            fastcgi_cache FASTCGICACHE;
            fastcgi_cache_valid 60m;
  
            #include /etc/nginx/nginx_limits.conf;
            fastcgi_buffer_size 128k;
            fastcgi_buffers 256 16k;
            fastcgi_busy_buffers_size 256k;
            fastcgi_temp_file_write_size 256k;
            fastcgi_send_timeout 600;
            fastcgi_read_timeout 600;
            fastcgi_intercept_errors on;
            fastcgi_param HTTP_PROXY "";
 
  
            if (-f $request_filename)
            {
                fastcgi_pass unix:/usr/local/php81/sockets/helpcenter.sock;
            }
        }

    }
}
server
{
    listen 11.22.33.44:443 ssl http2;
    server_name help-center.example.com www.help-center.example.com ;
    access_log /var/log/nginx/domains/help-center.example.com.log;
    access_log /var/log/nginx/domains/help-center.example.com.bytes bytes;
    error_log /var/log/nginx/domains/help-center.example.com.error.log;
    root /home/helpcenter/domains/help-center.example.com/private_html;
    index index.php index.html index.htm;
    ssl_certificate /usr/local/directadmin/data/users/helpcenter/domains/help-center.example.com.cert.combined;
    ssl_certificate_key /usr/local/directadmin/data/users/helpcenter/domains/help-center.example.com.key;
    if ($host = www.help-center.example.com){
        return 301 https://help-center.example.com$request_uri;
    }
####include /usr/local/directadmin/data/users/helpcenter/nginx_php.conf;
        # use fastcgi for all php files
        location ~ \.php$
        {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;

            #include /etc/nginx/fastcgi_params;
            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
            fastcgi_param  REQUEST_SCHEME     $scheme;
            fastcgi_param  HTTPS              $https if_not_empty;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;

            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            if ( $skip_cache ~ "^$" ) {
                set $skip_cache 1;
            }
            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache $skip_cache;
            fastcgi_cache FASTCGICACHE;
            fastcgi_cache_valid 60m;
  
            #include /etc/nginx/nginx_limits.conf;
            fastcgi_buffer_size 128k;
            fastcgi_buffers 256 16k;
            fastcgi_busy_buffers_size 256k;
            fastcgi_temp_file_write_size 256k;
            fastcgi_send_timeout 600;
            fastcgi_read_timeout 600;
            fastcgi_intercept_errors on;
            fastcgi_param HTTP_PROXY "";

            if (-f $request_filename)
            {
                fastcgi_pass unix:/usr/local/php81/sockets/helpcenter.sock;
            }
        }

    # Mail auto configuration (Thunderbird)
    location = "/.well-known/autoconfig/mail/config-v1.1.xml" {
        proxy_pass http://unix:/usr/local/directadmin/shared/internal.sock;
        proxy_set_header X-Forwarded-For  $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
    }
 
 
    #include /etc/nginx/webapps.ssl.conf;
    location ~ /(\.htaccess|\.htpasswd|\.user\.ini|\.env|\.git) {
        deny all;
    }
    location ^~ /.well-known/acme-challenge {
        root /var/www/html/;
        index index.php index.html index.htm;
        location ~ ^/.well-known/acme-challenge/ {
            access_log off;
        set $my_server_addr $server_addr;
        if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
            proxy_pass https://$my_server_addr:8081;
            proxy_set_header X-Client-IP      $remote_addr;
            proxy_set_header X-Accel-Internal /.well-known/acme-challenge/nginx_static_files;
            proxy_set_header Host         $host;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_hide_header Upgrade;
        }
        location ~ ^/.well-known/acme-challenge/nginx_static_files/ {
            access_log  /var/log/nginx/access_log_proxy;
            alias       /var/www/html/;
            internal;
        }
    }
    location ^~ /roundcube {
        root /var/www/html/;
        index index.php index.html index.htm;
        location ~ ^/roundcube/ {
            access_log off;
        set $my_server_addr $server_addr;
        if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
            proxy_pass https://$my_server_addr:8081;
            proxy_set_header X-Client-IP      $remote_addr;
            proxy_set_header X-Accel-Internal /roundcube/nginx_static_files;
            proxy_set_header Host         $host;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_hide_header Upgrade;
        }
        location ~ ^/roundcube/nginx_static_files/ {
            access_log  /var/log/nginx/access_log_proxy;
            alias       /var/www/html/;
            internal;
        }
    }
    location ^~ /phpMyAdmin {
        root /var/www/html/;
        index index.php index.html index.htm;
        location ~ ^/phpMyAdmin/ {
            access_log off;
        set $my_server_addr $server_addr;
        if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
            proxy_pass https://$my_server_addr:8081;
            proxy_set_header X-Client-IP      $remote_addr;
            proxy_set_header X-Accel-Internal /phpMyAdmin/nginx_static_files;
            proxy_set_header Host         $host;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_hide_header Upgrade;
        }
        location ~ ^/phpMyAdmin/nginx_static_files/ {
            access_log  /var/log/nginx/access_log_proxy;
            alias       /var/www/html/;
            internal;
        }
    }
    location ~ ^/phpmyadmin {
        rewrite ^/* /phpMyAdmin last;
    }
    location ~ ^/pma {
        rewrite ^/* /phpMyAdmin last;
    }
    location ~ ^/webmail {
        rewrite ^/* /roundcube last;
    }

 
 
 
    location ~ "^()(/.*)?$"
    {
        set $template_location "$1/";
        set $relative_location "$2";
 
        #include /etc/nginx/templates/dokuwiki.conf;
        #INFO=name=Dokuwiki
        if (!-f $request_filename) {
            rewrite /_media/(.*) ${template_location}lib/exe/fetch.php?media=$relative_location last;
            rewrite /_detail/(.*) ${template_location}lib/exe/detail.php?media=$relative_location last;
            rewrite /_export/([^/]+)/(.*) ${template_location}doku.php?do=export_$1&id=$2 last;
            rewrite ^ ${template_location}doku.php?id=$relative_location last;
        }


    ####include /usr/local/directadmin/data/users/helpcenter/nginx_php.conf;
        # use fastcgi for all php files
        location ~ \.php$
        {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
  
            #include /etc/nginx/fastcgi_params;
            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;

            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
            fastcgi_param  REQUEST_SCHEME     $scheme;
            fastcgi_param  HTTPS              $https if_not_empty;

            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;

            # PHP only, required if PHP was built with --enable-force-cgi-redirect
            fastcgi_param  REDIRECT_STATUS    200;


            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            if ( $skip_cache ~ "^$" ) {
                set $skip_cache 1;
            }
            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache $skip_cache;
            fastcgi_cache FASTCGICACHE;
            fastcgi_cache_valid 60m;
  
            #include /etc/nginx/nginx_limits.conf;
            fastcgi_buffer_size 128k;
            fastcgi_buffers 256 16k;
            fastcgi_busy_buffers_size 256k;
            fastcgi_temp_file_write_size 256k;
            fastcgi_send_timeout 600;
            fastcgi_read_timeout 600;
            fastcgi_intercept_errors on;
            fastcgi_param HTTP_PROXY "";

            if (-f $request_filename)
            {
                fastcgi_pass unix:/usr/local/php81/sockets/helpcenter.sock;
            }
        }

    }
}
 
Last edited:
OK some more digging and I solved it!


I had to create a "Custom HTTP Configuration" rule for NGINX that transformed a few kinds of URL e.g.

HTML:
https://help-center.example.com/lib/exe/fetch.php?w=20&h=20&tok=4733a7&media=checkbox_blue_20x20px.png
into this one:
HTML:
https://help-center.example.com/lib/exe/fetch.php/checkbox_blue_20x20px.png?w=20&h=20&tok=4733a7


To do this I went into:
Admin -> Server Manager -> Custom HTTPD Configurations

and then click the line for that domain
-> nginx.conf proxy

and add two NGINX rewrite rules that enables Dokuwiki to serve the user-uploaded files stored in it's Media Library

NGINX:
location ~* ^/_media/(.*)$ {
    rewrite ^/_media/(.*)$ /lib/exe/fetch.php/$1? last;
}
location ~* ^/lib/exe/fetch\.php/(.*)$ {
    rewrite ^/lib/exe/fetch\.php/(.*)$ /lib/exe/fetch.php?media=$1&$args last;
}


I added this in the top part (not the lower ones Custom1, Custom2, Custom3, Custom4)



Then I went to Services and on Nginx selected a "reload" action

and it all works now!

P.S. Perhaps these extra lines can be added to the default Dokuwiki nginx template, so any other Media Library users don't have the same issue :)
 
Last edited:
Back
Top