feat(website): legal pages (Impressum/Datenschutz) + auto-deploy on push-to-main
Two coupled changes that make sense to land together:
1. Legal pages required under German law
- /imprint/ + /de/impressum/ — §5 DDG disclosure (contact is email
plus Forgejo-Issues as the second quick-contact channel, per ECJ
C-298/07 no phone number required)
- /privacy/ + /de/datenschutz/ — Art. 13 GDPR minimum: server-log
processing (IP, UA, URL, retention ≤30 days), no cookies, no
tracking, no third-party embeds. RLP Landesbeauftragter as the
competent supervisory authority.
- Footer partial linked from every page, localized per language.
- DE versions are legally binding; EN versions are courtesy
translations noting that.
2. Auto-deploy wired up
- New workflow .forgejo/workflows/deploy-site.yml fires on
push-to-main with paths under website/**. Runs on the self-hosted
runner, which *is* forge-runner-01 — so "deploy" is just a local
rsync into /srv/furtka-site and a hugo build into
/var/www/furtka.org. No SSH, no secrets.
- website/deploy-ci.sh is the SSH-free counterpart of deploy.sh,
invoked by the workflow.
- compose.yml bind-mounts /srv/furtka-site and /var/www/furtka.org
into the runner container at matching paths so the workflow can
reach them. Requires a one-time `docker compose up -d` on the
runner host to pick the mounts up.
- deploy.sh is kept for out-of-band manual deploys (testing from a
local branch, CI outage) but gets a header comment pointing at
the CI path as the normal flow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d499907613
commit
b77ef80b56
9 changed files with 301 additions and 1 deletions
39
.forgejo/workflows/deploy-site.yml
Normal file
39
.forgejo/workflows/deploy-site.yml
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
name: Deploy site
|
||||||
|
|
||||||
|
# Auto-deploy the Hugo site to /var/www/furtka.org on push-to-main.
|
||||||
|
# Only fires when content under website/ changes — everything else
|
||||||
|
# (Python code, ISO build, runbook docs) is unaffected.
|
||||||
|
#
|
||||||
|
# Runs on the self-hosted runner, which is forge-runner-01 — the same
|
||||||
|
# host that serves furtka.org. So the "deploy" is just a local rsync
|
||||||
|
# of the Hugo source into /srv/furtka-site and a `hugo` build into
|
||||||
|
# /var/www/furtka.org. No SSH, no secrets, no cross-host anything.
|
||||||
|
#
|
||||||
|
# Requires two bind-mounts on the runner container (/srv/furtka-site
|
||||||
|
# and /var/www/furtka.org → same paths inside). See compose.yml.
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'website/**'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: deploy-site
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: self-hosted
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install hugo + rsync
|
||||||
|
# Runner image is alpine-based; apk is fast and cached.
|
||||||
|
# Pinning is intentionally skipped — alpine:latest moves hugo
|
||||||
|
# forward in lockstep with upstream, and the site only uses
|
||||||
|
# baseline features.
|
||||||
|
run: apk add --no-cache hugo rsync
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
run: ./website/deploy-ci.sh
|
||||||
|
|
@ -19,6 +19,13 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
# Auto-deploy of furtka.org runs inside this container — the
|
||||||
|
# runner host *is* the web server. Bind these at matching paths
|
||||||
|
# so rsync/hugo just see plain local filesystem. Without these
|
||||||
|
# mounts, .forgejo/workflows/deploy-site.yml can't reach the
|
||||||
|
# source tree or the webroot.
|
||||||
|
- /srv/furtka-site:/srv/furtka-site
|
||||||
|
- /var/www/furtka.org:/var/www/furtka.org
|
||||||
command: >-
|
command: >-
|
||||||
/bin/sh -c "apk add --no-cache nodejs docker-cli && sleep 5 &&
|
/bin/sh -c "apk add --no-cache nodejs docker-cli && sleep 5 &&
|
||||||
forgejo-runner daemon --config /data/config.yml"
|
forgejo-runner daemon --config /data/config.yml"
|
||||||
|
|
|
||||||
79
website/content/datenschutz.de.md
Normal file
79
website/content/datenschutz.de.md
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
---
|
||||||
|
title: "Datenschutzerklärung"
|
||||||
|
translationKey: "privacy"
|
||||||
|
sitemap:
|
||||||
|
priority: 0.2
|
||||||
|
---
|
||||||
|
|
||||||
|
### Kurzfassung
|
||||||
|
|
||||||
|
Diese Website setzt **keine Cookies**, lädt **keine Schriften oder
|
||||||
|
Skripte von Drittanbietern**, bindet **keine Analyse- oder
|
||||||
|
Tracking-Dienste** ein und enthält **keine externen Einbettungen**
|
||||||
|
(YouTube, Maps, Social-Media-Buttons, …). Technisch anfallend sind
|
||||||
|
ausschließlich kurzfristige Server-Zugriffsprotokolle.
|
||||||
|
|
||||||
|
### Verantwortlicher
|
||||||
|
|
||||||
|
<address>
|
||||||
|
Daniel Maksymilian Syrnicki<br>
|
||||||
|
Hauptstraße 35<br>
|
||||||
|
55569 Monzingen<br>
|
||||||
|
Deutschland<br>
|
||||||
|
E-Mail: <a href="mailto:hallo@furtka.org">hallo@furtka.org</a>
|
||||||
|
</address>
|
||||||
|
|
||||||
|
### Server-Logfiles
|
||||||
|
|
||||||
|
Beim Aufruf der Website werden technisch notwendige Daten vom Browser an
|
||||||
|
den Server übermittelt und dort in Logdateien gespeichert:
|
||||||
|
|
||||||
|
- Datum und Uhrzeit des Aufrufs
|
||||||
|
- IP-Adresse (in gekürzter Form)
|
||||||
|
- aufgerufene URL
|
||||||
|
- HTTP-Statuscode und übertragene Datenmenge
|
||||||
|
- Referrer (falls vom Browser gesendet)
|
||||||
|
- User-Agent-Kennung des Browsers
|
||||||
|
|
||||||
|
**Zweck:** Auslieferung der Website und Abwehr missbräuchlicher Zugriffe.
|
||||||
|
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse
|
||||||
|
an Betrieb und Sicherheit).
|
||||||
|
**Speicherdauer:** maximal 30 Tage, danach automatische Löschung.
|
||||||
|
**Empfänger:** keine Weitergabe. Die Website läuft auf eigener
|
||||||
|
Infrastruktur; es gibt keinen externen Auftragsverarbeiter.
|
||||||
|
**Drittlandübermittlung:** keine.
|
||||||
|
|
||||||
|
### Cookies und Tracking
|
||||||
|
|
||||||
|
Keine. Es werden keine Cookies gesetzt, kein LocalStorage oder
|
||||||
|
SessionStorage verwendet und keine Tracking- oder Analyse-Dienste
|
||||||
|
eingebunden. Eine Einwilligung nach § 25 TDDDG ist daher nicht
|
||||||
|
erforderlich.
|
||||||
|
|
||||||
|
### Ihre Rechte
|
||||||
|
|
||||||
|
Sie haben jederzeit das Recht auf:
|
||||||
|
|
||||||
|
- Auskunft über die zu Ihrer Person gespeicherten Daten (Art. 15 DSGVO)
|
||||||
|
- Berichtigung unrichtiger Daten (Art. 16 DSGVO)
|
||||||
|
- Löschung (Art. 17 DSGVO)
|
||||||
|
- Einschränkung der Verarbeitung (Art. 18 DSGVO)
|
||||||
|
- Datenübertragbarkeit (Art. 20 DSGVO)
|
||||||
|
- Widerspruch gegen die Verarbeitung (Art. 21 DSGVO)
|
||||||
|
|
||||||
|
Anfragen hierzu richten Sie bitte per E-Mail an hallo@furtka.org.
|
||||||
|
|
||||||
|
### Beschwerderecht
|
||||||
|
|
||||||
|
Sie haben das Recht, sich bei einer Datenschutz-Aufsichtsbehörde zu
|
||||||
|
beschweren. Zuständig ist:
|
||||||
|
|
||||||
|
**Der Landesbeauftragte für den Datenschutz und die Informationsfreiheit
|
||||||
|
Rheinland-Pfalz**
|
||||||
|
Hintere Bleiche 34, 55116 Mainz
|
||||||
|
Website: <https://www.datenschutz.rlp.de>
|
||||||
|
|
||||||
|
### Stand
|
||||||
|
|
||||||
|
Diese Erklärung ist aktuell gültig und wurde zuletzt am 18.04.2026
|
||||||
|
aktualisiert.
|
||||||
80
website/content/datenschutz.md
Normal file
80
website/content/datenschutz.md
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
---
|
||||||
|
title: "Privacy"
|
||||||
|
translationKey: "privacy"
|
||||||
|
url: /privacy/
|
||||||
|
sitemap:
|
||||||
|
priority: 0.2
|
||||||
|
---
|
||||||
|
|
||||||
|
### In short
|
||||||
|
|
||||||
|
This website sets **no cookies**, loads **no third-party fonts or
|
||||||
|
scripts**, embeds **no analytics or tracking services**, and contains
|
||||||
|
**no external embeds** (YouTube, Maps, social buttons, …). The only
|
||||||
|
technical data collected is short-lived server access logs.
|
||||||
|
|
||||||
|
### Controller
|
||||||
|
|
||||||
|
<address>
|
||||||
|
Daniel Maksymilian Syrnicki<br>
|
||||||
|
Hauptstraße 35<br>
|
||||||
|
55569 Monzingen<br>
|
||||||
|
Germany<br>
|
||||||
|
Email: <a href="mailto:hallo@furtka.org">hallo@furtka.org</a>
|
||||||
|
</address>
|
||||||
|
|
||||||
|
### Server logs
|
||||||
|
|
||||||
|
When you load a page, your browser sends technically necessary data to
|
||||||
|
the server, which stores it in log files:
|
||||||
|
|
||||||
|
- Date and time of the request
|
||||||
|
- IP address (in shortened form)
|
||||||
|
- Requested URL
|
||||||
|
- HTTP status code and bytes transferred
|
||||||
|
- Referrer (if sent by the browser)
|
||||||
|
- User-agent string
|
||||||
|
|
||||||
|
**Purpose:** serving the website and defending against abusive traffic.
|
||||||
|
**Legal basis:** Art. 6(1)(f) GDPR — legitimate interest in operation
|
||||||
|
and security.
|
||||||
|
**Retention:** up to 30 days, then automatically deleted.
|
||||||
|
**Recipients:** none. The site runs on our own infrastructure; no
|
||||||
|
external processor is involved.
|
||||||
|
**Transfers outside the EU/EEA:** none.
|
||||||
|
|
||||||
|
### Cookies and tracking
|
||||||
|
|
||||||
|
None. No cookies are set, no localStorage or sessionStorage is used, and
|
||||||
|
no tracking or analytics services are embedded. Because of this, no
|
||||||
|
consent under § 25 TDDDG (German implementation of the ePrivacy
|
||||||
|
directive) is required.
|
||||||
|
|
||||||
|
### Your rights
|
||||||
|
|
||||||
|
You have the right at any time to:
|
||||||
|
|
||||||
|
- Information about the data stored about you (Art. 15 GDPR)
|
||||||
|
- Correction of inaccurate data (Art. 16 GDPR)
|
||||||
|
- Erasure (Art. 17 GDPR)
|
||||||
|
- Restriction of processing (Art. 18 GDPR)
|
||||||
|
- Data portability (Art. 20 GDPR)
|
||||||
|
- Object to processing (Art. 21 GDPR)
|
||||||
|
|
||||||
|
Send requests to hallo@furtka.org.
|
||||||
|
|
||||||
|
### Right to complain
|
||||||
|
|
||||||
|
You have the right to file a complaint with a data protection
|
||||||
|
supervisory authority. The competent one is:
|
||||||
|
|
||||||
|
**Der Landesbeauftragte für den Datenschutz und die Informationsfreiheit
|
||||||
|
Rheinland-Pfalz**
|
||||||
|
Hintere Bleiche 34, 55116 Mainz, Germany
|
||||||
|
Website: <https://www.datenschutz.rlp.de>
|
||||||
|
|
||||||
|
### Last updated
|
||||||
|
|
||||||
|
This statement was last updated on 2026-04-18.
|
||||||
|
|
||||||
|
The German version of this privacy statement is the legally binding one.
|
||||||
26
website/content/impressum.de.md
Normal file
26
website/content/impressum.de.md
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
title: "Impressum"
|
||||||
|
translationKey: "imprint"
|
||||||
|
sitemap:
|
||||||
|
priority: 0.2
|
||||||
|
---
|
||||||
|
|
||||||
|
Angaben gemäß § 5 DDG.
|
||||||
|
|
||||||
|
<address>
|
||||||
|
<strong>Daniel Maksymilian Syrnicki</strong><br>
|
||||||
|
Hauptstraße 35<br>
|
||||||
|
55569 Monzingen<br>
|
||||||
|
Deutschland
|
||||||
|
</address>
|
||||||
|
|
||||||
|
### Kontakt
|
||||||
|
|
||||||
|
- E-Mail: hallo@furtka.org
|
||||||
|
- Forgejo-Issues: <https://forgejo.sourcegate.online/daniel/furtka/issues>
|
||||||
|
|
||||||
|
### Hinweis zum Projekt
|
||||||
|
|
||||||
|
Furtka ist ein privates Open-Source-Projekt. Es ist kein Unternehmen,
|
||||||
|
bietet keine kostenpflichtigen Leistungen an und nimmt keine Zahlungen
|
||||||
|
entgegen. Der Quelltext steht unter der AGPL-3.0.
|
||||||
29
website/content/impressum.md
Normal file
29
website/content/impressum.md
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
title: "Imprint"
|
||||||
|
translationKey: "imprint"
|
||||||
|
url: /imprint/
|
||||||
|
sitemap:
|
||||||
|
priority: 0.2
|
||||||
|
---
|
||||||
|
|
||||||
|
Information pursuant to § 5 DDG (German Digital Services Act).
|
||||||
|
|
||||||
|
<address>
|
||||||
|
<strong>Daniel Maksymilian Syrnicki</strong><br>
|
||||||
|
Hauptstraße 35<br>
|
||||||
|
55569 Monzingen<br>
|
||||||
|
Germany
|
||||||
|
</address>
|
||||||
|
|
||||||
|
### Contact
|
||||||
|
|
||||||
|
- Email: hallo@furtka.org
|
||||||
|
- Forgejo issues: <https://forgejo.sourcegate.online/daniel/furtka/issues>
|
||||||
|
|
||||||
|
### Project note
|
||||||
|
|
||||||
|
Furtka is a private open-source project. It is not a company, offers no
|
||||||
|
paid services, and does not accept payments. The source code is licensed
|
||||||
|
under AGPL-3.0.
|
||||||
|
|
||||||
|
The German version of this imprint is the legally binding one.
|
||||||
27
website/deploy-ci.sh
Executable file
27
website/deploy-ci.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Auto-deploy path run by .forgejo/workflows/deploy-site.yml inside the
|
||||||
|
# self-hosted runner — which is forge-runner-01, the actual web server.
|
||||||
|
# Same effect as deploy.sh but without the SSH hop: everything is local.
|
||||||
|
#
|
||||||
|
# Requires `rsync` and `hugo` on PATH. The workflow apk-installs both
|
||||||
|
# before invoking this script.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
SRCROOT="${FURTKA_SRCROOT:-/srv/furtka-site}"
|
||||||
|
WEBROOT="${FURTKA_WEBROOT:-/var/www/furtka.org}"
|
||||||
|
|
||||||
|
echo "==> rsync website/ → $SRCROOT"
|
||||||
|
rsync -az --delete \
|
||||||
|
--exclude='.hugo_build.lock' \
|
||||||
|
--exclude='public/' \
|
||||||
|
--exclude='resources/' \
|
||||||
|
--exclude='deploy.sh' \
|
||||||
|
--exclude='deploy-ci.sh' \
|
||||||
|
"$HERE/" "$SRCROOT/"
|
||||||
|
|
||||||
|
echo "==> hugo build → $WEBROOT"
|
||||||
|
cd "$SRCROOT"
|
||||||
|
hugo --minify --cleanDestinationDir -d "$WEBROOT"
|
||||||
|
|
||||||
|
echo "OK: deployed to https://furtka.org/"
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Deploy furtka.org to forge-runner-01.
|
# Manual deploy of furtka.org to forge-runner-01.
|
||||||
# Rsyncs the Hugo source up to the VM and builds it in-place.
|
# Rsyncs the Hugo source up to the VM and builds it in-place.
|
||||||
|
#
|
||||||
|
# Normal path is now the `Deploy site` Forgejo workflow, which auto-fires
|
||||||
|
# on every push-to-main that touches website/** — see
|
||||||
|
# .forgejo/workflows/deploy-site.yml. Keep this script for out-of-band
|
||||||
|
# pushes (testing from a local branch, recovering from a CI outage,
|
||||||
|
# whatever). The in-CI equivalent that skips the SSH hop is deploy-ci.sh.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
HOST="${FURTKA_HOST:-forge-runner}"
|
HOST="${FURTKA_HOST:-forge-runner}"
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,12 @@
|
||||||
· AGPL-3.0 ·
|
· AGPL-3.0 ·
|
||||||
<a href="mailto:{{ site.Params.contactEmail }}">{{ site.Params.contactEmail }}</a>
|
<a href="mailto:{{ site.Params.contactEmail }}">{{ site.Params.contactEmail }}</a>
|
||||||
</p>
|
</p>
|
||||||
|
<p class="kicker">
|
||||||
|
{{ if eq site.Language.Lang "de" -}}
|
||||||
|
<a href="/de/impressum/">Impressum</a> · <a href="/de/datenschutz/">Datenschutz</a>
|
||||||
|
{{- else -}}
|
||||||
|
<a href="/imprint/">Imprint</a> · <a href="/privacy/">Privacy</a>
|
||||||
|
{{- end }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue