diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3023577 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.gitea +.vdo-ninja-source +README.md +LICENSE +CONTRIBUTING.md +docker-compose.yml +.ki-workspace +*.md +!vdo-ninja-source/**/*.md diff --git a/.gitea/workflows/daily-docker.yml b/.gitea/workflows/daily-docker.yml new file mode 100644 index 0000000..ed505bb --- /dev/null +++ b/.gitea/workflows/daily-docker.yml @@ -0,0 +1,107 @@ +# VDO.Ninja Docker - Daily Build +# Prüft täglich um 20:00 Uhr (MESZ) auf Updates und baut ein neues Docker Image +# Quelle: https://github.com/steveseguin/vdo.ninja + +name: 🐳 Daily Docker Build + +on: + schedule: + # 18:00 UTC = 20:00 MESZ (Sommerzeit) / 19:00 MEZ (Winterzeit) + - cron: '0 18 * * *' + workflow_dispatch: + +env: + IMAGE_NAME: vdo-ninja + UPSTREAM_REPO: https://github.com/steveseguin/vdo.ninja + +jobs: + check-and-build: + name: 🔍 Update-Check & Build + runs-on: ubuntu-latest + + steps: + - name: 📥 Checkout Repository + uses: actions/checkout@v4 + + - name: 🔍 Auf VDO.Ninja Updates prüfen + id: check + run: | + # Neuesten Versions-Tag vom Upstream ermitteln (z.B. v29.0) + UPSTREAM_TAG=$(git ls-remote --tags --sort=-v:refname ${{ env.UPSTREAM_REPO }} 'v*' | head -n1 | sed 's/.*refs\/tags\///' | sed 's/\^{}//') + if [ -z "$UPSTREAM_TAG" ]; then + echo "::error::Kein Versions-Tag im Upstream-Repo gefunden." + exit 1 + fi + echo "upstream_tag=${UPSTREAM_TAG}" >> "$GITHUB_OUTPUT" + + # Registry-URL bereinigen (Protokoll entfernen) + REGISTRY="${{ vars.REGISTRY_URL }}" + REGISTRY="${REGISTRY#https://}" + REGISTRY="${REGISTRY#http://}" + echo "registry=${REGISTRY}" >> "$GITHUB_OUTPUT" + + # Prüfen ob ein Image mit diesem Versions-Tag bereits existiert + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ + -u "${{ secrets.REGISTRY_USER }}:${{ secrets.REGISTRY_TOKEN }}" \ + "${{ vars.REGISTRY_URL }}/v2/${{ secrets.REGISTRY_USER }}/${{ env.IMAGE_NAME }}/manifests/${UPSTREAM_TAG}" \ + -H "Accept: application/vnd.docker.distribution.manifest.v2+json" 2>/dev/null || echo "000") + + if [ "$HTTP_CODE" = "200" ] && [ "${{ github.event_name }}" != "workflow_dispatch" ]; then + echo "✅ Image mit Version ${UPSTREAM_TAG} existiert bereits. Build wird übersprungen." + echo "should_build=false" >> "$GITHUB_OUTPUT" + else + echo "🆕 Neue Version ${UPSTREAM_TAG} erkannt. Image wird gebaut." + echo "should_build=true" >> "$GITHUB_OUTPUT" + fi + + - name: 📦 VDO.Ninja Quellcode klonen + if: steps.check.outputs.should_build == 'true' + run: | + git clone --depth 1 ${{ env.UPSTREAM_REPO }} vdo-ninja-source + echo "📋 VDO.Ninja Commit: $(cd vdo-ninja-source && git rev-parse --short HEAD)" + + - name: 🔐 Login zur Container Registry + if: steps.check.outputs.should_build == 'true' + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY_URL }} + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: 🛠️ Docker Buildx einrichten + if: steps.check.outputs.should_build == 'true' + uses: docker/setup-buildx-action@v3 + + - name: 🏗️ Docker Image bauen und pushen + if: steps.check.outputs.should_build == 'true' + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + ${{ steps.check.outputs.registry }}/${{ secrets.REGISTRY_USER }}/${{ env.IMAGE_NAME }}:latest + ${{ steps.check.outputs.registry }}/${{ secrets.REGISTRY_USER }}/${{ env.IMAGE_NAME }}:${{ steps.check.outputs.upstream_tag }} + labels: | + org.opencontainers.image.title=VDO.Ninja + org.opencontainers.image.description=Self-hosted VDO.Ninja - Free browser-based peer-to-peer video streaming + org.opencontainers.image.version=${{ steps.check.outputs.upstream_tag }} + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.upstream=https://github.com/steveseguin/vdo.ninja + org.opencontainers.image.licenses=AGPL-3.0 + + - name: 📊 Build-Zusammenfassung + if: always() + run: | + if [ "${{ steps.check.outputs.should_build }}" = "true" ]; then + echo "### 🐳 Docker Build Zusammenfassung" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Eigenschaft | Wert |" >> $GITHUB_STEP_SUMMARY + echo "|---|---|" >> $GITHUB_STEP_SUMMARY + echo "| **Image** | \`${{ env.IMAGE_NAME }}\` |" >> $GITHUB_STEP_SUMMARY + echo "| **VDO.Ninja Version** | \`${{ steps.check.outputs.upstream_tag }}\` |" >> $GITHUB_STEP_SUMMARY + echo "| **Tags** | \`latest\`, \`${{ steps.check.outputs.upstream_tag }}\` |" >> $GITHUB_STEP_SUMMARY + else + echo "### ✅ Kein Update erforderlich" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "VDO.Ninja Version \`${{ steps.check.outputs.upstream_tag }}\` ist bereits als Image vorhanden." >> $GITHUB_STEP_SUMMARY + fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd530fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Geklonter VDO.Ninja Quellcode (wird nur im CI verwendet) +vdo-ninja-source/ +.vdo-ninja-source/ diff --git a/.ki-workspace b/.ki-workspace new file mode 100644 index 0000000..e69de29 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fbdecdc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,35 @@ +# VDO.Ninja Docker Image +# Basierend auf nginx:alpine für minimale Imagegröße +# Quelle: https://github.com/steveseguin/vdo.ninja + +FROM nginx:alpine + +LABEL maintainer="Patrick Asmus " +LABEL org.opencontainers.image.title="VDO.Ninja" +LABEL org.opencontainers.image.description="Self-hosted VDO.Ninja - Free browser-based, peer-to-peer video streaming" +LABEL org.opencontainers.image.source="https://github.com/steveseguin/vdo.ninja" +LABEL org.opencontainers.image.licenses="AGPL-3.0" + +# Eigene nginx-Konfiguration +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# VDO.Ninja Quelldateien (wird im CI-Workflow geklont) +COPY vdo-ninja-source/ /usr/share/nginx/html/ + +# Nicht benötigte Dateien entfernen +RUN rm -rf /usr/share/nginx/html/.git \ + /usr/share/nginx/html/.github \ + /usr/share/nginx/html/.gitignore \ + /usr/share/nginx/html/.prettierrc \ + /usr/share/nginx/html/CONTRIBUTING.md \ + /usr/share/nginx/html/install.md \ + /usr/share/nginx/html/turnserver_install.sh.sample \ + /usr/share/nginx/html/turnserver_basic.conf \ + /usr/share/nginx/html/turnserver.md \ + /usr/share/nginx/html/turnsetup.sh \ + /usr/share/nginx/html/turn-credentials-php.sample + +EXPOSE 80 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget -qO- http://localhost:80/ || exit 1 diff --git a/README.md b/README.md index df7ff0a..910defe 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,223 @@ -# template_repository +# 🐳 VDO.Ninja Docker + +Automatisiertes Docker Image für [VDO.Ninja](https://github.com/steveseguin/vdo.ninja) – die kostenlose, browserbasierte Peer-to-Peer-Video-Streaming-Lösung. + +Dieses Repository baut täglich ein aktuelles Docker Image aus dem originalen VDO.Ninja-Quellcode und stellt es über die Gitea Container Registry bereit. +--- +## 📋 Übersicht -Wichtig: Link für Lizenz anpassen. +[VDO.Ninja](https://vdo.ninja) (ehemals OBS.Ninja) ermöglicht es, Video- und Audiostreams direkt im Browser zu teilen – ohne Server, ohne Accounts, ohne Software-Installation. Es wird häufig in Kombination mit OBS Studio verwendet, um Gäste remote in Livestreams einzubinden. +Da das Original-Repository **kein offizielles Docker Image** anbietet, übernimmt dieses Projekt den automatisierten Build und die Bereitstellung als Docker Container. +### ✨ Features + +- 🔄 **Täglicher automatischer Build** – Prüft täglich um 20:00 Uhr auf neue Commits +- 🧠 **Intelligenter Update-Check** – Baut nur, wenn sich im Upstream etwas geändert hat +- 🏷️ **Versionierte Tags** – Jedes Image wird mit Upstream-Version (z.B. `v29.0`) und `latest` getaggt +- 🪶 **Leichtgewichtig** – Basiert auf `nginx:alpine` für minimale Imagegröße +- 🔒 **Security Headers** – Nginx-Konfiguration mit Sicherheits-Headern +- 📦 **Gzip-Komprimierung** – Optimierte Auslieferung der statischen Dateien +- ❤️ **Healthcheck** – Integrierter Docker-Healthcheck + +--- + +## 🚀 Schnellstart + +### Docker Run + +```bash +docker run -d \ + --name vdo-ninja \ + -p 8080:80 \ + --restart unless-stopped \ + git.techniverse.net/scriptos/vdo-ninja:latest +``` + +Danach ist VDO.Ninja unter `http://localhost:8080` erreichbar. Alle verfügbaren Versionen findest du in der [📦 Container Registry](https://git.techniverse.net/scriptos/-/packages/container/vdo-ninja). + +### Docker Compose + +Eine fertige `docker-compose.yml` liegt im Repository: + +```bash +docker compose up -d +``` + +Oder manuell erstellen: + +```yaml +services: + vdo-ninja: + image: git.techniverse.net/scriptos/vdo-ninja:latest + container_name: vdo-ninja + restart: unless-stopped + ports: + - "8080:80" +``` + +--- + +## ⚙️ Konfiguration + +### 🔌 Ports + +| Container-Port | Beschreibung | +|---|---| +| `80` | HTTP (Nginx Webserver) | + +Der Container lauscht intern auf Port `80`. Über `-p` oder `ports:` kann dieser auf einen beliebigen Host-Port gemappt werden. + +### 🔐 Reverse Proxy (empfohlen) + +> **Wichtig:** WebRTC benötigt eine sichere Verbindung (HTTPS). Für den produktiven Einsatz sollte ein Reverse Proxy mit TLS-Terminierung vorgeschaltet werden. + +#### Beispiel: Traefik (via Docker Labels) + +```yaml +services: + vdo-ninja: + image: git.techniverse.net/scriptos/vdo-ninja:latest + container_name: vdo-ninja + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.vdo-ninja.rule=Host(`vdo.example.de`)" + - "traefik.http.routers.vdo-ninja.entrypoints=websecure" + - "traefik.http.routers.vdo-ninja.tls.certresolver=letsencrypt" + - "traefik.http.services.vdo-ninja.loadbalancer.server.port=80" + networks: + - proxy + +networks: + proxy: + external: true +``` + +#### Beispiel: Caddy + +``` +vdo.example.de { + reverse_proxy vdo-ninja:80 +} +``` + +--- + +## 🔄 Automatische Updates + +Der Gitea Workflow (`.gitea/workflows/daily-docker.yml`) prüft **täglich um 20:00 Uhr (MESZ)** ob es neue Commits im [originalen VDO.Ninja Repository](https://github.com/steveseguin/vdo.ninja) gibt. + +### So funktioniert der Update-Check: + +1. 🔍 **Versions-Tag abrufen** – Der neueste Versions-Tag (z.B. `v29.0`) wird via `git ls-remote` vom Upstream abgefragt +2. 🏷️ **Registry prüfen** – Es wird geprüft, ob ein Image mit diesem Versions-Tag bereits in der Registry existiert +3. 🏗️ **Nur bei neuer Version bauen** – Ein neues Image wird nur gebaut, wenn die Version noch nicht vorhanden ist +4. 📤 **Push zur Registry** – Das fertige Image wird mit `latest` und dem Versions-Tag in die Registry gepusht + +### ⏰ Zeitplan + +| Zeitzone | Uhrzeit | +|---|---| +| MESZ (Sommerzeit) | 20:00 Uhr | +| MEZ (Winterzeit) | 19:00 Uhr | +| UTC | 18:00 Uhr | + +> Der Workflow kann jederzeit auch manuell über die Gitea-Oberfläche gestartet werden (`workflow_dispatch`). + +--- + +## 📦 Image-Tags + +| Tag | Beschreibung | +|---|---| +| `latest` | Immer das neueste Build | +| `vX.Y` | VDO.Ninja Upstream-Version (z.B. `v29.0`) | + +### Beispiel: Bestimmte Version verwenden + +```bash +# Immer die neueste Version +docker pull git.techniverse.net/scriptos/vdo-ninja:latest + +# Bestimmte Version pinnen +docker pull git.techniverse.net/scriptos/vdo-ninja:v29.0 +``` + +--- + +## 🏗️ Manuell bauen + +Das Image kann auch lokal gebaut werden: + +```bash +# VDO.Ninja Quellcode klonen +git clone --depth 1 https://github.com/steveseguin/vdo.ninja vdo-ninja-source + +# Docker Image bauen +docker build -t vdo-ninja:local . + +# Container starten +docker run -d -p 8080:80 --name vdo-ninja vdo-ninja:local +``` + +--- + +## 🛡️ Secrets & Variablen + +Folgende Secrets und Variablen müssen in Gitea konfiguriert sein: + +### Secrets + +| Name | Beschreibung | +|---|---| +| `REGISTRY_USER` | Benutzername für die Container Registry | +| `REGISTRY_TOKEN` | Token/Passwort für die Container Registry | + +### Variablen + +| Name | Beschreibung | Beispiel | +|---|---|---| +| `REGISTRY_URL` | URL der Container Registry | `https://git.techniverse.net` | + +--- + +## 🗂️ Projektstruktur + +``` +. +├── .gitea/ +│ └── workflows/ +│ └── daily-docker.yml # 🔄 Gitea Workflow (täglicher Build) +├── Dockerfile # 🐳 Docker-Bauanleitung +├── nginx.conf # ⚙️ Nginx-Konfiguration +├── docker-compose.yml # 🚀 Compose-Datei für einfaches Deployment +├── .dockerignore # 🚫 Dateien die nicht ins Image gehören +├── LICENSE # 📄 MIT-Lizenz (dieses Repo) +└── README.md # 📖 Diese Datei +``` + +--- + +## 📄 Lizenz + +Dieses Repository (Dockerfile, Workflow, Konfiguration) steht unter der [MIT-Lizenz](./LICENSE). + +**VDO.Ninja** selbst steht unter der [AGPL-3.0-Lizenz](https://github.com/steveseguin/vdo.ninja/blob/master/AGPLv3.md). + +--- + +## 🔗 Links + +| | Link | +|---|---| +| 🌐 VDO.Ninja | https://vdo.ninja | +| 📦 Original-Repository | https://github.com/steveseguin/vdo.ninja | +| 📖 VDO.Ninja Dokumentation | https://docs.vdo.ninja | +| 🐳 Docker Image (Registry) | [git.techniverse.net/scriptos/vdo-ninja](https://git.techniverse.net/scriptos/-/packages/container/vdo-ninja) |

diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..991809d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +services: + vdo-ninja: + image: git.techniverse.net/scriptos/vdo-ninja:latest + container_name: vdo-ninja + restart: unless-stopped + ports: + - "8080:80" + networks: + vdo_ninja_net: + ipv4_address: 172.19.76.130 + +networks: + vdo_ninja_net: + name: vdo-ninja.dockernetwork.local + driver: bridge + ipam: + config: + - subnet: 172.19.76.128/25 + gateway: 172.19.76.129 + ip_range: 172.19.76.128/25 diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..9bdca7f --- /dev/null +++ b/nginx.conf @@ -0,0 +1,43 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # Security Headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Gzip-Komprimierung + gzip on; + gzip_vary on; + gzip_min_length 1000; + gzip_proxied any; + gzip_types + text/plain + text/css + text/javascript + application/javascript + application/json + application/xml + image/svg+xml; + + location / { + try_files $uri $uri/ =404; + } + + # Statische Assets cachen + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 7d; + add_header Cache-Control "public"; + } + + # Zugriff auf versteckte Dateien blockieren + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } +}