Run Example Caddy Module

1. Output of caddy version:

./caddy version
v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

2. How I run Caddy:

a. System environment:

MacOS

b. Command:

./caddy run

Running my locally built version here.

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

{
	debug
}

route / {
	visitor_ip
}

:2015 {

	respond "hello, world!"
}

3. The problem I’m having:

I’m leaning how to extend Caddy with modules with the extending caddy tutorial. However, there are no instructions on how to put together a Caddyfile nor a caddy.json to run the hello world.

4. Error messages and/or full log output:

./caddy run
2023/01/18 19:01:01.716	INFO	using adjacent Caddyfile
Error: adapting config using caddyfile: Caddyfile:6: unrecognized directive: visitor_ip
xcaddy list-modules
2023/01/18 14:58:57 [INFO] Temporary folder: /Users/crismar/workspace/golang/misc/caddy_gizmo/buildenv_2023-01-18-1458.3097065933
2023/01/18 14:58:57 [INFO] Writing main module: /Users/crismar/workspace/golang/misc/caddy_gizmo/buildenv_2023-01-18-1458.3097065933/main.go
package main

import (
	caddycmd "github.com/caddyserver/caddy/v2/cmd"

	// plug in Caddy modules here
	_ "github.com/caddyserver/caddy/v2/modules/standard"
	_ "gizmo"
)

func main() {
	caddycmd.Main()
}
2023/01/18 14:58:57 [INFO] Initializing Go module
2023/01/18 14:58:57 [INFO] exec (timeout=10s): /Users/crismar/.asdf/shims/go mod init caddy
go: creating new go.mod: module caddy
go: to add module requirements and sums:
	go mod tidy
2023/01/18 14:58:57 [INFO] Replace gizmo => /Users/crismar/workspace/golang/misc/caddy_gizmo
2023/01/18 14:58:57 [INFO] exec (timeout=10s): /Users/crismar/.asdf/shims/go mod edit -replace gizmo=/Users/crismar/workspace/golang/misc/caddy_gizmo
2023/01/18 14:58:58 [INFO] Pinning versions
2023/01/18 14:58:58 [INFO] exec (timeout=0s): /Users/crismar/.asdf/shims/go get -d -v github.com/caddyserver/caddy/v2
go: added github.com/beorn7/perks v1.0.1
go: added github.com/caddyserver/caddy/v2 v2.6.2
go: added github.com/caddyserver/certmagic v0.17.2
go: added github.com/cespare/xxhash/v2 v2.1.2
go: added github.com/fsnotify/fsnotify v1.5.1
go: added github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
go: added github.com/golang/mock v1.6.0
go: added github.com/golang/protobuf v1.5.2
go: added github.com/google/uuid v1.3.0
go: added github.com/klauspost/cpuid/v2 v2.1.1
go: added github.com/libdns/libdns v0.2.1
go: added github.com/lucas-clemente/quic-go v0.29.2
go: added github.com/marten-seemann/qpack v0.2.1
go: added github.com/marten-seemann/qtls-go1-18 v0.1.3
go: added github.com/marten-seemann/qtls-go1-19 v0.1.1
go: added github.com/matttproud/golang_protobuf_extensions v1.0.1
go: added github.com/mholt/acmez v1.0.4
go: added github.com/miekg/dns v1.1.50
go: added github.com/nxadm/tail v1.4.8
go: added github.com/onsi/ginkgo v1.16.4
go: added github.com/prometheus/client_golang v1.12.2
go: added github.com/prometheus/client_model v0.2.0
go: added github.com/prometheus/common v0.32.1
go: added github.com/prometheus/procfs v0.7.3
go: added go.uber.org/atomic v1.9.0
go: added go.uber.org/multierr v1.6.0
go: added go.uber.org/zap v1.23.0
go: added golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
go: added golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
go: added golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
go: added golang.org/x/net v0.0.0-20220812165438-1d4ff48094d1
go: added golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10
go: added golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
go: added golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b
go: added golang.org/x/tools v0.1.10
go: added golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f
go: added google.golang.org/protobuf v1.28.0
go: added gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
2023/01/18 14:58:58 [INFO] exec (timeout=0s): /Users/crismar/.asdf/shims/go get -d -v
go: added gizmo v0.0.0-00010101000000-000000000000
2023/01/18 14:59:00 [INFO] Build environment ready
2023/01/18 14:59:00 [INFO] Building Caddy
2023/01/18 14:59:00 [INFO] exec (timeout=0s): /Users/crismar/.asdf/shims/go mod tidy
2023/01/18 14:59:00 [INFO] exec (timeout=0s): /Users/crismar/.asdf/shims/go build -o /Users/crismar/workspace/golang/misc/caddy_gizmo/caddy -ldflags -w -s -trimpath
2023/01/18 14:59:02 [INFO] Build complete: ./caddy
2023/01/18 14:59:02 [INFO] Cleaning up temporary folder: /Users/crismar/workspace/golang/misc/caddy_gizmo/buildenv_2023-01-18-1458.3097065933
2023/01/18 14:59:02 [INFO] Running [./caddy list-modules]

admin.api.load
admin.api.metrics
admin.api.pki
admin.api.reverse_proxy
caddy.adapters.caddyfile
caddy.config_loaders.http
caddy.listeners.http_redirect
caddy.listeners.tls
caddy.logging.encoders.console
caddy.logging.encoders.filter
caddy.logging.encoders.filter.cookie
caddy.logging.encoders.filter.delete
caddy.logging.encoders.filter.hash
caddy.logging.encoders.filter.ip_mask
caddy.logging.encoders.filter.query
caddy.logging.encoders.filter.regexp
caddy.logging.encoders.filter.rename
caddy.logging.encoders.filter.replace
caddy.logging.encoders.json
caddy.logging.writers.discard
caddy.logging.writers.file
caddy.logging.writers.net
caddy.logging.writers.stderr
caddy.logging.writers.stdout
caddy.storage.file_system
events
http
http.authentication.hashes.bcrypt
http.authentication.hashes.scrypt
http.authentication.providers.http_basic
http.encoders.gzip
http.encoders.zstd
http.handlers.acme_server
http.handlers.authentication
http.handlers.copy_response
http.handlers.copy_response_headers
http.handlers.encode
http.handlers.error
http.handlers.file_server
http.handlers.headers
http.handlers.map
http.handlers.metrics
http.handlers.push
http.handlers.request_body
http.handlers.reverse_proxy
http.handlers.rewrite
http.handlers.static_response
http.handlers.subroute
http.handlers.templates
http.handlers.tracing
http.handlers.vars
http.matchers.expression
http.matchers.file
http.matchers.header
http.matchers.header_regexp
http.matchers.host
http.matchers.method
http.matchers.not
http.matchers.path
http.matchers.path_regexp
http.matchers.protocol
http.matchers.query
http.matchers.remote_ip
http.matchers.vars
http.matchers.vars_regexp
http.precompressed.br
http.precompressed.gzip
http.precompressed.zstd
http.reverse_proxy.selection_policies.cookie
http.reverse_proxy.selection_policies.first
http.reverse_proxy.selection_policies.header
http.reverse_proxy.selection_policies.ip_hash
http.reverse_proxy.selection_policies.least_conn
http.reverse_proxy.selection_policies.random
http.reverse_proxy.selection_policies.random_choose
http.reverse_proxy.selection_policies.round_robin
http.reverse_proxy.selection_policies.uri_hash
http.reverse_proxy.transport.fastcgi
http.reverse_proxy.transport.http
http.reverse_proxy.upstreams.a
http.reverse_proxy.upstreams.multi
http.reverse_proxy.upstreams.srv
pki
tls
tls.certificates.automate
tls.certificates.load_files
tls.certificates.load_folders
tls.certificates.load_pem
tls.certificates.load_storage
tls.client_auth.leaf
tls.get_certificate.http
tls.get_certificate.tailscale
tls.handshake_match.remote_ip
tls.handshake_match.sni
tls.issuance.acme
tls.issuance.internal
tls.issuance.zerossl
tls.stek.distributed
tls.stek.standard

  Standard modules: 99

http.handlers.visitor_ip

  Non-standard modules: 1

  Unknown modules: 0

5. What I already tried:

  • I tried adding debug to get more information.
  • I found a guide in the forum, Validating GitHub Webhook Requests in Caddy and its GitHub repo that gives a good example on how to write the config for a http.handlers module. I followed the style but didn’t solve my issue.

6. Links to relevant resources:

You need to use xcaddy run to extend Caddy and then run it; ./caddy run will just run the Caddy binary in your current folder.

Directives must go inside a site block.

1 Like

It works! I had to put the directive inside the block as Francis Pointed out. Also, my Output field was not being exported, I had output.

You need to use xcaddy run to extend Caddy and then run it; ./caddy run will just run the Caddy binary in your current folder.

I was using xcaddy build to generate the binary but turns out it doesn’t contain my plugin. Does that mean that if I want to use this plugin in production I would have to use xcaddy.

1 Like

You need to use xcaddy build --with <your-module> to make a build with your plugin. See the xcaddy README for instructions.

1 Like