Files
opencrm/docker-compose.yml
T
duffyduck 7d07d52774 docker: App-User statt root für DB-Connection nutzen
Bisher: Backend connectete als root (mit DB_ROOT_PASSWORD) – zu viele
Privilegien (GRANT ALL ON *.*).

Jetzt: Backend nutzt den App-User ${DB_USER}, den MariaDB beim ersten
Container-Start automatisch über MARIADB_USER/MARIADB_PASSWORD anlegt.
Dieser User bekommt von MariaDB direkt GRANT ALL PRIVILEGES auf
${DB_NAME}.* (= nur die OpenCRM-Datenbank, keine anderen Schemas).

Ausreichend für Prisma db push (DDL+DML auf opencrm.*),
nicht ausreichend für Schema-übergreifende Operationen oder
mysql.user-Manipulation – wie es sein soll.

DB_ROOT_PASSWORD bleibt für Adminer / Notfall-Wartung.
.env.example dokumentiert den Mechanismus.

Live-verifiziert:
- Container läuft mit DATABASE_URL=mysql://opencrm:***@db:3306/opencrm
- Prisma db push synced Schema
- Login + alle CRUD-Operationen funktionieren

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:06:43 +02:00

106 lines
3.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenCRM komplettes Setup: MariaDB + Backend/Frontend + Adminer
# Konfiguration über ./.env (siehe ./.env.example)
#
# Quick-Start (Compose v2):
# cp .env.example .env # Werte anpassen (Secrets rotieren!)
# docker compose up -d # erstes Mal: holt Images, baut Backend, startet alles
# Quick-Start (Compose v1, Legacy):
# docker-compose up -d
#
# Browser:
# http://localhost:${OPENCRM_PORT} # CRM
# http://localhost:${ADMINER_PORT} # DB-UI
#
# Daten liegen alle unter ./data/* Bind-Mounts statt Volumes (auf Wunsch).
#version: '3.8'
services:
db:
image: mariadb:10.11
container_name: opencrm-db
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MARIADB_DATABASE: ${DB_NAME}
MARIADB_USER: ${DB_USER}
MARIADB_PASSWORD: ${DB_PASSWORD}
ports:
# Externe Erreichbarkeit für lokale DB-Tools (TablePlus etc.).
# Auf 127.0.0.1 binden kein public exposure.
- "127.0.0.1:${DB_PORT:-3306}:3306"
volumes:
- ${DB_DATA_DIR:-./data/db}:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 20s
interval: 10s
timeout: 5s
retries: 5
opencrm:
build:
context: .
dockerfile: backend/Dockerfile
container_name: opencrm-app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
# Connection ins Container-Netzwerk (Service-Name = Hostname).
# Wir nutzen den App-User ${DB_USER}, der von MariaDB beim ersten Start
# automatisch mit GRANT ALL PRIVILEGES auf ${DB_NAME}.* angelegt wird
# (über MARIADB_USER/MARIADB_PASSWORD). KEIN root für die App.
DATABASE_URL: "mysql://${DB_USER}:${DB_PASSWORD}@db:3306/${DB_NAME}"
JWT_SECRET: ${JWT_SECRET}
JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
NODE_ENV: production
PORT: 3001
LISTEN_ADDR: 0.0.0.0
CORS_ORIGINS: ${CORS_ORIGINS:-}
RUN_SEED: ${RUN_SEED:-false}
ports:
- "${OPENCRM_PORT:-3010}:3001"
volumes:
# Bind-Mounts für persistente Daten unter ./data/
- ${UPLOADS_DIR:-./data/uploads}:/app/uploads
- ${FACTORY_DEFAULTS_DIR:-./data/factory-defaults}:/app/factory-defaults
- ${BACKUPS_DIR:-./data/backups}:/app/prisma/backups
adminer:
image: adminer:latest
container_name: opencrm-adminer
restart: unless-stopped
depends_on:
- db
environment:
ADMINER_DEFAULT_SERVER: db
ADMINER_DESIGN: ${ADMINER_DESIGN:-pepa-linha}
# Adminers offizieller entrypoint linkt nur Designs, deren CSS exakt
# `adminer.css` heißt. Manche Designs (dracula, adminer-dark) haben aber
# `adminer-dark.css`. Wir machen den Symlink generisch: erstes .css im
# gewählten Design wird verlinkt. Danach übergeben wir an den originalen
# entrypoint.sh.
entrypoint:
- /bin/sh
- -c
- >
cd /var/www/html;
if [ -n "$$ADMINER_DESIGN" ] && [ -d "designs/$$ADMINER_DESIGN" ]; then
CSS=$$(ls designs/$$ADMINER_DESIGN/*.css 2>/dev/null | head -1);
if [ -n "$$CSS" ]; then
ln -sf "$$CSS" adminer.css;
touch .adminer-init;
echo "[adminer-bootstrap] Theme aktiv: $$ADMINER_DESIGN -> $$CSS";
else
echo "[adminer-bootstrap] Design '$$ADMINER_DESIGN' enthält kein CSS nutze Default";
fi;
fi;
exec entrypoint.sh docker-php-entrypoint "$$@"
- --
command: ["php", "-S", "[::]:8080", "-t", "/var/www/html"]
ports:
- "127.0.0.1:${ADMINER_PORT:-8090}:8080"