diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..589e016f --- /dev/null +++ b/examples/README.md @@ -0,0 +1,5 @@ +# Examples + +This folder contains runnable, friendly examples for integrating Zerobyte with common tooling. + +- [Tailscale sidecar](tailscale-sidecar/README.md): run Zerobyte behind a Tailscale container using the sidecar networking pattern. diff --git a/examples/tailscale-sidecar/.env.example b/examples/tailscale-sidecar/.env.example new file mode 100644 index 00000000..dcecd934 --- /dev/null +++ b/examples/tailscale-sidecar/.env.example @@ -0,0 +1,16 @@ +# --- Zerobyte --- +TZ=UTC + +# --- Tailscale --- +# Create an auth key in the Tailscale admin console. +# Recommended: ephemeral + pre-approved (or tagged) key. +TS_AUTHKEY=tskey-auth-xxxxxxxxxxxxxxxxxxxx + +# How this node should appear in your tailnet. +TS_HOSTNAME=zerobyte + +# Optional extra args passed to `tailscale up`. +# Examples: +# TS_EXTRA_ARGS=--accept-dns=true +# TS_EXTRA_ARGS=--advertise-tags=tag:backup --accept-routes +TS_EXTRA_ARGS= diff --git a/examples/tailscale-sidecar/README.md b/examples/tailscale-sidecar/README.md new file mode 100644 index 00000000..7b86ecc4 --- /dev/null +++ b/examples/tailscale-sidecar/README.md @@ -0,0 +1,64 @@ +# Zerobyte + Tailscale sidecar (Docker Compose) + +This example runs Zerobyte behind a Tailscale sidecar container so the Zerobyte web UI/API can be reached over your tailnet and Zerobyte can access other devices on your tailnet (based on the ACLs/tags you configure in Tailscale). + +It uses a common “sidecar networking” pattern: +- The `tailscale` container brings up a Tailscale node +- The `zerobyte` container shares the `tailscale` network namespace (`network_mode: service:tailscale`) + +## About Tailscale + +Tailscale is a mesh VPN built on WireGuard. It connects devices and containers into a private network (“tailnet”) without opening inbound ports on your router or exposing services directly to the public internet. + +In this example, Tailscale acts as a secure access layer in front of Zerobyte: +- You reach Zerobyte using the node’s tailnet IP/DNS name. +- Access can be restricted using Tailscale ACLs/tags. + +## Prerequisites + +- Docker + Docker Compose +- A Tailscale account and an auth key + +This compose file runs Tailscale in kernel (non-userspace) mode (`TS_USERSPACE=false`), which requires: +- `/dev/net/tun` available on the host +- the `NET_ADMIN` capability +- the `SYS_MODULE` capability (as configured in the compose file) + +## Setup + +1. Copy the env file and fill in your auth key: + ```bash + cp .env.example .env + ``` + +2. Start the stack: + ```bash + docker compose up -d + ``` + +3. In the Tailscale admin console, confirm the node is present (and approved if your policy requires it). + +## Access + +- Over Tailscale: `http://:4096` or `http://:4096` +- Locally (optional): the example publishes `4096:4096` on the host + +If you want Zerobyte to be reachable only via Tailscale, remove the `ports:` section from the `tailscale` service in [docker-compose.yml](docker-compose.yml). + +## Notes + +- `network_mode: service:tailscale` makes Zerobyte share the Tailscale container’s *entire* network namespace (interfaces + routing table). +- Traffic to tailnet IPs (typically `100.x.y.z`) goes over `tailscale0` and is governed by Tailscale ACLs; traffic to your LAN/Internet may still go over the normal network interface depending on routes and host firewall. +- Zerobyte still needs `SYS_ADMIN` and `/dev/fuse` if you intend to mount NFS/SMB/WebDAV volumes from inside the container. + +The example uses these environment variables (see [.env.example](.env.example)): +- `TS_AUTHKEY` (required) +- `TS_HOSTNAME` (optional) +- `TS_EXTRA_ARGS` (optional; passed to `tailscale up`) +- `TZ` (optional) + +## Troubleshooting + +- If the `tailscale` container can’t start due to missing TUN support, ensure your host has `/dev/net/tun` available and that Docker is allowed to use it. +- If your tailnet uses ACLs/tags, set `TS_EXTRA_ARGS` accordingly (for example `--advertise-tags=tag:backup`). +- If the `tailscale` container fails due to `SYS_MODULE` (common on Docker Desktop / restricted hosts), switch to userspace mode by setting `TS_USERSPACE=true` in the compose file and remove `SYS_MODULE` from `cap_add`. diff --git a/examples/tailscale-sidecar/docker-compose.yml b/examples/tailscale-sidecar/docker-compose.yml new file mode 100644 index 00000000..ac3d8c00 --- /dev/null +++ b/examples/tailscale-sidecar/docker-compose.yml @@ -0,0 +1,49 @@ +services: + tailscale: + image: tailscale/tailscale:stable + container_name: zerobyte-tailscale + hostname: ${TS_HOSTNAME:-zerobyte} + restart: unless-stopped + cap_add: + - NET_ADMIN + # Required for Kernel native Tailscale (not userspace mode) + - SYS_MODULE + devices: + - /dev/net/tun:/dev/net/tun + environment: + - TS_AUTHKEY=${TS_AUTHKEY} + - TS_STATE_DIR=/var/lib/tailscale + # Use Kernel native Tailscale (not userspace mode) + - TS_USERSPACE=false + # Optional flags passed to `tailscale up`. + # Examples: + # - --advertise-tags=tag:zerobyte + # - --accept-dns=true --accept-routes + - TS_EXTRA_ARGS=${TS_EXTRA_ARGS:-} + volumes: + - tailscale-state:/var/lib/tailscale + # If you only want access over Tailscale (not from the local network), remove this. + ports: + - "4096:4096" + + zerobyte: + image: ghcr.io/nicotsx/zerobyte:latest + container_name: zerobyte + restart: unless-stopped + # Share the Tailscale network namespace (sidecar pattern) + network_mode: service:tailscale + depends_on: + - tailscale + devices: + - /dev/fuse:/dev/fuse + cap_add: + - SYS_ADMIN + environment: + - TZ=${TZ:-UTC} + volumes: + - /etc/localtime:/etc/localtime:ro + - zerobyte-data:/var/lib/zerobyte + +volumes: + tailscale-state: + zerobyte-data: