Lego-deprecated on FreeBSD – how to pass environment variables?

1. Caddy version (caddy version):

v2.4.6

2. How I run Caddy:

As installed by this script

a. System environment:

Caddy runs in an iocage jail on TrueNAS (FreeBSD) 12

b. Command:

service caddy start

c. Service/unit/compose file:

n/a

d. My complete Caddyfile or JSON config:

{
        # acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
        email sysadmin@glod.studio
}

:2020 {
        respond "Hello, world!"
}

cumulus.glod.studio {
        encode gzip
        reverse_proxy http://10.188.0.33
}

warden.glod.studio {
        encode gzip
        reverse_proxy http://10.188.0.43:4567

collabora.glod.studio {
        encode gzip
        @collabora {
                path /loleaflet/* # Loleaflet is the client part of LibreOffice
                path /hosting/discovery # WOPI discovery URL
                path /hosting/capabilities # Show capabilities as json
                path /lool/* # Main websocket, uploads/downloads, presentations
        }
        reverse_proxy @collabora http://10.188.0.35:9980
}

octoprint.lan.glod.studio {
       reverse_proxy http://10.188.0.44:5000
       tls {
               dns lego_deprecated domeneshop
       }

3. The problem I’m having:

I’ve been using Caddy for a while as a reverse proxy for a couple of public services (Nextcloud/Collabora, Vaultwarden) and it’s worked well so far.

I would also like to use Caddy as a reverse proxy for some internal web interfaces (Node-Red and Octoprint, plus a few others). I’ll need to use the DNS challenge as the subdomain .lan.glod.studio is internal only and has no A record. The only support for my provider (Domeneshop) is by means of the lego-deprecated plugin. I’ll need to set the Domeneshop API token and secret using environment variables, but I must admit I can’t figure out how to pass those to Caddy.

4. Error messages and/or full log output:

{"level":"info","ts":1644186567.9219067,"msg":"using provided configuration","config_file":"/usr/local/www/Caddyfile","config_adapter":"caddyfile"}
{"level":"info","ts":1644186567.9241796,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["localhost:2019","[::1]:2019","127.0.0.1:2019"]}
{"level":"info","ts":1644186567.9243329,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc00063f6c0"}
{"level":"info","ts":1644186567.9243772,"logger":"tls.cache.maintenance","msg":"stopped background certificate maintenance","cache":"0xc00063f6c0"}
run: loading initial config: loading new config: loading http app module: provision http: getting tls app: loading tls app module: provision tls: provisioning automation policy 0: loading TLS automation management module: position 0: loading module 'acme': provision tls.issuance.acme: loading DNS provider module: loading module 'lego_deprecated': provision dns.providers.lego_deprecated: domeneshop: some credentials information are missing: DOMENESHOP_API_TOKEN,DOMENESHOP_API_SECRET
start: caddy process exited with error: exit status 1

5. What I already tried:

To get started I just tried using setenv (FreeBSD’s equivalent to export),

setenv DOMENESHOP_API_TOKEN mytoken
setenv DOMENESHOP_API_SECRET mysecret

And I checked the output of env to make sure that they’d been properly set. Didn’t work. I also tried using rc.conf,

sysrc caddy_env="DOMENESHOP_API_TOKEN=mytoken DOMENESHOP_API_SECRET=mysecret"

and a reboot, but that didn’t work either.

6. Links to relevant resources:

Installation script

I don’t use FreeBSD, so I don’t have an answer for that.

@basil, thoughts?

I’m totally new to FreeBSD as well, so it’s taking some getting used to. To be honest I don’t even know if my question is mainly about Caddy, or if it’s really more about FreeBSD or TrueNAS or iocage or something else entirely :slight_smile:

For what it’s worth, here’s the rc.d that starts Caddy as a service. I’m looking at this to figure out how I might get the environment variables set when starting the iocage jail, but I don’t know if that will help. Maybe it’s moot, seeing as it didn’t work when I set the variables using setenv either.

#!/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:
#                             https://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 https://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"

And GOT IT! I added

DOMENESHOP_API_TOKEN=x
export DOMENESHOP_API_TOKEN
DOMENESHOP_API_SECRET=x
export DOMENESHOP_API_SECRET

above #Defaults in the rc.d script and it works perfectly. I have a feeling this isn’t best practice, it feels a bit hacky, but then again, so is using a deprecated plugin. It’ll do for now.

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