Web: Repo-Link mit Gitea-Logo im Footer + Coolify-Deploy (nginx)

- Footer der Web-App verlinkt aufs Gitea-Repo mit kleinem Gitea-Logo (inline SVG)
- Dockerfile (nginx:alpine) liefert web/ statisch aus -> Coolify Git-Deploy
- deploy/nginx.conf: CSP frame-ancestors erlaubt Einbettung als iframe nur von
  gaertner.onl; sw.js/manifest ungecacht; Dev-Artefakte (_*) werden geblockt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Claude Code
2026-07-15 11:00:14 +00:00
parent 7569cd3fab
commit e5f834c34a
3 changed files with 50 additions and 1 deletions

9
Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
# schattenpost Web/PWA — reine statische App hinter nginx.
# Coolify baut direkt aus dem Repo (Build Pack: Dockerfile).
FROM nginx:1.27-alpine
# App-Shell (die _*-Dev-Helfer werden per nginx-Regel nicht ausgeliefert).
COPY web/ /usr/share/nginx/html/
COPY deploy/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

22
deploy/nginx.conf Normal file
View File

@@ -0,0 +1,22 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# App-Shell darf NUR von der eigenen Homepage als iframe eingebettet werden.
add_header Content-Security-Policy "frame-ancestors 'self' https://gaertner.onl https://*.gaertner.onl" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
# Service Worker & Manifest nie cachen -> App-Updates greifen sofort.
location = /sw.js { add_header Cache-Control "no-cache"; }
location = /manifest.webmanifest { add_header Cache-Control "no-cache"; }
# Entwickler-/Test-Artefakte (_-Präfix) niemals ausliefern.
location ~ /_ { deny all; }
location / {
try_files $uri $uri/ =404;
}
}

View File

@@ -60,6 +60,10 @@
a.dl { display: block; margin-top: 10px; color: var(--accent); font-weight: 600; text-decoration: none; a.dl { display: block; margin-top: 10px; color: var(--accent); font-weight: 600; text-decoration: none;
background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 11px 13px; } background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; padding: 11px 13px; }
footer { color: var(--muted); font-size: 12px; text-align: center; margin-top: 8px; line-height: 1.7; } footer { color: var(--muted); font-size: 12px; text-align: center; margin-top: 8px; line-height: 1.7; }
footer a.repo { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px;
color: var(--muted); text-decoration: none; font-weight: 600; }
footer a.repo:hover { color: var(--accent); }
footer a.repo svg { display: block; flex: 0 0 auto; }
code { background: var(--panel2); padding: 1px 5px; border-radius: 4px; font-size: 12.5px; } code { background: var(--panel2); padding: 1px 5px; border-radius: 4px; font-size: 12.5px; }
</style> </style>
@@ -131,7 +135,21 @@
<footer> <footer>
Krypto &amp; Steganografie laufen ausschließlich lokal (client-side).<br> Krypto &amp; Steganografie laufen ausschließlich lokal (client-side).<br>
Format-kompatibel zum <code>schattenpost.py</code>-CLI. Format-kompatibel zum <code>schattenpost.py</code>-CLI.<br>
<a class="repo" href="https://gitea.gaertner.onl/christian/schattenpost" target="_blank" rel="noopener noreferrer">
<svg viewBox="0 0 32 32" width="15" height="15" role="img" aria-label="Gitea">
<path fill="#609926" d="M6 8h13.5v8.5A6.75 6.75 0 0 1 12.75 23.25h-.5A6.75 6.75 0 0 1 6 16.5V8z"/>
<path fill="none" stroke="#609926" stroke-width="2.4" d="M19.5 10.5h3.25a3.25 3.25 0 0 1 0 6.5H19.5"/>
<g fill="#fff">
<circle cx="10.6" cy="11.4" r="1.5"/>
<circle cx="15.4" cy="11.4" r="1.5"/>
<circle cx="13" cy="18.4" r="1.5"/>
</g>
<path fill="none" stroke="#fff" stroke-width="1.5" stroke-linecap="round"
d="M10.6 12.9v.6a2.4 2.4 0 0 0 2.4 2.4M15.4 12.9v.6a2.4 2.4 0 0 1-2.4 2.4M13 15.9v1"/>
</svg>
Quellcode auf Gitea
</a>
</footer> </footer>
<script> <script>