Repository navigation
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
146 lines (142 loc) · 6.24 KB
/
Copy pathdocker-compose.yml
File metadata and controls
146 lines (142 loc) · 6.24 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# TuneCamp Docker Compose Configuration
# Quick start:
# docker compose up -d --build
#
# Default web UI: http://localhost:1970 (Admin: admin / admin)
#
# Don't edit this file to fit your server. Two seams keep your deployment
# separate from the repo, so `git pull` never conflicts with it:
# .env — values (ports, paths, secrets, API keys)
# docker-compose.override.yml — structure (extra services, networks,
# container names, labels, volumes). Compose
# merges it automatically; it is gitignored.
# Start from docker-compose.override.yml.example.
services:
tunecamp:
build:
context: .
args:
- TUNECAMP_RPC_URL=${TUNECAMP_RPC_URL:-https://mainnet.base.org}
- TUNECAMP_CURRENCY_CONTRACT=${TUNECAMP_CURRENCY_CONTRACT:-0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913}
image: tunecamp:latest
container_name: tunecamp
ports:
- "${TUNECAMP_PORT:-1970}:1970"
volumes:
# TUNECAMP_MUSIC_PATH is the folder ON THE HOST holding your audio files.
# It is a Compose-only variable: it decides what gets mounted, nothing
# more. Inside the container that folder is always /music, which is what
# TUNECAMP_MUSIC_DIR below points the server at. Set MUSIC_PATH, not
# MUSIC_DIR, when running under Docker.
- ${TUNECAMP_MUSIC_PATH:-./music}:/music
# Persistent data (SQLite database, downloaded content, uploads)
- tunecamp_data:/data
env_file:
# A fresh clone has no .env and every value below already has a default,
# so a missing file must not abort the first start. Long syntax needs
# Compose v2.24+.
- path: .env
required: false
environment:
# Core Paths & Port
- NODE_ENV=production
- TUNECAMP_PORT=1970
# In-container library path. Fixed: it is the mount target above.
- TUNECAMP_MUSIC_DIR=/music
- TUNECAMP_DB_PATH=/data/tunecamp.db
- TUNECAMP_DOWNLOAD_DIR=${TUNECAMP_DOWNLOAD_DIR:-/data/downloads}
# Initial Admin credentials (change upon first login)
- TUNECAMP_ADMIN_USER=${TUNECAMP_ADMIN_USER:-admin}
- TUNECAMP_ADMIN_PASS=${TUNECAMP_ADMIN_PASS:-admin}
# Network & Federation
- TUNECAMP_PUBLIC_URL=${TUNECAMP_PUBLIC_URL:-}
- TUNECAMP_SITE_NAME=${TUNECAMP_SITE_NAME:-TuneCamp}
- TUNECAMP_JWT_SECRET=${TUNECAMP_JWT_SECRET:-}
- TUNECAMP_FEDERATION_SEEDS=${TUNECAMP_FEDERATION_SEEDS:-}
# Web3 / Payments (Base Network)
- TUNECAMP_RPC_URL=${TUNECAMP_RPC_URL:-https://mainnet.base.org}
- TUNECAMP_CURRENCY_CONTRACT=${TUNECAMP_CURRENCY_CONTRACT:-0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913}
- TUNECAMP_OWNER_ADDRESS=${TUNECAMP_OWNER_ADDRESS:-}
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY:-}
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET:-}
- STRIPE_ONRAMP_SECRET_KEY=${STRIPE_ONRAMP_SECRET_KEY:-}
# Integrations & Metadata
- DISCOGS_TOKEN=${DISCOGS_TOKEN:-}
- TUNECAMP_TELEGRAM_BOT_TOKEN=${TUNECAMP_TELEGRAM_BOT_TOKEN:-}
- TUNECAMP_TELEGRAM_MASTER_ID=${TUNECAMP_TELEGRAM_MASTER_ID:-}
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY:-}
- OPENROUTER_MODEL=${OPENROUTER_MODEL:-openai/gpt-4o-mini}
- TUNECAMP_GDRIVE_CLIENT_ID=${TUNECAMP_GDRIVE_CLIENT_ID:-}
- TUNECAMP_GDRIVE_CLIENT_SECRET=${TUNECAMP_GDRIVE_CLIENT_SECRET:-}
# Email & Monitoring
- BREVO_API_KEY=${BREVO_API_KEY:-}
- BREVO_SENDER_EMAIL=${BREVO_SENDER_EMAIL:-}
- SENTRY_DSN=${SENTRY_DSN:-}
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "curl -f http://127.0.0.1:1970/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 45s
# Optional public URL for instances with no domain and no port forwarding
# (a home machine behind NAT). Opt in with:
# docker compose --profile tunnel up -d
# srv.us is a free, signup-free SSH reverse tunnel: it answers the connection
# with an https://<id>.srv.us address that forwards here. The address is
# derived from the SSH key, so keeping the key in the data volume keeps the
# URL stable across restarts — which matters, because federation identity and
# any link shared with a listener are tied to it.
#
# Per srv.us's own docs: traffic is not recorded, but the bandwidth you use is
# consumed twice on their side, and heavy usage may be throttled unless you
# contribute financially. A music library is exactly the heavy case — fine for
# a handful of listeners, not for a public music site. Get a real domain
# before that point.
tunnel:
profiles: ["tunnel"]
image: alpine:3.20
container_name: tunecamp-tunnel
depends_on:
- tunecamp
volumes:
- tunecamp_data:/data
# ExitOnForwardFailure turns a refused forward into a container restart
# instead of an idle connection that looks alive but tunnels nothing.
# Literal block (|), not folded (>): a folded scalar keeps the line breaks of
# more-indented lines, which silently splits a wrapped command into separate
# ones. Every continuation below is an explicit backslash.
command:
- sh
- -c
- |
set -e
echo "[tunnel] Installing openssh-client..."
apk add --no-cache openssh-client
mkdir -p /data/ssh
if [ ! -f /data/ssh/id_ed25519 ]; then
echo "[tunnel] Generating SSH key..."
ssh-keygen -t ed25519 -N '' -f /data/ssh/id_ed25519
echo "[tunnel] Key generated."
else
echo "[tunnel] SSH key already exists."
fi
# Verify the key is valid before connecting
if [ ! -s /data/ssh/id_ed25519 ]; then
echo "[tunnel] ERROR: key file is empty or missing!" >&2
exit 1
fi
echo "[tunnel] Key fingerprint:"
ssh-keygen -l -f /data/ssh/id_ed25519
echo "[tunnel] Connecting to srv.us..."
exec ssh -i /data/ssh/id_ed25519 \
-o UserKnownHostsFile=/data/ssh/known_hosts \
-o StrictHostKeyChecking=accept-new \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-R 1:tunecamp:1970 srv.us 2>&1
restart: unless-stopped
volumes:
tunecamp_data:
driver: local