Reach a tailnet
This guide puts xixo on a Tailscale network, including one coordinated by
Headscale, so it can attach storage, mail, and other services on machines
that have no public address. xixo joins the network as its own node through a tailscale
container. Each resource on the network names the tailnet resource as the one it is reached
through. See reaching through another resource.
You need a running xixo from self-hosting, and an auth key for the
network. On Headscale, headscale preauthkeys create --user <user> makes one.
Join the network
Section titled “Join the network”Add a tailscale service to the Compose project, and run xixo and worker in its network
namespace. Both reach the tailnet through it, and both share its socket so xixo can ask tailscaled
for its status.
x-xixo: &xixo environment: XIXO_TAILSCALE_SOCKET: /var/run/tailscale/tailscaled.sock volumes: - tailscale-socket:/var/run/tailscale
services: tailscale: image: tailscale/tailscale:stable hostname: xixo environment: TS_AUTHKEY: ... TS_STATE_DIR: /var/lib/tailscale TS_SOCKET: /var/run/tailscale/tailscaled.sock TS_USERSPACE: "false" TS_EXTRA_ARGS: --login-server=https://headscale.example.com cap_add: - NET_ADMIN devices: - /dev/net/tun:/dev/net/tun volumes: - tailscale:/var/lib/tailscale - tailscale-socket:/var/run/tailscale
xixo: <<: *xixo network_mode: service:tailscale
worker: <<: *xixo network_mode: service:tailscale
volumes: tailscale: tailscale-socket:Leave TS_EXTRA_ARGS off for Tailscale’s own coordination server. The auth key is used once. The
node’s identity is kept in the tailscale volume after that.
A container in another service’s network namespace has no networks or ports of its own. List the
networks xixo was on under tailscale instead, and point the reverse proxy at tailscale, which
now answers for xixo on port 80.
Limit what xixo reaches
Section titled “Limit what xixo reaches”xixo reaches every node the network lets it reach. Tag its node, and allow the tag only the services xixo should attach, in the tailnet’s access policy. A xixo that is compromised can then reach those services and nothing else on the network.
Check the tailnet resource
Section titled “Check the tailnet resource”With XIXO_TAILSCALE_SOCKET set, xixo declares a resource named tailnet in every tenant when it
boots, beside the resources in config/resources.yml. It is never attached by hand. Its check asks
tailscaled for its status, and passes when tailscaled reports Running.
Open Settings → Resources in the app. tailnet is under Networks. A failed check says what
tailscaled reported, such as tailscaled is NeedsLogin.
Attach a resource on the tailnet
Section titled “Attach a resource on the tailnet”Attach the resource as usual, give its address on the tailnet, and set Reached through to
tailnet. Through GraphQL, pass via: "tailnet" to attachResource. Name the node by its tailnet
address, such as http://100.64.0.5:8080. The container resolves names with its own resolver, which
does not know MagicDNS names.
A resource reached through tailnet connects only to addresses on the tailnet. An address elsewhere
fails with is not an address its transport reaches. When the tailnet is down, the resource’s check
fails with <key> is reached through tailnet, which is down.
To move an existing resource onto the tailnet, change it and set Reached through, or pass via
to updateResource. An empty via reaches it directly again.