1. The problem I’m having:
Hi folks,
I want to redirect /tag/<foo>
to /tags/<foo>
and /post/<bar>
to /posts/<bar>
in lighttpd i was able to do this like so:
url.redirect = (
"^/post/(.*)" => "/posts/$1",
"^/tag/(.*)" => "/tags/$1",
)
i have tried various options, such as:
redir /tag/* /tags/
this doesn’t include suffix string, just always goes to /tags/, so i guess i need to use regular expressions?
redir path_regexp old ^/tag/(.*)$ /tags/{re.old.1}
this results in this error: Feb 18 18:53:28 arch1 caddy[135705]: Error: adapting config using caddyfile: parsing caddyfile tokens for 'redir': Not a supported redir code type or not valid integer: 'old', at /etc/caddy/Caddyfile:57
i have tried
# redir path_regex ^/tag/(.*) /tags/
which results in Feb 18 18:55:17 arch1 caddy[135724]: Error: adapting config using caddyfile: parsing caddyfile tokens for 'redir': Not a supported redir code type or not valid integer: '^/tag/(.*)', at /etc/caddy/Caddyfile:56
finally i came up with this config:
@old path_regexp old ^/tag/(.*)$
redir @old /tags/{re.old.1}
@oldposts path_regexp postp ^/post/(.*)$
redir @oldposts /posts/{re.oldp.1}
this one works fine for tags, however for posts, it always redirects to /posts ignoring the regex match. eg curl output:
> GET /post/practical-fault-detection-redux-next-generation-alerting-now-as-presentation/ HTTP/2
> Host: dieter-dev.plaetinck.be
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/2 302
< alt-svc: h3=":443"; ma=2592000
< location: /posts/
< server: Caddy
< content-length: 0
< date: Sun, 18 Feb 2024 18:45:06 GMT
<
* Connection #0 to host dieter-dev.plaetinck.be left intact
2. Error messages and/or full log output:
had some trouble copypasting logs properly. but hopefully the issue is obvious enough
3. Caddy version:
v2.7.6
4. How I installed and ran Caddy:
pacman -S caddy # i use arch, btw
a. System environment:
I use arch linux, btw.
b. Command:
it auto starts
c. Service/unit/compose file:
[root@arch1 http]# caddy version
v2.7.6
[root@arch1 http]# locate caddy.service
/usr/lib/systemd/system/caddy.service
[root@arch1 http]# cat /usr/lib/systemd/system/caddy.service
# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.
[Unit]
Description=Caddy web server
Documentation=https://caddyserver.com/docs/
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
StartLimitIntervalSec=14400
StartLimitBurst=10
[Service]
Type=notify
User=caddy
Group=caddy
Environment=XDG_DATA_HOME=/var/lib
Environment=XDG_CONFIG_HOME=/etc
ExecStartPre=/usr/bin/caddy validate --config /etc/caddy/Caddyfile
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
ExecStopPost=/usr/bin/rm -f /run/caddy/admin.socket
# Do not allow the process to be restarted in a tight loop. If the
# process fails to start, something critical needs to be fixed.
Restart=on-abnormal
# Use graceful shutdown with a reasonable timeout
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
# Hardening options
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
DevicePolicy=closed
LockPersonality=true
MemoryAccounting=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
ProcSubset=pid
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=strict
RemoveIPC=true
ReadWritePaths=/var/lib/caddy /var/log/caddy /run/caddy
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
[Install]
WantedBy=multi-user.target
d. My complete Caddy config:
# The Caddyfile is an easy way to configure your Caddy web server.
#
# https://caddyserver.com/docs/caddyfile
#
# The configuration below serves a welcome page over HTTP on port 80.
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace the line below with your
# domain name.
#
# https://caddyserver.com/docs/caddyfile/concepts#addresses
{
# Restrict the admin interface to a local unix file socket whose directory
# is restricted to caddy:caddy. By default the TCP socket allows arbitrary
# modification for any process and user that has access to the local
# interface. If admin over TCP is turned on one should make sure
# implications are well understood.
admin "unix//run/caddy/admin.socket"
}
(cors) {
@origin header Origin {args[0]}
header @origin Access-Control-Allow-Origin "{args[0]}"
header @origin Access-Control-Allow-Methods "OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE"
}
https://src.tapas.fit {
import cors https://tapas.fit
root * /srv/http/tapas
reverse_proxy /waitlist 127.0.01:6000
file_server
log
}
https://tapas.fit {
root * /srv/http/tapas
file_server
log
}
https://e.tapas.fit {
reverse_proxy https://app.posthog.com:443 {
header_up Host app.posthog.com
header_down -Access-Control-Allow-Origin
}
import cors https://tapas.fit
}
https://dieter-dev.plaetinck.be {
root * /srv/http/dieter-dev
# failures:
# rewrite /tag/* /tags/ # doesn't include suffix str, just goes to /tags/
redir path_regex ^/tag/(.*) /tags/ # ??
#redir path_regexp old ^/tag/(.*)$ /tags/{re.old.1} # startup error
# this works, but is a bit clunky
# @old path_regexp old ^/tag/(.*)$
# redir @old /tags/{re.old.1}
# @oldposts path_regexp postp ^/post/(.*)$
# redir @oldposts /posts/{re.oldp.1}
root /files/ /srv/http/files
file_server
log
}
import /etc/caddy/conf.d/*