Rewrite for heimdall dashboard

1. Caddy version (caddy version):

v2.4.5

2. How I run Caddy:

I run Caddy v2 as a jail in truenas 12.

a. System environment:

I run Caddy as a jail in truenas.
Jail version: 12.2-release-p6

b. Command:

service caddy start

c. Service/unit/compose file:

#!/bin/sh

# PROVIDE: caddy
# REQUIRE: LOGIN DAEMON NETWORKING
# KEYWORD: shutdown

# To enable caddy, add 'caddy_enable="YES"' to /etc/rc.conf or
# /etc/rc.conf.local

# Optional settings:
# caddy_config (string):      Full path to caddy config file
#                             (/usr/local/etc/caddy/Caddyfile)
# caddy_adapter (string):     Config adapter type (caddyfile)
# caddy_directory (string):   Root for caddy storage (ACME certs, etc.)
#                             (/var/db/caddy)
# caddy_extra_flags (string): Extra flags passed to caddy start
# caddy_logdir (string):      Where caddy logs are stored
#                             (/var/log/caddy)
# caddy_logfile (string):     Location of process log (${caddy_logdir}/caddy.log)
#                             This is for startup/shutdown/error messages.
#                             To create an access log, see:
#                             caddyserver.com/docs/caddyfile/directives/log
# caddy_user (user):          User to run caddy (root)
# caddy_group (group):        Group to run caddy (wheel)
#
# This script will honor XDG_CONFIG_HOME/XDG_DATA_HOME. Caddy will create a
# .../caddy subdir in each of those. By default, they are subdirs of /var/db/caddy.
# See caddyserver.com/docs/conventions#data-directory

. /etc/rc.subr

name=caddy
rcvar=caddy_enable
desc="Powerful, enterprise-ready, open source web server with automatic HTTPS written in Go"

load_rc_config $name

# Defaults
: ${caddy_enable:=NO}
: ${caddy_adapter:=caddyfile}
: ${caddy_config:=/usr/local/etc/caddy/Caddyfile}
: ${caddy_directory:=/var/db/caddy}
: ${caddy_extra_flags:=""}
: ${caddy_logdir:="/var/log/${name}"}
: ${caddy_logfile:="${caddy_logdir}/${name}.log"}
: ${caddy_user:="root"}
: ${caddy_group:="wheel"}

# Config and base directories
: ${XDG_CONFIG_HOME:="${caddy_directory}/config"}
: ${XDG_DATA_HOME:="${caddy_directory}/data"}
export XDG_CONFIG_HOME XDG_DATA_HOME

command="/usr/local/bin/${name}"
caddy_flags="--config ${caddy_config} --adapter ${caddy_adapter}"
pidfile="/var/run/${name}/${name}.pid"

required_files="${caddy_config} ${command}"

start_precmd="caddy_precmd"
start_cmd="caddy_start"
stop_cmd="caddy_stop"

# Extra Commands
extra_commands="configtest reload"
configtest_cmd="caddy_command validate ${caddy_flags}"
reload_cmd="caddy_command reload ${caddy_flags}"

caddy_command()
{
        /usr/bin/su -m "${caddy_user}" -c "${command} $*"
}

caddy_precmd()
{
        # Create required directories and set permissions
        /usr/bin/install -d -m 755 -o "${caddy_user}" -g "${caddy_group}" ${caddy_directory}
        /usr/bin/install -d -m 700 -o "${caddy_user}" -g "${caddy_group}" ${caddy_directory}/config
        /usr/bin/install -d -m 700 -o "${caddy_user}" -g "${caddy_group}" ${caddy_directory}/data
        /usr/bin/install -d -m 755 -o "${caddy_user}" -g "${caddy_group}" ${caddy_logdir}
        /usr/bin/install -d -m 700 -o "${caddy_user}" -g "${caddy_group}" /var/run/caddy
}

caddy_start()
{
        echo -n "Starting caddy... "
        /usr/bin/su -m ${caddy_user} -c "${command} start ${caddy_flags} \
                ${caddy_extra_flags} --pidfile ${pidfile}" >> ${caddy_logfile} 2>&1
        if [ $? -eq 0 ] && ps -ax -o pid | grep -q "$(cat ${pidfile})"; then
                echo "done"
                echo "Log: ${caddy_logfile}"
        else
                echo "Error: Caddy failed to start"
                echo "Check the caddy log: ${caddy_logfile}"
        fi
}

caddy_stop()
{
        echo -n "Stopping caddy... "
        if caddy_command stop; then
                echo "done"
        else
                echo "Error: Unable to stop caddy"
                echo "Check the caddy log: ${caddy_logfile}"
        fi
}

run_rc_command "$1"

d. My complete Caddyfile or JSON config:

{
        acme_dns duckdns <APIKEY>
}

myheimdalldomain.duckdns.org {
   encode gzip
   reverse_proxy https://10.10.10.150:443 {
         transport http {
               tls_insecure_skip_verify
           }
    }
}

3. The problem I’m having:

I’d like to redirect the heimdall dashboard to a subfolder: mydomain.duckdns.org/heimdall
As expected SSL works if I don’t redirect Heimdall to a subfolder. But I’ve seen people getting the redirect to work here: Problem using Caddy · Issue #295 · linuxserver/Heimdall · GitHub
But I’m having a hard time adapting the config so I can get it to work with my caddy file.

myheimdalldomain.com {
  tls user@email.org
  gzip
  root /var/www/heimdall/public
  fastcgi / 127.0.0.19000 php {
    index /index.php
  }
  rewrite {
    to {path} {path}/ /index.php?{query}
  }
}

4. Error messages and/or full log output:

No errors. The caddyfile loads normally

5. What I already tried:

redir /heimdall /heimdall/*
handle_path /heimdall/* {
       rewrite * /index.php?{query}
       reverse_proxy http://10.10.10.150:80
   }

When I surf to my URL via Caddy, all the layout is gone. And all I see is text (see picture)
Left side vs right side:

6. Links to relevant resources:

If you’re trying to use a subpath because you want to serve other services alongside it, use a subdomain instead like heimdall.yourdomain.duckdns.org.

See this article which explains why it’s difficult to proxy to a subpath if the app isn’t set up for it:

1 Like

Dear Francis,

Thank you for your reply. I’ll take that route then.
However I have one question… How does one know what, where and when to use special rewrite rules or special parameters to get the subfolder url working?

It seems I just lack the knowledge to make a proper config for the subfolder url. The simple or popular things (pihole, calibre, sonarr, radarr…) all work with a subfolder url because they either have a “reverse proxy” option builtin (like sonarr, radarr) or I found them while googling…

My intuition says I just have to put Caddy in debug mode and look at the logs and adjust the Caddyfile accordingly… However will the debug logs show everything to make a proper config so the subfolder url will eventually work?

Kind regards,
Vlackho

I’m not really sure how to answer that question.

Some apps were designed properly such that they allow a configurable base path. This is necessary so they put that base path on all their URLs and assets in HTML (like the JS/CSS/image includes, etc)

If the apps didn’t take that into consideration, then there’s really not much you can do to make it work. Simple rewrites will usually not be enough, because the actual HTML content will still point to the wrong places (not having the base path as a prefix, using the root of your domain instead).

This topic was automatically closed after 30 days. New replies are no longer allowed.