Files
tibi-svelte-starter/.agents/skills/deployment/SKILL.md
T
apairon 4020ad62c5 feat: enhance medialib image handling and add asset URL resolution
- Implemented `resolveApiAssetUrl` function to normalize asset URLs based on API base.
- Updated `MedialibImage` component to utilize new asset URL resolution and added support for alt text and class properties.
- Enhanced image loading behavior with improved width measurement and focal point handling.
- Added placeholder image handling and improved accessibility with alt text.
- Introduced new test script for auditing broken links in skill documentation.
- Expanded seeded test content to include medialib entries and updated related tests for pagebuilder previews.
- Improved global setup and teardown logging for clarity on seeded content management.
2026-05-17 00:52:41 +00:00

7.3 KiB
Raw Blame History

name, description
name description
deployment Production deployment setup for tibi-projects Basispanel subdomain, .env, CI-Pipeline, Makefile. Use when deploying a new project to production or setting up a staging environment.

Deployment

Überblick

Ein tibi-Projekt wird per Gitea Actions CI gebaut und via rsync auf den Produktionsserver (dock4) deployed. Davor muss die Subdomain im Basispanel angelegt und der Kunde korrekt konfiguriert sein.

1. Basispanel Subdomain anlegen

Kunde prüfen

# Domain des Kunden suchen
mcp_call(server="basispanel", tool="bp_list_domains", args={"search": "<kunde>"})
# → liefert Customer-ID, Domain-ID, Company, Username

Subdomain anlegen

# 1. Config holen (verfügbare Webserver + Storages sehen)
mcp_call(server="basispanel", tool="bp_get_config")

# 2. Subdomain erstellen (ohne Webserver)
mcp_call(server="basispanel", tool="bp_create_subdomain", args={
    "domainId": <domain-id>,
    "name": "<subdomain>",  # oder leer für bare domain
})

# 3. Löschen + neu mit Webserver (wenn Update nicht klappt)
mcp_call(server="basispanel", tool="bp_delete_subdomain", args={"id": <subdomain-id>})

mcp_call(server="basispanel", tool="bp_create_subdomain", args={
    "domainId": <domain-id>,
    "name": "<subdomain>",
    "webserverKey": "dock4_lamp2",
    "webserverStorage": "dock4_webroots2",
    "webserverSettings": {
        "redirectType": "docroot",
        "docroot": "/<subdomain>.<domain>/frontend",
        "gitbaseRepository": "<org>/<repo>",
        "deployRoot": "./..",
        "defaultAlias": "wwwAlias",
        "defaultSubdomain": "defaultSubdomain",
        "wwwRedirect": "wwwRedirect",
        "php": "phpDisabled",      # tibi-SPA kein PHP
        "https": "noHttps",        # erstmal aus, später aktivieren
        "certbot": "noCertbot",
    },
})

Wichtige Keys (aus bp_get_config):

Server Key Storage
dock4 dock4_lamp2 dock4_webroots2
dock1 dock1_... dock1_webroots...

Status prüfen

mcp_call(server="basispanel", tool="bp_get_subdomain_status", args={"id": <subdomain-id>})

Achtung: Health-Check zeigt DNS-Warnungen (externe Nameserver) das ist normal solange der Kunde sein DNS selbst verwaltet.

2. .env konfigurieren

# Basis
PROJECT_NAME=<project>
TIBI_PREFIX=tibi
TIBI_NAMESPACE=<project>

# RSYNC für Deploy
RSYNC_HOST=ftp1.webmakers.de
RSYNC_PORT=22223
PRODUCTION_RSYNC_UID=100<customer-id>00    # z.B. 10051300
PRODUCTION_RSYNC_GID=33

# Production Server
PRODUCTION_SERVER=dock4.basehosts.de
PRODUCTION_TIBI_PREFIX=tibi
PRODUCTION_PATH=/webroots2/customers/<customer-id>/htdocs

# Staging
STAGING_PATH=/staging/<org>/<project>/dev

# URLs
LIVE_URL=http://<subdomain>.<domain>.dock4.basispanel.de   # Preview-URL
STAGING_URL=https://dev-<project>.staging.testversion.online
CODING_URL=https://<project>.code.testversion.online

3. CI-Pipeline (.gitea/workflows/deploy.yml)

name: deploy to production
on: "push"
jobs:
    deploy:
        steps:
            - checkout + git fetch --tags
            - node 22 + yarn install
            - yarn validate
            - ./scripts/ci-modify-config.sh # injiziert LIVE_URL, release, preview
            - yarn build # frontend
            - yarn build:server # SSR
            - sourcemaps → sentry
            - if dev-branch: ./scripts/ci-staging.sh
            - if master-branch: ./scripts/ci-deploy.sh

Wichtig: Das aktuelle Workflow-File führt yarn validate, yarn build und yarn build:server im CI aus. Wenn validate dort scheitert, behebe den eigentlichen Typ- oder Pfadfehler statt den Schritt stillschweigend zu entfernen.

4. Deploy-Skripte

scripts/ci-deploy.sh (Production)

  • Liest .env und api/config.yml.env
  • rsynct frontend/, api/, media/ via SSH zu RSYNC_HOST
  • deshalb muessen Collection-Dateiuploads auf den Repo-Root media/ zeigen, typischerweise via uploadPath: ../media/<collection> in api/collections/*.yml
  • api/media ist in diesem Setup nicht der persistente Deploy-Zielpfad fuer Uploads
  • Nutzt RSYNC_USER + RSYNC_PASS (aus Gitea Secrets)
  • Auf master: excludiert src/ und *.map
  • Reloadt den projektlokalen Proxy-Endpunkt via LIVE_URL/api/_/admin/reload mit Authorization: Bearer ${ADMIN_TOKEN}
  • Cleared SSR cache via LIVE_URL/api/ssr?clear=1

scripts/ci-staging.sh (Dev/Staging)

  • rsynct api/, frontend/dist, und frontend/assets nach /data/${{ github.repository }}/${{ github.ref_name }}
  • Startet docker-compose-staging.yml
  • Reloadt den projektlokalen Proxy-Endpunkt via STAGING_URL/api/_/admin/reload mit Authorization: Bearer ${ADMIN_TOKEN}

scripts/ci-modify-config.sh

  • Injiziert LIVE_URL als originURL in api/hooks/config-client.js
  • Injiziert LIVE_URL als PREVIEW_URL in api/config.yml.env
  • Setzt release + buildTime für Sentry
  • Kopiert frontend/spa.htmlapi/templates/spa.html (SSR-Template)
  • Ersetzt __TIMESTAMP__ in spa.html (Cache-Busting)

5. Makefile

Wichtige Targets:

# Media von Production syncen
media-sync-master-to-local:
    rsync -v -e "ssh ... -l $(PRODUCTION_RSYNC_UID),$(PRODUCTION_RSYNC_GID),$(PRODUCTION_PATH)/media" \
        -az $(RSYNC_HOST):/ media/

# MongoDB von Production syncen (via Chisel-Tunnel)
mongo-sync-master-to-local:
    chisel client --auth coder:$$PASSWORD http://$(PRODUCTION_SERVER):10987 27017:mongo:27017 &
    mongodump ... | mongorestore ...

6. DNS

Der Kunde verwaltet sein DNS selbst (externe Nameserver). Für die Subdomain muss ein A-Record gesetzt werden:

<subdomain>.<domain>  IN  A  45.129.180.102   (IP von dock4)

Die Preview-URL http://<subdomain>.<domain>.dock4.basispanel.de funktioniert ohne DNS (wird von Basispanel intern aufgelöst).

7. HTTPS nachträglich aktivieren

Sobald das Projekt live geht:

  1. Im Basispanel Subdomain updaten:
    • https: "https" (statt "noHttps")
    • certbot: "certbot" (automatisches Letsencrypt)
    • httpsRedirect: "httpsRedirect" (HTTP→HTTPS)
  2. .env: LIVE_URL auf https://www.<domain> ändern
  3. api/hooks/config-client.js: originURL entsprechend setzen (wird von CI überschrieben)

8. Typische Fehler

Problem Ursache Fix
invalid webserverKey: dock4 Falscher Key Mit bp_get_config prüfen → dock4_lamp2
subdomain exists Doppelt angelegt Mit bp_delete_subdomain löschen, neu anlegen
yarn validate scheitert in CI Typen/Submodule/Pfade nicht sauber eingecheckt Checkout-, Submodule- und Include-Pfade korrigieren; validate im Workflow belassen
Rsync "Permission denied" Falscher RSYNC_USER In Gitea Secrets prüfen
404 auf Subdomain DNS nicht gesetzt A-Record beim Kunden-DNS-Provider eintragen