Configure Tailscale logging
mainTailscale logs are emitted using a dedicated Caddy logger named tailscale. You can customize the logging level or output using the standard Caddy log global option.
{
log tailscale {
level DEBUG
}
}repository·main·Indexed 21 days ago
https://github.com/tailscale/caddy-tailscaleA Caddy plugin that allows the web server to run a Tailscale node directly within its process. It enables Caddy to join a Tailnet, serve sites privately using the Tailscale network listener, proxy to other Tailnet devices, and authenticate users via the tailscale_auth directive without requiring a separate Tailscale client on the host.
Tailscale logs are emitted using a dedicated Caddy logger named tailscale. You can customize the logging level or output using the standard Caddy log global option.
{
log tailscale {
level DEBUG
}
}To use the Tailscale plugin, you must build a custom Caddy binary that includes it. The recommended way is using xcaddy.
Alternatively, you can build the included cmd/caddy package directly using go build.
# Using xcaddy (Recommended)
xcaddy build v2.9.1 --with github.com/tailscale/caddy-tailscale
# Using go build
go build ./cmd/caddyThe tailscale_auth directive sets up a Tailscale authentication provider in Caddy. It enforces that all incoming requests originate from a Tailscale user and populates the Caddy user object with Tailscale-specific identity metadata.
Key constraints:
Available User Fields:
When tailscale_auth is active, the following fields are available on the Caddy user object:
user.id: The Tailscale email-ish user ID.user.tailscale_login: The username portion of the Tailscale user ID.user.tailscale_user: Same as user.id.user.tailscale_name: The display name of the Tailscale user.user.tailscale_profile_picture: The URL of the Tailscale user's profile picture.user.tailscale_tailnet: The name of the Tailscale network the user is a member of.:80 {
tailscale_auth
}The Tailscale network listener allows Caddy to serve sites directly on your tailnet. Use the bind directive within a site block to specify a Tailscale network address.
tailscale/ (with a trailing slash) to use the default node configuration.tailscale/<node_name> to use a specific named node configuration.# Bind to the default Tailscale node
:80 {
bind tailscale/
}
# Bind to a specific named node
:80 {
bind tailscale/myapp
}
# Bind to multiple interfaces
:80 {
bind tailscale/myhost tailscale/my-other-host localhost
}Caddy can use Tailscale's HTTPS support to automatically issue certificates for your node's hostname.
ts.net hostname: No extra configuration is needed.tailscale certificate manager in the tls block.# Option 1: Full hostname (Automatic)
https://myhost.tail1234.ts.net {
bind tailscale/myhost
}
# Option 2: Partial hostname (Requires explicit cert manager)
:443 {
bind tailscale/myhost
tls {
get_certificate tailscale
}
}You can use a pre-built Docker image containing the plugin, or build your own using the provided Dockerfile.
When running via Docker, it is recommended to:
TS_AUTHKEY environment variable./config to persist the Tailscale state directory so nodes aren't re-registered on every restart./etc/caddy/Caddyfile.docker run -it --rm \
-e TS_AUTHKEY="tskey-auth-XXX" \
-v ./custom.caddyfile:/etc/caddy/Caddyfile -v ./config:config \
ghcr.io/tailscale/caddy-tailscaleUse the tailscale global option in your Caddyfile to define how Tailscale nodes are registered and managed. You can define global settings or specific named node configurations that override the globals.
Note: Nodes are only registered and connected to your tailnet when they are actually used (e.g., via a bind directive).
{
tailscale {
# Global settings
auth_key <auth_key>
ephemeral true
state_dir /var/lib/tailscale
# Named node override
my-app {
auth_key <different-key>
hostname custom-host
tags tag:production
}
}
}The Tailscale plugin provides a global tailscale directive for Caddyfiles to configure the App and its Nodes.
Basic syntax:
tailscale {
auth_key <key>
ephemeral
tags <tag1> <tag2>
node-name {
auth_key <key>
hostname <name>
}
}Note: For ephemeral and webui, providing the keyword without a value (e.g., just ephemeral) defaults the value to true during parsing.
tailscale {
auth_key tskey-auth-123
state_dir /var/lib/tailscale
web-server-node {
hostname caddy-node
port 443
tags tag:production
}
}The Transport module is a Caddy HTTP reverse proxy transport that routes requests through a Tailscale node. It allows Caddy to proxy traffic to services running on your Tailnet.
To use it, configure a reverse_proxy block in your Caddyfile and specify the tailscale transport followed by the name of the node you wish to use.
If no node name is provided, it defaults to caddy-proxy.
reverse_proxy {
transport tailscale my-node
}The Auth module is an HTTP authentication provider that identifies users based on their Tailscale identity. When a request is made through a Tailscale node, this provider extracts user metadata and attaches it to the Caddy User object.
LocalClient to call WhoIs based on the request's remote address.caddyauth.User.Metadata map:tailscale_login: The user's login name without the domain (e.g., user).tailscale_user: The user's full login name (e.g., user@example.com).tailscale_name: The user's display name.tailscale_profile_picture: The URL to the user's profile picture.tailscale_tailnet: The user's tailnet name (if the user is not connecting to a shared node).In a Caddyfile, you can use the tailscale_auth directive. It is registered to appear after basicauth in the directive order.
# Example Caddyfile usage (conceptual)
{
route {
tailscale_auth
# Subsequent handlers can access user.Metadata["tailscale_user"]
}
}You can pass Tailscale identity information to upstream applications (like Gitea or Grafana) by mapping the tailscale_auth user fields to HTTP headers using header_up within a reverse_proxy block. This is useful for applications that support proxy authentication.
:80 {
bind tailscale/gitea
tailscale_auth
reverse_proxy http://localhost:3000 {
header_up X-Webauth-User {http.auth.user.tailscale_login}
header_up X-Webauth-Email {http.auth.user.tailscale_user}
header_up X-Webauth-Name {http.auth.user.tailscale_name}
}
}The tailscale proxy transport allows Caddy to use a Tailscale node to connect to an upstream reverse proxy. This enables proxying non-Tailscale traffic to a node on your tailnet (similar to Tailscale Funnel).
In the reverse_proxy directive, you can specify a named node configuration. If no name is provided, the default caddy-proxy node is used. Note that the node name is separated by a space (not a slash) in the transport configuration.
:8080 {
reverse_proxy http://my-other-node:10000 {
transport tailscale myhost
}
}