From 30d15cd68081bc2a0fefd56763f8325f163066a9 Mon Sep 17 00:00:00 2001 From: Robert Rapp Date: Mon, 31 Aug 2026 00:01:17 +0200 Subject: [PATCH] Image in der CI bauen statt zur Laufzeit, Site ins Image backen Bisher baute der Server das Image selbst und der Container holte sich Inhalte per git pull ueber deploy.php. Das war seit jeher kaputt: git verweigerte wegen "dubious ownership" die Arbeit, die &&-Kette brach ab, hugo lief nie. Live war stets der Stand des letzten Containerstarts. Statt das zu flicken faellt der Mechanismus jetzt weg. Das Dockerfile ist zweistufig: Hugo baut die Seite im Builder, das Laufzeit-Image enthaelt nur nginx und fertiges HTML. Kein PHP, kein git, kein Hugo mehr zur Laufzeit - 49 MB statt eines Debian-Images mit vier Werkzeugketten. Deployen heisst damit: neues Image ziehen, Container neu starten. Entfernt: deploy.php, entrypoint.sh und .htaccess (Apache-Rest aus der Kirby-Zeit, unter nginx wirkungslos). Der Ordner kirby/ heisst jetzt docker/, weil dort nie Kirby lag. docker-compose.yml zieht das Image aus der Registry. Das Volume-Mount auf /var/www/html ist weg - es haette die ins Image gebackene Seite verdeckt. Lokal geprueft: Build laeuft durch, Container liefert alle Seiten und Assets mit HTTP 200 aus, Intro-Text kommt aus der Markdown-Datei, alle sieben Lampenbilder sind enthalten. Co-Authored-By: Claude Opus 5 --- .gitea/workflows/build.yml | 46 ++++++++++++++++++++++++++ .htaccess | 67 -------------------------------------- deploy.php | 48 --------------------------- docker-compose.yml | 18 ++++------ docker/Dockerfile | 33 +++++++++++++++++++ docker/nginx.conf | 18 ++++++++++ kirby/Dockerfile | 31 ------------------ kirby/entrypoint.sh | 23 ------------- kirby/nginx.conf | 21 ------------ 9 files changed, 103 insertions(+), 202 deletions(-) create mode 100644 .gitea/workflows/build.yml delete mode 100644 .htaccess delete mode 100644 deploy.php create mode 100644 docker/Dockerfile create mode 100644 docker/nginx.conf delete mode 100644 kirby/Dockerfile delete mode 100644 kirby/entrypoint.sh delete mode 100644 kirby/nginx.conf diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..4a9f14f --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,46 @@ +name: Image bauen und in die Registry pushen + +on: + push: + branches: + - main + workflow_dispatch: + +env: + REGISTRY: gitea.mindboost.team + IMAGE: gitea.mindboost.team/rorapp/robbis.space + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Repository auschecken + uses: actions/checkout@v4 + with: + # themes/gokarna ist ein Submodule und wird fuer den Hugo-Build + # zwingend gebraucht. Ohne dies bricht der Dockerfile-Check ab. + submodules: recursive + fetch-depth: 0 + + - name: Buildx einrichten + uses: docker/setup-buildx-action@v3 + + - name: An der Registry anmelden + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Bauen und pushen + uses: docker/build-push-action@v6 + with: + context: . + file: docker/Dockerfile + platforms: linux/amd64 + push: true + tags: | + ${{ env.IMAGE }}:latest + ${{ env.IMAGE }}:${{ gitea.sha }} + cache-from: type=registry,ref=${{ env.IMAGE }}:buildcache + cache-to: type=registry,ref=${{ env.IMAGE }}:buildcache,mode=max diff --git a/.htaccess b/.htaccess deleted file mode 100644 index 5fe5c71..0000000 --- a/.htaccess +++ /dev/null @@ -1,67 +0,0 @@ -# Kirby .htaccess -# revision 2023-07-22 - -# rewrite rules - - -# enable awesome urls. i.e.: -# http://yourdomain.com/about-us/team -RewriteEngine on - -# make sure to set the RewriteBase correctly -# if you are running the site in a subfolder; -# otherwise links or the entire site will break. -# -# If your homepage is http://yourdomain.com/mysite, -# set the RewriteBase to: -# -# RewriteBase /mysite - -# In some environments it's necessary to -# set the RewriteBase to: -# -# RewriteBase / - -# block files and folders beginning with a dot, such as .git -# except for the .well-known folder, which is used for Let's Encrypt and security.txt -RewriteRule (^|/)\.(?!well-known\/) index.php [L] - -# block all files in the content folder from being accessed directly -RewriteRule ^content/(.*) index.php [L] - -# block all files in the site folder from being accessed directly -RewriteRule ^site/(.*) index.php [L] - -# block direct access to Kirby and the Panel sources -RewriteRule ^kirby/(.*) index.php [L] - -# make site links work -RewriteCond %{REQUEST_FILENAME} !-f -RewriteCond %{REQUEST_FILENAME} !-d -RewriteRule ^(.*) index.php [L] - - - -# pass the Authorization header to PHP -SetEnvIf Authorization "(.+)" HTTP_AUTHORIZATION=$1 - -# compress text file responses - -AddOutputFilterByType DEFLATE text/plain -AddOutputFilterByType DEFLATE text/html -AddOutputFilterByType DEFLATE text/css -AddOutputFilterByType DEFLATE text/javascript -AddOutputFilterByType DEFLATE application/json -AddOutputFilterByType DEFLATE application/javascript -AddOutputFilterByType DEFLATE application/x-javascript - - -# set security headers in all responses - - -# serve files as plain text if the actual content type is not known -# (hardens against attacks from malicious file uploads) -Header set Content-Type "text/plain" "expr=-z %{CONTENT_TYPE}" -Header set X-Content-Type-Options "nosniff" - - diff --git a/deploy.php b/deploy.php deleted file mode 100644 index 0bd9665..0000000 --- a/deploy.php +++ /dev/null @@ -1,48 +0,0 @@ -&1 && git submodule update --init --recursive 2>&1 && hugo 2>&1'); - -http_response_code(200); -header('Content-Type: text/plain'); -echo "Deploy triggered:\n" . $output; diff --git a/docker-compose.yml b/docker-compose.yml index b8ac468..cda49da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,16 +1,10 @@ -version: '3.8' - services: robbis-space: - build: - context: ./kirby - dockerfile: Dockerfile - image: robbis-space + # Fertiges Image aus der Gitea-Registry. Die Seite ist beim Build + # hineingebacken - kein git pull, kein Hugo-Lauf zur Laufzeit. + # Deployen heisst: docker compose pull && docker compose up -d + image: ${ROBBIS_IMAGE:-gitea.mindboost.team/rorapp/robbis.space:latest} container_name: robbis-space - volumes: - - /home/kirbyuser/robbis-space:/var/www/html:rw # Persistente Daten - environment: - - DEPLOY_SECRET=dc2d9b0af4849284a0cb396d462aa1853df0c16fec45c5c859d6b97874ea8db4 restart: unless-stopped networks: - proxy @@ -24,12 +18,12 @@ services: - "traefik.http.routers.robbis-space.entrypoints=websecure" - "traefik.http.routers.robbis-space.tls=true" - "traefik.http.services.robbis-space.loadbalancer.server.port=80" - # HTTP-Router (Port 80) + # HTTP-Router (Port 80) mit Weiterleitung auf HTTPS - "traefik.http.routers.robbis-space-http.rule=Host(`robbis.space`)" - "traefik.http.routers.robbis-space-http.entrypoints=web" - "traefik.http.routers.robbis-space-http.middlewares=traefik-https-redirect" - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https" - # Service-Port (nginx läuft auf Port 80 im Container) + networks: proxy: external: true diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..c7398f2 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,33 @@ +# Zweistufiger Build: Hugo erzeugt die Seite, nginx liefert nur noch aus. +# Das fertige HTML steckt im Image - zur Laufzeit wird nichts mehr gebaut +# oder aus git geholt. + +FROM debian:bookworm-slim AS builder + +ARG HUGO_VERSION=0.147.0 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -fsSL "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" \ + | tar -xz -C /usr/local/bin hugo + +WORKDIR /src +COPY . . + +# themes/gokarna ist ein Submodule und muss im Build-Context liegen. +# In der CI sorgt actions/checkout mit submodules:recursive dafuer. +RUN test -f themes/gokarna/theme.toml \ + || { echo "FEHLER: themes/gokarna fehlt - Submodule nicht ausgecheckt"; exit 1; } + +RUN hugo --minify --destination /public + + +FROM nginx:1.27-alpine + +COPY docker/nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /public /usr/share/nginx/html + +EXPOSE 80 diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..659396e --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,18 @@ +server { + listen 80; + server_name robbis.space; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ =404; + } + + error_page 404 /404.html; + + location ~* \.(css|js|jpg|jpeg|png|gif|svg|webp|woff2?)$ { + expires 30d; + add_header Cache-Control "public, immutable"; + } +} diff --git a/kirby/Dockerfile b/kirby/Dockerfile deleted file mode 100644 index 7df25a4..0000000 --- a/kirby/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -FROM debian:bookworm-slim - -# Install nginx, PHP-CLI, git, curl -RUN apt-get update && apt-get install -y --no-install-recommends \ - nginx \ - php-cli \ - php-fpm \ - git \ - curl \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -# Install Hugo (extended) -ARG HUGO_VERSION=0.147.0 -RUN curl -L "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" \ - | tar -xz -C /usr/local/bin hugo - -# nginx config -COPY nginx.conf /etc/nginx/sites-available/default - -# PHP-FPM for deploy.php -RUN sed -i 's|listen = /run/php/php.*-fpm.sock|listen = 127.0.0.1:9000|' /etc/php/*/fpm/pool.d/www.conf \ - && sed -i 's|;clear_env = no|clear_env = no|' /etc/php/*/fpm/pool.d/www.conf \ - || echo 'clear_env = no' >> /etc/php/*/fpm/pool.d/www.conf - -COPY entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh - -EXPOSE 80 - -ENTRYPOINT ["/entrypoint.sh"] diff --git a/kirby/entrypoint.sh b/kirby/entrypoint.sh deleted file mode 100644 index 65e64ad..0000000 --- a/kirby/entrypoint.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -e - -# Start PHP-FPM -PHP_FPM=$(find /usr/sbin -name 'php-fpm*' | head -1) -$PHP_FPM - -# deploy.php laeuft als www-data, das Repo gehoert einem anderen Benutzer. -# Ohne diese Ausnahme bricht git mit "detected dubious ownership" ab und die -# &&-Kette in deploy.php erreicht hugo nie. --system gilt fuer alle Benutzer. -git config --system --add safe.directory /var/www/html -git config --system --add safe.directory /var/www/html/themes/gokarna - -# www-data muss ins Repo schreiben koennen (git pull, hugo nach public/). -chown -R www-data:www-data /var/www/html || true - -# Initial Hugo build -cd /var/www/html -git submodule update --init --recursive -hugo - -# Start nginx in foreground -nginx -g 'daemon off;' diff --git a/kirby/nginx.conf b/kirby/nginx.conf deleted file mode 100644 index 25e302e..0000000 --- a/kirby/nginx.conf +++ /dev/null @@ -1,21 +0,0 @@ -server { - listen 80; - server_name robbis.space; - - root /var/www/html/public; - index index.html; - - # Serve static Hugo output - location / { - try_files $uri $uri/ =404; - } - - # deploy.php webhook handler - location = /deploy.php { - root /var/www/html; - fastcgi_pass 127.0.0.1:9000; - fastcgi_index deploy.php; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME /var/www/html/deploy.php; - } -}