- Document Docker + Tailscale sidecar architecture - Add Gitea secrets configuration guide - Add service management (add/remove/update) - Add troubleshooting section - Add Tailscale ACL configuration
355 lines
9.9 KiB
Markdown
355 lines
9.9 KiB
Markdown
# Seedbox Server
|
|
|
|
Docker-based seedbox with Tailscale integration. Each service runs in its own container with a Tailscale sidecar for secure HTTPS access via your tailnet.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ SEEDBOX │
|
|
│ │
|
|
│ Tailscale Host (SSH only) │
|
|
│ └─► seedbox.taila5ad8.ts.net │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ Docker Stacks │ │
|
|
│ │ │ │
|
|
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
|
│ │ │ Transmission│ │ Prowlarr │ │ Sonarr │ │ │
|
|
│ │ │ + ts-sidecar│ │ + ts-sidecar│ │ + ts-sidecar│ │ │
|
|
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
|
|
│ │ │ │ │ │ │
|
|
│ │ ▼ ▼ ▼ │ │
|
|
│ │ transmission. prowlarr. sonarr. │ │
|
|
│ │ taila5ad8.ts.net taila5ad8.ts.net taila5ad8.ts.net │ │
|
|
│ │ │ │
|
|
│ │ ┌─────────────┐ │ │
|
|
│ │ │ Portainer │ (optional, for monitoring) │ │
|
|
│ │ │ + ts-sidecar│ │ │
|
|
│ │ └─────────────┘ │ │
|
|
│ │ │ │ │
|
|
│ │ ▼ │ │
|
|
│ │ portainer.taila5ad8.ts.net │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ Storage: │
|
|
│ ├─ /srv/seedbox/downloads (local SSD) │
|
|
│ └─ /mnt/media (NFS from NAS) │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### 1. Server Installation
|
|
|
|
```bash
|
|
# With NFS mount
|
|
NFS_SERVER=nas curl -fsSL https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/seedbox/install.sh | bash
|
|
|
|
# Without NFS (configure later)
|
|
curl -fsSL https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/seedbox/install.sh | bash
|
|
```
|
|
|
|
### 2. Configure Gitea Secrets
|
|
|
|
Go to **Gitea > Repository > Settings > Secrets and Variables > Actions** and add:
|
|
|
|
| Secret | Description | Example |
|
|
|--------|-------------|---------|
|
|
| `TS_AUTHKEY` | Tailscale OAuth client secret | `tskey-client-xxxxx-yyyyyyyy` |
|
|
| `SEEDBOX_SSH_KEY` | SSH private key (ed25519) | `-----BEGIN OPENSSH PRIVATE KEY-----...` |
|
|
| `TRANSMISSION_USER` | Transmission WebUI username | `admin` |
|
|
| `TRANSMISSION_PASS` | Transmission WebUI password | `your-secure-password` |
|
|
|
|
#### Creating Tailscale OAuth Client
|
|
|
|
1. Go to https://login.tailscale.com/admin/settings/oauth
|
|
2. Click "Generate OAuth Client"
|
|
3. Scopes: `devices:write`
|
|
4. Copy the **Client Secret** (starts with `tskey-client-`)
|
|
|
|
#### Creating SSH Deploy Key
|
|
|
|
```bash
|
|
# Generate key pair
|
|
ssh-keygen -t ed25519 -f seedbox-deploy -N "" -C "gitea-deploy"
|
|
|
|
# Add public key to seedbox
|
|
ssh debian@seedbox.taila5ad8.ts.net "cat >> ~/.ssh/authorized_keys" < seedbox-deploy.pub
|
|
|
|
# Copy private key content to Gitea secret SEEDBOX_SSH_KEY
|
|
cat seedbox-deploy
|
|
```
|
|
|
|
#### Tailscale ACL Configuration
|
|
|
|
Add this tag to your Tailscale ACL policy (https://login.tailscale.com/admin/acls):
|
|
|
|
```json
|
|
{
|
|
"tagOwners": {
|
|
"tag:container": ["autogroup:admin"]
|
|
},
|
|
"acls": [
|
|
{
|
|
"action": "accept",
|
|
"src": ["autogroup:member"],
|
|
"dst": ["tag:container:*"]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 3. Deploy Services
|
|
|
|
Push to the `main` branch to trigger deployment:
|
|
|
|
```bash
|
|
git push origin main
|
|
```
|
|
|
|
Or create a PR for validation first.
|
|
|
|
## Services
|
|
|
|
| Service | URL | Port | Description |
|
|
|---------|-----|------|-------------|
|
|
| Transmission | `transmission.taila5ad8.ts.net` | 9091 | BitTorrent client |
|
|
| Prowlarr | `prowlarr.taila5ad8.ts.net` | 9696 | Indexer manager |
|
|
| Sonarr | `sonarr.taila5ad8.ts.net` | 8989 | TV series manager |
|
|
| Portainer | `portainer.taila5ad8.ts.net` | 9000 | Docker management UI |
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
/srv/seedbox/
|
|
├── stacks/
|
|
│ ├── transmission/
|
|
│ │ ├── docker-compose.yml
|
|
│ │ └── serve.json
|
|
│ ├── prowlarr/
|
|
│ │ ├── docker-compose.yml
|
|
│ │ └── serve.json
|
|
│ ├── sonarr/
|
|
│ │ ├── docker-compose.yml
|
|
│ │ └── serve.json
|
|
│ └── portainer/
|
|
│ ├── docker-compose.yml
|
|
│ └── serve.json
|
|
├── downloads/ # Local downloads (SSD)
|
|
├── .env # Secrets (created by pipeline)
|
|
└── .gitea/
|
|
└── workflows/
|
|
└── deploy.yml # Deployment pipeline
|
|
```
|
|
|
|
## Adding a New Service
|
|
|
|
1. Create a new directory in `stacks/`:
|
|
|
|
```bash
|
|
mkdir -p seedbox/stacks/myservice
|
|
```
|
|
|
|
2. Create `docker-compose.yml`:
|
|
|
|
```yaml
|
|
services:
|
|
ts-myservice:
|
|
image: tailscale/tailscale:latest
|
|
hostname: myservice
|
|
environment:
|
|
- TS_AUTHKEY=${TS_AUTHKEY}
|
|
- TS_EXTRA_ARGS=--advertise-tags=tag:container
|
|
- TS_STATE_DIR=/var/lib/tailscale
|
|
- TS_SERVE_CONFIG=/config/serve.json
|
|
- TS_USERSPACE=false
|
|
volumes:
|
|
- ts-state:/var/lib/tailscale
|
|
- ./serve.json:/config/serve.json:ro
|
|
devices:
|
|
- /dev/net/tun:/dev/net/tun
|
|
cap_add:
|
|
- net_admin
|
|
restart: unless-stopped
|
|
|
|
myservice:
|
|
image: myservice/image:latest
|
|
container_name: myservice
|
|
network_mode: service:ts-myservice
|
|
depends_on:
|
|
- ts-myservice
|
|
environment:
|
|
- PUID=1000
|
|
- PGID=1000
|
|
- TZ=Europe/Paris
|
|
volumes:
|
|
- config:/config
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
ts-state:
|
|
config:
|
|
```
|
|
|
|
3. Create `serve.json`:
|
|
|
|
```json
|
|
{
|
|
"TCP": {
|
|
"443": {
|
|
"HTTPS": true
|
|
}
|
|
},
|
|
"Web": {
|
|
"myservice.taila5ad8.ts.net:443": {
|
|
"Handlers": {
|
|
"/": {
|
|
"Proxy": "http://127.0.0.1:PORT"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
4. Commit and push:
|
|
|
|
```bash
|
|
git add seedbox/stacks/myservice/
|
|
git commit -m "feat(seedbox): add myservice stack"
|
|
git push origin main
|
|
```
|
|
|
|
## Removing a Service
|
|
|
|
### Option A: Via Git (recommended)
|
|
|
|
1. Remove the stack directory:
|
|
|
|
```bash
|
|
rm -rf seedbox/stacks/myservice/
|
|
git add -A
|
|
git commit -m "feat(seedbox): remove myservice stack"
|
|
git push origin main
|
|
```
|
|
|
|
2. Manually stop containers on seedbox:
|
|
|
|
```bash
|
|
ssh debian@seedbox.taila5ad8.ts.net
|
|
cd /srv/seedbox/stacks/myservice
|
|
docker compose down -v
|
|
```
|
|
|
|
3. Remove Tailscale device from admin console
|
|
|
|
### Option B: Manual (emergency)
|
|
|
|
```bash
|
|
ssh debian@seedbox.taila5ad8.ts.net
|
|
cd /srv/seedbox/stacks/myservice
|
|
docker compose down -v
|
|
rm -rf /srv/seedbox/stacks/myservice
|
|
# Remove device from https://login.tailscale.com/admin/machines
|
|
```
|
|
|
|
## Updating Services
|
|
|
|
### Update Docker Images
|
|
|
|
The pipeline automatically pulls latest images on each deployment. To force an update:
|
|
|
|
```bash
|
|
# Trigger a new deployment by making any change
|
|
git commit --allow-empty -m "chore: trigger deployment"
|
|
git push origin main
|
|
```
|
|
|
|
### Manual Update
|
|
|
|
```bash
|
|
ssh debian@seedbox.taila5ad8.ts.net
|
|
cd /srv/seedbox/stacks/transmission
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
## Network Access
|
|
|
|
| Service | Public | Tailscale |
|
|
|---------|--------|-----------|
|
|
| SSH | ❌ | ✅ `seedbox.taila5ad8.ts.net` |
|
|
| Transmission WebUI | ❌ | ✅ HTTPS via sidecar |
|
|
| Transmission Peer | ✅ Port 51413 | ✅ |
|
|
| Prowlarr | ❌ | ✅ HTTPS via sidecar |
|
|
| Sonarr | ❌ | ✅ HTTPS via sidecar |
|
|
| Portainer | ❌ | ✅ HTTPS via sidecar |
|
|
|
|
## Troubleshooting
|
|
|
|
### Check container status
|
|
|
|
```bash
|
|
docker ps -a
|
|
docker logs ts-transmission
|
|
docker logs transmission
|
|
```
|
|
|
|
### Check Tailscale sidecar
|
|
|
|
```bash
|
|
docker exec ts-transmission tailscale status
|
|
docker exec ts-transmission tailscale serve status
|
|
```
|
|
|
|
### Restart a stack
|
|
|
|
```bash
|
|
cd /srv/seedbox/stacks/transmission
|
|
docker compose restart
|
|
```
|
|
|
|
### View all Tailscale devices
|
|
|
|
```bash
|
|
tailscale status
|
|
```
|
|
|
|
### Force re-authentication of sidecar
|
|
|
|
```bash
|
|
cd /srv/seedbox/stacks/transmission
|
|
docker compose down
|
|
docker volume rm transmission_ts-state
|
|
docker compose up -d
|
|
```
|
|
|
|
## NAS Configuration (Synology)
|
|
|
|
Ensure your NAS exports the media share via NFS:
|
|
|
|
1. **Control Panel → Shared Folder → Edit → NFS Permissions**
|
|
2. Add rule:
|
|
- Hostname/IP: `100.64.0.0/10` (Tailscale subnet) or specific IP
|
|
- Privilege: Read/Write
|
|
- Squash: No mapping
|
|
- Security: sys
|
|
- Enable NFSv4.1: ✅
|
|
|
|
## Post-install Verification
|
|
|
|
```bash
|
|
# Check NFS mount
|
|
df -h /mnt/media
|
|
|
|
# Check Docker
|
|
docker ps
|
|
|
|
# Check Tailscale devices
|
|
tailscale status
|
|
|
|
# Test service access
|
|
curl -k https://transmission.taila5ad8.ts.net
|
|
```
|