feat: fertige Docker Images via Gitea Actions + Runtime-Konfiguration
Some checks failed
Docker Images bauen und pushen / build-and-push (push) Has been cancelled

CI/CD:
- .gitea/workflows/docker-publish.yml: baut + pusht bei Push auf release und Tags
- Images: git.cynfo.net/christian/rmm2/backend:latest + frontend:latest
- Gitea Secrets: REGISTRY_USER + REGISTRY_PASSWORD gesetzt

Runtime-Konfiguration (kein Rebuild bei IP-Aenderung):
- frontend/docker-entrypoint.sh: generiert runtime-config.js aus ENV-Vars beim Start
- frontend/src/config.js: window.__RMM_CONFIG__ (Docker) vor Vite-ENV (in .gitignore, nicht im release-Commit)
- frontend/public/runtime-config.js: leerer Fallback fuer lokale Entwicklung
- frontend/index.html: laedt /runtime-config.js vor dem App-Bundle

docker-compose:
- Nutzt fertige Images aus der Gitea Registry
- docker-compose.build.yml: Override fuer lokalen Build
- Alle Frontend-Werte via ENV zur Laufzeit
This commit is contained in:
cynfo3000 2026-03-08 19:42:56 +01:00
parent 9d5f060cbd
commit 3afd5c8445
8 changed files with 111 additions and 20 deletions

View File

@ -0,0 +1,65 @@
name: Docker Images bauen und pushen
on:
push:
branches:
- release
tags:
- "v*"
env:
REGISTRY: git.cynfo.net
IMAGE_BACKEND: git.cynfo.net/christian/rmm2/backend
IMAGE_FRONTEND: git.cynfo.net/christian/rmm2/frontend
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login in Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Docker Buildx einrichten
uses: docker/setup-buildx-action@v3
- name: Image-Tag bestimmen
id: meta
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
TAG="${{ github.ref_name }}"
else
TAG="latest"
fi
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- name: Backend bauen und pushen
uses: docker/build-push-action@v5
with:
context: ./backend
push: true
tags: |
${{ env.IMAGE_BACKEND }}:${{ steps.meta.outputs.tag }}
${{ env.IMAGE_BACKEND }}:latest
cache-from: type=registry,ref=${{ env.IMAGE_BACKEND }}:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_BACKEND }}:buildcache,mode=max
- name: Frontend bauen und pushen
uses: docker/build-push-action@v5
with:
context: ./frontend
push: true
tags: |
${{ env.IMAGE_FRONTEND }}:${{ steps.meta.outputs.tag }}
${{ env.IMAGE_FRONTEND }}:latest
# BACKEND_HOST ist zur Laufzeit nicht bekannt — wird im Compose via Env gesetzt
# Wer eigene Images braucht: docker compose build
cache-from: type=registry,ref=${{ env.IMAGE_FRONTEND }}:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_FRONTEND }}:buildcache,mode=max

View File

@ -189,8 +189,9 @@ docker compose logs backend
Fertig. Frontend unter `http://<BACKEND_HOST>`, Backend-API unter `https://<BACKEND_HOST>:8443`. Fertig. Frontend unter `http://<BACKEND_HOST>`, Backend-API unter `https://<BACKEND_HOST>:8443`.
> **Hinweis:** Das Frontend-Image wird mit der `BACKEND_HOST`-URL gebaut. > **Hinweis:** Die Frontend-Konfiguration (Backend-Host, API-Key) wird zur **Laufzeit** via ENV
> Nach einer IP-Änderung muss das Frontend neu gebaut werden: `docker compose build frontend && docker compose up -d frontend` > in den Container injiziert — kein Rebuild bei IP-Änderungen nötig.
> Selbst bauen statt fertige Images: `docker compose -f docker-compose.yml -f docker-compose.build.yml up -d`
--- ---

11
docker-compose.build.yml Normal file
View File

@ -0,0 +1,11 @@
# Lokaler Build statt fertige Images verwenden:
# docker compose -f docker-compose.yml -f docker-compose.build.yml up -d
services:
backend:
build: ./backend
image: ~
frontend:
build: ./frontend
image: ~

View File

@ -16,7 +16,7 @@ services:
retries: 10 retries: 10
backend: backend:
build: ./backend image: git.cynfo.net/christian/rmm2/backend:latest
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8443:8443" - "8443:8443"
@ -32,15 +32,14 @@ services:
condition: service_healthy condition: service_healthy
frontend: frontend:
build: image: git.cynfo.net/christian/rmm2/frontend:latest
context: ./frontend
args:
VITE_BACKEND_HOST: ${BACKEND_HOST}
VITE_BACKEND_PORT: ${BACKEND_PORT:-8443}
VITE_API_KEY: ${API_KEY}
restart: unless-stopped restart: unless-stopped
ports: ports:
- "80:80" - "80:80"
environment:
BACKEND_HOST: ${BACKEND_HOST}
BACKEND_PORT: ${BACKEND_PORT:-8443}
API_KEY: ${API_KEY}
depends_on: depends_on:
- backend - backend

View File

@ -5,16 +5,6 @@ COPY package*.json ./
RUN npm ci RUN npm ci
COPY . . COPY . .
# Backend-URL wird zur Build-Zeit via ARG gesetzt
ARG VITE_BACKEND_HOST=localhost
ARG VITE_BACKEND_PORT=8443
ARG VITE_API_KEY=""
ENV VITE_BACKEND_HOST=$VITE_BACKEND_HOST \
VITE_BACKEND_PORT=$VITE_BACKEND_PORT \
VITE_API_KEY=$VITE_API_KEY
RUN npm run build RUN npm run build
# --- # ---
@ -23,7 +13,14 @@ FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
EXPOSE 80 EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] # Konfiguration via ENV zur Laufzeit (kein Rebuild bei IP-Aenderung noetig)
ENV BACKEND_HOST=localhost \
BACKEND_PORT=8443 \
API_KEY=""
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@ -0,0 +1,13 @@
#!/bin/sh
# Generiert /usr/share/nginx/html/runtime-config.js aus ENV-Variablen
# Wird beim Container-Start ausgefuehrt
cat > /usr/share/nginx/html/runtime-config.js << EOF
window.__RMM_CONFIG__ = {
backendHost: "${BACKEND_HOST:-localhost}",
backendPort: "${BACKEND_PORT:-8443}",
apiKey: "${API_KEY:-}"
};
EOF
exec nginx -g "daemon off;"

View File

@ -1,6 +1,8 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<!-- Runtime-Konfiguration (Docker): wird von nginx aus ENV-Vars generiert -->
<script src="/runtime-config.js" onerror="window.__RMM_CONFIG__={}"></script>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />

View File

@ -0,0 +1,3 @@
// Lokaler Entwicklungs-Fallback — in Docker wird diese Datei durch
// docker-entrypoint.sh mit echten Werten ueberschrieben
window.__RMM_CONFIG__ = {};