feat(deploy): Multi-Stage-Docker-Build fuer automatisches Deployment

- App_Server/Dockerfile: Build-Context auf Repo-Root, COPY-Pfade
  angepasst, ENTRYPOINT aktiviert, dev-Stage mit inittypescriptdev.sh
- NGINX_Server/Dockerfile: Multi-Stage mit frontend-Stage (Node.js baut
  TypeScript), statische Dateien und Config-Templates ins Image kopiert
- docker-compose.base.yaml: Context auf '.', python-venv Volume entfernt,
  NGINX_STATIC_DIR/CONFIG_TEMPLATE_DIR bind-mounts in Dev verschoben
- docker-compose.dev.yaml: python-venv-dev Volume, APP_DEBUG=true,
  nginx-proxy mit bind-mounts fuer statische Dateien und Templates
- docker-compose.prod.yaml: Code-bind-mount entfernt, nginx-proxy extends
- approot.py: absolute Pfade, Debug-Modus via APP_DEBUG Umgebungsvariable
- init.sh: vereinfacht (kein cd/pip, absolute Pfade)
- inireader.mjs: absoluter Pfad fuer config.ini
- package.json: scripts.build (tsc + rollup) ergaenzt
- .dockerignore, deploy-kbcrm-test.sh, deploy-kbcrm-prod.sh erstellt
- docker-compose.save.yaml geloescht
- env-sample: BUILD_ENVIRONMENT nach oben, Dev-only Variablen markiert

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
gg committed 2026-09-13 18:40:55 +02:00
1 parent 31ef206bd8
commit 3b3e2893e5
14 files changed
+200 -91

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
.git/
Client/node_modules/
Client/tsout/
App_Server/data/
App_Server/env/
oidc-test/
*.pyc
__pycache__/
+18 -15
View File
@@ -1,6 +1,10 @@
ARG PYTHON_VERSION ARG PYTHON_VERSION
ARG NODE_VERSION ARG NODE_VERSION
ARG NPM_VERSION ARG NPM_VERSION
# ── Stage: prod ──────────────────────────────────────────────────
# Build-Context ist das Repo-Root (.), daher muessen alle COPY-Pfade
# mit App_Server/ praefigiert werden.
FROM python:${PYTHON_VERSION} AS prod FROM python:${PYTHON_VERSION} AS prod
RUN ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime RUN ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
RUN apt-get clean && apt-get update && apt-get install -y locales RUN apt-get clean && apt-get update && apt-get install -y locales
@@ -12,15 +16,19 @@ RUN locale-gen
RUN mkdir -p /usr/opt/pythonapp/App_Server/root /usr/opt/pythonapp/env /usr/var/pythonappdata RUN mkdir -p /usr/opt/pythonapp/App_Server/root /usr/opt/pythonapp/env /usr/var/pythonappdata
WORKDIR /usr/opt/pythonapp WORKDIR /usr/opt/pythonapp
RUN python -m venv --upgrade-deps /usr/opt/pythonapp/env RUN python -m venv --upgrade-deps /usr/opt/pythonapp/env
COPY root/requirements.txt /usr/opt/pythonapp/App_Server/root/requirements.txt COPY App_Server/root/requirements.txt /usr/opt/pythonapp/App_Server/root/requirements.txt
RUN /usr/opt/pythonapp/env/bin/pip install --no-cache-dir --upgrade pip -r /usr/opt/pythonapp/App_Server/root/requirements.txt RUN /usr/opt/pythonapp/env/bin/pip install --no-cache-dir --upgrade pip -r /usr/opt/pythonapp/App_Server/root/requirements.txt
# COPY scripts/init.sh /init.sh
# RUN chmod 552 /init.sh
# # ENTRYPOINT [ "/init.sh" ] # Python-Anwendungscode ins Image kopieren (inkl. templates/index.html)
# ENTRYPOINT [ "sh", "/init.sh" ] COPY App_Server/root/ /usr/opt/pythonapp/App_Server/root/
# CMD []
# Prod-Start-Script
COPY App_Server/scripts/init.sh /usr/opt/pythonapp/App_Server/scripts/init.sh
RUN chmod +x /usr/opt/pythonapp/App_Server/scripts/init.sh
ENTRYPOINT ["sh", "/usr/opt/pythonapp/App_Server/scripts/init.sh"]
# ── Stage: dev ───────────────────────────────────────────────────
FROM prod AS dev FROM prod AS dev
ARG NODE_VERSION ARG NODE_VERSION
ARG NPM_VERSION ARG NPM_VERSION
@@ -41,19 +49,14 @@ RUN apt-get update && \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# --- 3. Node.js + npm installieren --- # --- 3. Node.js + npm installieren ---
RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \ RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \
apt-get install -y nodejs && \ apt-get install -y nodejs && \
npm install -g npm@${NPM_VERSION} npm install -g npm@${NPM_VERSION}
# --- 8. Arbeitsverzeichnis für TypeScript --- # --- 4. Dev-Start-Script kopieren (fuer Konsistenz, wird sonst per bind-mount bereitgestellt) ---
# In dem Entwicklungsverzeichnis (PYTHON_DEV_DIR) existiert dies schon als Unterverzeichnis "Client", daher wird es hier nicht erstellt COPY App_Server/scripts/inittypescriptdev.sh /usr/opt/pythonapp/App_Server/scripts/inittypescriptdev.sh
RUN chmod +x /usr/opt/pythonapp/App_Server/scripts/inittypescriptdev.sh
# --- 9. TypeScript + Rollup installieren ---
# Das Script inittypescriptdev.sh wird in der Entwicklungsumgebung ausgeführt, um die TypeScript-Umgebung zu initialisieren.
# Daher ist es nicht notwendig, es hier zu kopieren und auszuführen.
# COPY ./scripts/inittypescriptdev.sh /usr/opt/pythonapp/App_Server/scripts/inittypescriptdev.sh
# RUN chmod +x /usr/opt/pythonapp/App_Server/scripts/inittypescriptdev.sh
ENTRYPOINT ["sh", "/usr/opt/pythonapp/App_Server/scripts/inittypescriptdev.sh"] ENTRYPOINT ["sh", "/usr/opt/pythonapp/App_Server/scripts/inittypescriptdev.sh"]
CMD ["/usr/opt/pythonapp/env/bin/python", "root/runserver.py", "-D"] CMD ["/usr/opt/pythonapp/env/bin/python", "/usr/opt/pythonapp/App_Server/root/runserver.py", "-D"]
+3 -3
View File
@@ -4,7 +4,7 @@ from settings import Configuration
from db import dbauth from db import dbauth
from db import dbapp from db import dbapp
from auth.model.checkdb import checkupdates as checkupdatesauth from auth.model.checkdb import checkupdates as checkupdatesauth
from os import path import os
login_manager = LoginManager() login_manager = LoginManager()
@@ -12,7 +12,7 @@ login_manager = LoginManager()
def init_app(): def init_app():
app = Flask(__name__) app = Flask(__name__)
config: Configuration = Configuration("root/config.ini") config: Configuration = Configuration("/usr/opt/pythonapp/App_Server/root/config.ini")
_projektname = config.app_projectname _projektname = config.app_projectname
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////usr/var/pythonappdb/{}.db".format(_projektname) app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////usr/var/pythonappdb/{}.db".format(_projektname)
@@ -20,7 +20,7 @@ def init_app():
"auth": "sqlite:////usr/var/pythonappdb/auth.db", "auth": "sqlite:////usr/var/pythonappdb/auth.db",
"appdb": "sqlite:////usr/var/pythonappdb/{}.db".format(_projektname) "appdb": "sqlite:////usr/var/pythonappdb/{}.db".format(_projektname)
} }
app.config["DEBUG"] = path.exists("root/debug") app.config["DEBUG"] = os.environ.get("APP_DEBUG", "false").lower() in ("true", "1", "yes")
app.config["PROJEKTNAME"] = config.app_projectname app.config["PROJEKTNAME"] = config.app_projectname
app.config["APPID"] = config.app_appid app.config["APPID"] = config.app_appid
app.config["APPVERSION"] = config.clientapp_version app.config["APPVERSION"] = config.clientapp_version
+6 -15
View File
@@ -1,16 +1,7 @@
# Python virtual Environment anlegen #!/bin/bash
cd /usr/opt/pythonapp # Startet den Python-Server im Prod-Modus.
# Wenn es die Datei pyvenv.cfg im Unterverzeichnis env nocht nicht gibt, muss das # pip install ist nicht mehr noetig — Abhaengigkeiten sind im Image.
# virtuelle Environment angelegt werden # Kein cd noetig — alle Pfade sind absolut.
# if [ ! -s env/pyvenv.cfg ] # Python-Imports funktionieren ueber sys.path[0] (Verzeichnis des Scripts).
# then
# echo "Creating Python Virtual environment..."
# python -m venv --upgrade-deps /usr/opt/pythonapp/env
# echo "Python Virtual environment created."
# fi
echo "Installing Python requirements..."
env/bin/pip install -r root/requirements.txt
echo "Python requirements installed."
echo "Starting Python-Server..." echo "Starting Python-Server..."
env/bin/python root/runserver.py exec /usr/opt/pythonapp/env/bin/python /usr/opt/pythonapp/App_Server/root/runserver.py
+1 -1
View File
@@ -38,5 +38,5 @@ export function getIniValue(value){
return result["APP"][value] return result["APP"][value]
} }
var inifile = readFileSync("../App_Server/root/config.ini").toString() var inifile = readFileSync("/usr/opt/pythonapp/App_Server/root/config.ini").toString()
result = parseINIString(inifile) result = parseINIString(inifile)
+3
View File
@@ -1,4 +1,7 @@
{ {
"scripts": {
"build": "tsc && rollup -c rollup.config.mjs"
},
"dependencies": { "dependencies": {
"mithril": "^2.2.2" "mithril": "^2.2.2"
}, },
+28 -2
View File
@@ -1,6 +1,32 @@
ARG NGINX_VERSION ARG NGINX_VERSION
ARG NODE_VERSION
ARG NPM_VERSION
# ── Stage: frontend — baut das TypeScript-JS-Bundle ──────────────
# Node.js, npm und node_modules landen NICHT im Prod-Image.
FROM node:${NODE_VERSION}-bookworm-slim AS frontend
# Zielverzeichnis fuer rollup-Output erstellen (absoluter Pfad wie in rollup.config.mjs)
RUN mkdir -p /usr/opt/pythonapp/NGINX_Server/html/static
WORKDIR /usr/opt/pythonapp/Client
# Erst package.json + lockfile kopieren (besseres Layer-Caching)
COPY Client/package.json Client/package-lock.json* ./
RUN npm ci || npm install
# Rest des Client-Quellcodes kopieren
COPY Client/ ./
# config.ini wird fuer rollup benoetigt (inireader.mjs liest Version/Name)
COPY App_Server/root/config.ini /usr/opt/pythonapp/App_Server/root/config.ini
# tsc + rollup ausfuehren — Output geht nach /usr/opt/pythonapp/NGINX_Server/html/static/
RUN npm run build
# ── Stage: nginx ────────────────────────────────────────────────
FROM nginx:${NGINX_VERSION} FROM nginx:${NGINX_VERSION}
RUN ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime RUN ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
RUN mkdir -p /etc/certs /etc/nginx/templates RUN mkdir -p /etc/certs /etc/nginx/templates
COPY 10-select-ssl.sh /docker-entrypoint.d/10-select-ssl.sh COPY NGINX_Server/10-select-ssl.sh /docker-entrypoint.d/10-select-ssl.sh
RUN chmod +x /docker-entrypoint.d/10-select-ssl.sh RUN chmod +x /docker-entrypoint.d/10-select-ssl.sh
# NGINX Config-Templates ins Image kopieren (in Prod; Dev ueberschreibt per bind-mount)
COPY NGINX_Server/configtemplates/ /etc/nginx/configtemplates/
# Alle statischen Dateien aus dem Repo kopieren (CSS, favicon, fonts, logo)
COPY NGINX_Server/html/static/ /usr/share/nginx/html/static/
# JS-Bundle aus der frontend-Stage ueberschreibt ggf. vorhandene alte JS-Dateien
COPY --from=frontend /usr/opt/pythonapp/NGINX_Server/html/static/ /usr/share/nginx/html/static/
+16 -14
View File
@@ -2,15 +2,19 @@ name: kbpbase
services: services:
nginx-proxy: nginx-proxy:
build: build:
context: NGINX_Server context: . # Repo-Root (fuer frontend-Stage im NGINX-Dockerfile)
args: # Übergibt die ARGS an das dockerfile dockerfile: NGINX_Server/Dockerfile # explizit, da Context nicht mehr NGINX_Server/
NGINX_VERSION: ${NGINX_VERSION} args:
NGINX_VERSION: ${NGINX_VERSION}
NODE_VERSION: ${NODE_VERSION}
NPM_VERSION: ${NPM_VERSION}
ports: ports:
- ${NGINX_HOST_PORT}:4430 - ${NGINX_HOST_PORT}:4430
volumes: volumes:
- ${NGINX_STATIC_DIR}:/usr/share/nginx/html:ro # NGINX_STATIC_DIR entfaellt in Prod — statische Dateien sind im NGINX-Image
- ${NGINX_CONFIG_TEMPLATE_DIR}:/etc/nginx/configtemplates:ro # NGINX_CONFIG_TEMPLATE_DIR entfaellt in Prod — Templates sind im Image
# Beide werden in Dev per bind-mount ueberschrieben (siehe docker-compose.dev.yaml)
- ${NGINX_CERTS}:/etc/certs - ${NGINX_CERTS}:/etc/certs
environment: environment:
- NGINX_USE_SSL=${NGINX_USE_SSL:-true} - NGINX_USE_SSL=${NGINX_USE_SSL:-true}
@@ -19,15 +23,13 @@ services:
- NGINX_SERVER_NAME=${NGINX_SERVER_NAME} - NGINX_SERVER_NAME=${NGINX_SERVER_NAME}
pythonapp: pythonapp:
build: build:
context: App_Server context: . # Repo-Root (fuer COPY-Pfade im Dockerfile)
# target: kommt aus dem prod oder dev dockerfile dockerfile: App_Server/Dockerfile # explizit, da Context nicht mehr App_Server/
args: # Übergibt die ARGS an das dockerfile args:
PYTHON_VERSION: ${PYTHON_VERSION} PYTHON_VERSION: ${PYTHON_VERSION}
NODE_VERSION: ${NODE_VERSION} # fuer dev-Stage
NPM_VERSION: ${NPM_VERSION} # fuer dev-Stage
volumes: volumes:
#- ${PYTHON_APP_DIR}:/usr/opt/pythonapp/root
- ${PYTHON_DB_DIR}:/usr/var/pythonappdb - ${PYTHON_DB_DIR}:/usr/var/pythonappdb
- python-venv:/usr/opt/pythonapp/env # python-venv Volume entfaellt — venv ist im Image
# - ${PYTHON_ENV_DIR}:/usr/opt/pythonapp/env # (dev-Stage definiert eigenen Volume in docker-compose.dev.yaml)
volumes:
python-venv:
+16 -3
View File
@@ -6,17 +6,30 @@ services:
service: pythonapp service: pythonapp
build: build:
target: dev target: dev
args: # Übergibt die ARGS an das dockerfile args:
# PYTHON_VERSION: ${PYTHON_VERSION}
NODE_VERSION: ${NODE_VERSION:-18} NODE_VERSION: ${NODE_VERSION:-18}
NPM_VERSION: ${NPM_VERSION:-8} NPM_VERSION: ${NPM_VERSION:-8}
environment: environment:
# Globales Vibe-Home innerhalb des Workspace-Bind-Mounts, damit es auf dem Host persistiert # Globales Vibe-Home innerhalb des Workspace-Bind-Mounts, damit es auf dem Host persistiert
- VIBE_HOME=/usr/opt/pythonapp/.vibe-global - VIBE_HOME=/usr/opt/pythonapp/.vibe-global
# Debug-Modus aktivieren — Werkzeug-Reloader statt Waitress
- APP_DEBUG=true
volumes: volumes:
- ${PYTHON_DEV_DIR}:/usr/opt/pythonapp - ${PYTHON_DEV_DIR}:/usr/opt/pythonapp
# - ${TYPESCRIPT_SRC_DIR}:/usr/opt/typescript # python-venv-dev: venv als Volume, da der bind-mount das Image-venv ueberlagert
- python-venv-dev:/usr/opt/pythonapp/env
- node-modules:/usr/opt/typescript/node_modules - node-modules:/usr/opt/typescript/node_modules
nginx-proxy:
extends:
file: docker-compose.base.yaml
service: nginx-proxy
volumes:
# Statische Dateien per bind-mount — Aenderungen (tsc/rollup, CSS) sofort sichtbar
- ${NGINX_STATIC_DIR}:/usr/share/nginx/html:ro
# Config-Templates per bind-mount — Aenderungen an NGINX-Config sofort sichtbar
- ${NGINX_CONFIG_TEMPLATE_DIR}:/etc/nginx/configtemplates:ro
volumes: volumes:
python-venv-dev:
node-modules: node-modules:
+6 -2
View File
@@ -6,5 +6,9 @@ services:
service: pythonapp service: pythonapp
build: build:
target: prod target: prod
volumes: # Kein Code-bind-mount mehr — Code ist im Image
- ${PYTHON_APP_DIR}:/usr/opt/pythonapp nginx-proxy:
extends:
file: docker-compose.base.yaml
service: nginx-proxy
# Kein STATIC_DIR bind-mount mehr — statische Dateien sind im NGINX-Image
-27
View File
@@ -1,27 +0,0 @@
services:
nginx-proxy:
build:
context: NGINX_Server
args: # Übergibt die ARGS an das dockerfile
NGINX_VERSION: ${NGINX_VERSION}
ports:
- ${NGINX_HOST_PORT}:4430
volumes:
- ${NGINX_STATIC_DIR}:/usr/share/nginx/html:ro
- ${NGINX_CONFIG_TEMPLATE_DIR}:/etc/nginx/configtemplates:ro
- ${NGINX_CERTS}:/etc/certs
environment:
- NGINX_USE_SSL=${NGINX_USE_SSL:-true}
- NGINX_CERT=${NGINX_CERT}
- NGINX_CERT_KEY=${NGINX_CERT_KEY}
- NGINX_SERVER_NAME=${NGINX_SERVER_NAME}
pythonapp:
build:
context: App_Server
args: # Übergibt die ARGS an das dockerfile
PYTHON_VERSION: ${PYTHON_VERSION}
volumes:
- ${PYTHON_APP_DIR}:/usr/opt/pythonapp/root
- ${PYTHON_DB_DIR}:/usr/var/pythonappdb
# - ${PYTHON_ENV_DIR}:/usr/opt/pythonapp/env
+15 -9
View File
@@ -1,3 +1,12 @@
# =============================================================================
# BUILD-UMGEBUNG (zentrale Einstellung — hier dev/prod umschalten)
# =============================================================================
# Bestimmt, welche docker-compose-*.yaml neben der base-Datei geladen wird.
# COMPOSE_FILE wird von Docker Compose automatisch ausgewertet (auch via .env);
# mehrere Dateien werden durch ':' getrennt und nacheinander gemerged.
BUILD_ENVIRONMENT=dev
COMPOSE_FILE=docker-compose.base.yaml:docker-compose.${BUILD_ENVIRONMENT}.yaml
# Parameter für NGINX-Server # Parameter für NGINX-Server
NGINX_VERSION=mainline-alpine NGINX_VERSION=mainline-alpine
# SSL für NGINX aktivieren (true) oder deaktivieren (false). # SSL für NGINX aktivieren (true) oder deaktivieren (false).
@@ -5,7 +14,11 @@ NGINX_VERSION=mainline-alpine
NGINX_USE_SSL=true NGINX_USE_SSL=true
NGINX_HOST_PORT=443 NGINX_HOST_PORT=443
NGINX_SERVER_NAME=kbp_crm.mylocal.de NGINX_SERVER_NAME=kbp_crm.mylocal.de
# NGINX_STATIC_DIR: nur in Dev benoetigt (bind-mount fuer statische Dateien).
# In Prod liegen die statischen Dateien im NGINX-Image.
NGINX_STATIC_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/NGINX_Server/html NGINX_STATIC_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/NGINX_Server/html
# NGINX_CONFIG_TEMPLATE_DIR: nur in Dev benoetigt (bind-mount fuer NGINX-Templates).
# In Prod liegen die Templates im NGINX-Image.
NGINX_CONFIG_TEMPLATE_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/NGINX_Server/configtemplates NGINX_CONFIG_TEMPLATE_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/NGINX_Server/configtemplates
NGINX_CERTS=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/NGINX_Server/certs NGINX_CERTS=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/NGINX_Server/certs
NGINX_CERT=wildcard.mylocal.crt NGINX_CERT=wildcard.mylocal.crt
@@ -13,7 +26,8 @@ NGINX_CERT_KEY=wildcard.mylocal.key
# Parameter for Python App-Server # Parameter for Python App-Server
PYTHON_VERSION=slim-bookworm PYTHON_VERSION=slim-bookworm
PYTHON_APP_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/App_Server/root # PYTHON_APP_DIR entfaellt — Code wird in Prod ins Image gebaut (Option B).
# In Dev wird PYTHON_DEV_DIR als bind-mount verwendet (siehe docker-compose.dev.yaml).
PYTHON_DEV_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm PYTHON_DEV_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm
PYTHON_DB_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/App_Server/data PYTHON_DB_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/App_Server/data
# PYTHON_ENV_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/App_Server/env # PYTHON_ENV_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/App_Server/env
@@ -22,14 +36,6 @@ PYTHON_DB_DIR=/home/schoschi/Entwicklung/Projekte_Runden/kbcrm/App_Server/data
NODE_VERSION=lts NODE_VERSION=lts
NPM_VERSION=latest NPM_VERSION=latest
# Umgebung für Docker-Compose-Stack (prod oder dev).
# Bestimmt, welche docker-compose-*.yaml neben der base-Datei geladen wird.
# COMPOSE_FILE wird von Docker Compose automatisch ausgewertet (auch via .env);
# mehrere Dateien werden durch ':' getrennt und nacheinander gemerged.
# Dadurch entfällt der mehrfache Aufruf des -f Parameters beim docker compose Aufruf.
BUILD_ENVIRONMENT=dev
COMPOSE_FILE=docker-compose.base.yaml:docker-compose.${BUILD_ENVIRONMENT}.yaml
# ============================================================================= # =============================================================================
# ZITADEL OIDC SETTINGS # ZITADEL OIDC SETTINGS
# ============================================================================= # =============================================================================
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
# Deploy-Script: Promotion nach PROD (manuelles OK erforderlich)
# Wird manuell aufgerufen, nachdem test-prod verifiziert wurde.
# Voraussetzungen auf dem Server: git, docker, docker compose.
set -euo pipefail
# Konfiguration — an die jeweilige Server-Umgebung anpassen
REPO_DIR=/opt/kbcrm-prod/repo
COMPOSE_FILE=docker-compose.prod.yaml
ENV_FILE=/opt/kbcrm-prod/.env
PROD_PORT=443
echo "=== Deploy KB-CRM PROD ==="
# Sicherheitsabfrage — nur bei manueller Eingabe von "yes" wird fortgesetzt
echo "This will deploy to PRODUCTION. Continue? (yes/no)"
read -r confirmation
if [ "$confirmation" != "yes" ]; then
echo "Aborted."
exit 1
fi
# 1. Code aktualisieren
cd "$REPO_DIR"
echo "=== Pulling latest code ==="
git fetch origin main
git checkout main
git reset --hard origin/main
# 2. Images neu bauen und Container starten
echo "=== Building and starting containers ==="
docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d --build
# 3. Health-Check
echo "=== Waiting for container startup ==="
sleep 10
if curl -sf "http://localhost:${PROD_PORT}/health-check" >/dev/null 2>&1; then
echo "Health check: OK"
else
echo "WARNING: Health check failed — check container logs with:"
echo " docker compose --env-file $ENV_FILE -f $COMPOSE_FILE logs"
fi
echo "=== Deploy PROD complete ==="
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
# Deploy-Script: Automatisches Deployment nach TEST (test-prod)
# Wird durch Git-Hook/Webhook oder manuell aufgerufen.
# Voraussetzungen auf dem Server: git, docker, docker compose.
set -euo pipefail
# Konfiguration — an die jeweilige Server-Umgebung anpassen
REPO_DIR=/opt/kbcrm-test/repo
COMPOSE_FILE=docker-compose.prod.yaml
ENV_FILE=/opt/kbcrm-test/.env
TEST_PORT=8443
echo "=== Deploy KB-CRM TEST ==="
# 1. Code aktualisieren
cd "$REPO_DIR"
echo "=== Pulling latest code ==="
git fetch origin main
git checkout main
git reset --hard origin/main
# 2. Images neu bauen und Container starten
echo "=== Building and starting containers ==="
docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d --build
# 3. Health-Check
echo "=== Waiting for container startup ==="
sleep 10
if curl -sf "http://localhost:${TEST_PORT}/health-check" >/dev/null 2>&1; then
echo "Health check: OK"
else
echo "WARNING: Health check failed — check container logs with:"
echo " docker compose --env-file $ENV_FILE -f $COMPOSE_FILE logs"
fi
echo "=== Deploy TEST complete ==="