Repository navigation
Expand file tree
/
Copy pathdocker-compose.stack.yml
More file actions
106 lines (102 loc) · 4.87 KB
/
Copy pathdocker-compose.stack.yml
File metadata and controls
106 lines (102 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Tawny — downloadable stack.
#
# This is the compose file to hand another machine. Like docker-compose.yml it
# pulls a prebuilt image and never builds — it just also carries no .env
# defaults, so it drops straight into Portainer (Stacks -> Add stack ->
# Repository, or -> URL) or a plain `docker compose -f`.
#
# The default image is the published one, ghcr.io/pressf4me/tawny:latest, built
# and pushed by .github/workflows/release.yml on a vX.Y.Z tag. Override
# TAWNY_IMAGE only for a fork or private mirror — to build that image, see
# "Building it yourself" in README.md.
# ---------------------------------------------------------------------------
# DEPLOY on the other machine
#
# Portainer: Stacks -> Add stack -> Web editor (paste this) or Repository
# (its URL). In "Environment variables" set at least:
#
# TAWNY_IMAGE = ghcr.io/pressf4me/tawny:latest (optional — this is the default)
# TS_AUTHKEY = tskey-auth-... (https://login.tailscale.com/admin/settings/keys
# -> Reusable, Ephemeral OFF)
#
# CLI: echo 'TAWNY_IMAGE=ghcr.io/pressf4me/tawny:latest' > .env
# echo 'TS_AUTHKEY=tskey-auth-...' >> .env
# docker compose -f docker-compose.stack.yml up -d
#
# Then approve the subnet route once at
# https://login.tailscale.com/admin/machines, and check http://<box>:8099/setup.
# Everything else is in README.md.
#
# Host networking is load-bearing: the container has to see the real LAN
# interface to know which subnet to advertise into the tailnet, to reach the
# Monitor phone's own relay, and to give coturn real addresses. If your
# Portainer environment forbids host networking, use the bridge variant at the
# bottom — it works, but you supply the LAN CIDR by hand (TS_ROUTES) and it
# cannot open the phone's LAN relay for a browser, so a remote Viewer then
# depends on the phone falling back to the cloud rendezvous + coturn.
name: tawny
services:
tawny:
# Defaults to the published image. Pin a version with TAWNY_TAG (e.g.
# 2.0.3), or point TAWNY_IMAGE at a full ref for a fork / private mirror.
image: "${TAWNY_IMAGE:-ghcr.io/pressf4me/tawny:${TAWNY_TAG:-latest}}"
# A plain `docker compose up -d` re-pulls, so a pushed rebuild lands on the
# next `up` / stack update without a manual `docker pull`.
pull_policy: always
container_name: tawny
restart: unless-stopped
network_mode: host
volumes:
- tawny-data:/data
#
# The host's tailscaled socket, if it has one. Harmless when it does not:
# only used when TS_AUTHKEY is empty. Read-only — the CLI only connects.
- /var/run/tailscale:/var/run/tailscale:ro
environment:
PORT: "8099"
# Two ways in, picked automatically. Set an auth key from
# https://login.tailscale.com/admin/settings/keys (Reusable, not
# Ephemeral) and the container joins as its own node. Leave it empty and
# it drives the host's existing tailscaled through the socket above,
# reusing that machine's identity. Empty with no host daemon is LAN-only.
# /setup says which of the three you got.
TS_AUTHKEY: "${TS_AUTHKEY:-}"
TS_HOSTNAME: "${TS_HOSTNAME:-tawny}"
# Empty = the subnet this container is on (right under host networking).
# off by default: see docker-compose.yml. /setup turns it on live and
# remembers the answer, and will not call the deployment finished
# until you have answered one way or the other.
TS_ROUTES: "${TS_ROUTES-off}"
TS_SERVE: "${TS_SERVE:-on}"
# All optional; leave blank. The container derives its own address from
# each request and generates its TURN secret at startup. See DESIGN.md.
ALLOWED_HOSTS: "${TAWNY_ALLOWED_HOSTS:-}"
STUN_URLS: "${TAWNY_STUN_URLS:-stun:stun.l.google.com:19302,stun:stun.cloudflare.com:3478}"
RENDEZVOUS_URL: "${TAWNY_RENDEZVOUS_URL:-}"
TURN_MODE: "auto"
TURN_EMBEDDED: "${TAWNY_TURN_EMBEDDED:-on}"
TURN_PORT: "3478"
TAWNY_PUBLIC_IP: "${TAWNY_PUBLIC_IP:-}"
TAWNY_TURN_URLS: "${TAWNY_TURN_URLS:-}"
TAWNY_TURN_SECRET: "${TAWNY_TURN_SECRET:-}"
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8099/healthz | grep -q '\"ok\":true'"]
interval: 30s
timeout: 5s
retries: 3
start_period: 5s
volumes:
tawny-data:
# --- bridge variant, if host networking is not available --------------------
#
# Replace `network_mode: host` with the ports block below, and set TS_ROUTES to
# the LAN CIDR the Monitor phone is on (e.g. 192.168.1.0/24) — the container
# cannot see it for itself from behind a bridge. The /lan bridge that lets a
# browser reach the phone's own relay does not work from here either, so a
# remote Viewer relies on the phone's cloud-rendezvous fallback plus coturn.
#
# ports:
# - "8099:8099"
# - "3478:3478/udp"
# - "3478:3478/tcp"
# - "49160-49200:49160-49200/udp"