diff --git a/.env.example b/.env.example index 2b5e310..2f99de2 100644 --- a/.env.example +++ b/.env.example @@ -37,33 +37,15 @@ S3_ACCESS_KEY=fedeo-minio S3_SECRET_KEY=change-this-minio-password S3_BUCKET=fedeo -# Datei-Backend. S3 bleibt aktuell der Standard; Seafile ist im Stack -# vorbereitet und kann nach dem Backend-Umbau als vollständiges File-Backend -# genutzt werden. +# Datei-Backend. S3 bleibt aktuell der Standard; Seafile kann als externer +# Dateidienst angebunden werden, sobald der Backend-Umbau aktiviert ist. FEDEO_FILE_BACKEND=s3 -# Seafile CE läuft im Standard-Stack unter der Hauptdomain auf /files. -SEAFILE_SERVER_HOSTNAME=app.example.com -SEAFILE_SERVER_PROTOCOL=https -SEAFILE_SITE_ROOT=/files/ -SEAFILE_BASE_URL=https://app.example.com/files -SEAFILE_INTERNAL_URL=http://seafile:80 -SEAFILE_IMAGE=seafileltd/seafile-mc:13.0-latest -SEAFILE_DB_IMAGE=mariadb:10.11 -SEAFILE_REDIS_IMAGE=redis:7-alpine -INIT_SEAFILE_MYSQL_ROOT_PASSWORD=change-this-seafile-root-password -SEAFILE_MYSQL_DB_USER=seafile -SEAFILE_MYSQL_DB_PASSWORD=change-this-seafile-db-password -SEAFILE_REDIS_PASSWORD=change-this-seafile-redis-password -SEAFILE_JWT_PRIVATE_KEY=change-this-seafile-jwt-private-key-at-least-32-chars -INIT_SEAFILE_ADMIN_EMAIL=admin@example.com -INIT_SEAFILE_ADMIN_PASSWORD=change-this-seafile-admin-password -SEAFILE_ENABLE_GO_FILESERVER=true -SEAFILE_ENABLE_SEADOC=false -SEAFILE_ENABLE_NOTIFICATION_SERVER=false -SEAFILE_ENABLE_AI=false -SEAFILE_ENABLE_FACE_RECOGNITION=false -SEAFILE_MD_FILE_COUNT_LIMIT=100000 +# Externer Seafile-Dienst, nicht Teil des Standard-Compose-Stacks. +SEAFILE_BASE_URL=https://files.example.com +SEAFILE_INTERNAL_URL=https://files.example.com +SEAFILE_ADMIN_EMAIL=admin@example.com +SEAFILE_ADMIN_PASSWORD=change-this-seafile-admin-password M2M_API_KEY=change-this-m2m-key API_BASE_URL=https://app.example.com/backend diff --git a/README.md b/README.md index dbb3a76..e872870 100644 --- a/README.md +++ b/README.md @@ -122,8 +122,6 @@ mkdir -p /opt/fedeo/traefik/letsencrypt mkdir -p /opt/fedeo/traefik/logs mkdir -p /opt/fedeo/postgres mkdir -p /opt/fedeo/minio -mkdir -p /opt/fedeo/seafile/mysql -mkdir -p /opt/fedeo/seafile/data touch /opt/fedeo/traefik/letsencrypt/acme.json chmod 600 /opt/fedeo/traefik/letsencrypt/acme.json ``` @@ -134,8 +132,7 @@ Als Startpunkt kannst du die Beispielumgebung kopieren: cp .env.example .env ``` -Ersetze anschließend alle Platzhalter und passe mindestens `DOMAIN`, `CONTACT_EMAIL`, Datenbank-, Secret-, SMTP- und S3-Werte an. -Seafile läuft im Standard-Stack unter derselben Domain auf `/files`, zum Beispiel `https://app.example.com/files`. Die für Seafile nötigen technischen Nebenpfade wie `/media`, `/seafhttp` und `/seafdav` werden auf derselben Domain mitgeroutet. +Ersetze anschließend alle Platzhalter und passe mindestens `DOMAIN`, `CONTACT_EMAIL`, Datenbank-, Secret-, SMTP- und S3-Werte an. Seafile ist kein Teil des Standard-Stacks; wenn FEDEO später Seafile als File-Backend nutzen soll, zeigst du die Seafile-Variablen auf einen externen Seafile-Dienst. Alternativ kannst du die Konfiguration geführt erzeugen lassen: @@ -208,27 +205,10 @@ S3_SECRET_KEY=change-this-minio-password S3_BUCKET=fedeo FEDEO_FILE_BACKEND=s3 -SEAFILE_SERVER_HOSTNAME=app.example.com -SEAFILE_SERVER_PROTOCOL=https -SEAFILE_SITE_ROOT=/files/ -SEAFILE_BASE_URL=https://app.example.com/files -SEAFILE_INTERNAL_URL=http://seafile:80 -SEAFILE_IMAGE=seafileltd/seafile-mc:13.0-latest -SEAFILE_DB_IMAGE=mariadb:10.11 -SEAFILE_REDIS_IMAGE=redis:7-alpine -INIT_SEAFILE_MYSQL_ROOT_PASSWORD=change-this-seafile-root-password -SEAFILE_MYSQL_DB_USER=seafile -SEAFILE_MYSQL_DB_PASSWORD=change-this-seafile-db-password -SEAFILE_REDIS_PASSWORD=change-this-seafile-redis-password -SEAFILE_JWT_PRIVATE_KEY=change-this-seafile-jwt-private-key-at-least-32-chars -INIT_SEAFILE_ADMIN_EMAIL=admin@example.com -INIT_SEAFILE_ADMIN_PASSWORD=change-this-seafile-admin-password -SEAFILE_ENABLE_GO_FILESERVER=true -SEAFILE_ENABLE_SEADOC=false -SEAFILE_ENABLE_NOTIFICATION_SERVER=false -SEAFILE_ENABLE_AI=false -SEAFILE_ENABLE_FACE_RECOGNITION=false -SEAFILE_MD_FILE_COUNT_LIMIT=100000 +SEAFILE_BASE_URL=https://files.example.com +SEAFILE_INTERNAL_URL=https://files.example.com +SEAFILE_ADMIN_EMAIL=admin@example.com +SEAFILE_ADMIN_PASSWORD=change-this-seafile-admin-password M2M_API_KEY=change-this-m2m-key API_BASE_URL=https://app.example.com/backend @@ -272,11 +252,11 @@ NUXT_PUBLIC_MATRIX_ELEMENT_URL=https://app.example.com/element Die `FEDEO_BOOTSTRAP_*`-Werte sind für den ersten Start gedacht. Wenn `FEDEO_BOOTSTRAP_ADMIN_EMAIL` und `FEDEO_BOOTSTRAP_ADMIN_PASSWORD` gesetzt sind, legt das Backend idempotent einen Admin-Benutzer, einen ersten Mandanten, eine Administrator-Rolle und grundlegende Stammdaten an. Nach erfolgreichem Erstzugriff solltest du das Bootstrap-Passwort aus der `.env` entfernen oder ändern. -## Docker Compose mit optionalem S3, Seafile und Matrix +## Docker Compose mit optionalem S3 und Matrix Die Selfhost-Konfiguration wird im Betriebsverzeichnis als `docker-compose.yml` abgelegt. Sie startet MinIO standardmäßig mit. Wenn du stattdessen AWS S3, Hetzner Object Storage, Backblaze B2 S3 oder einen anderen externen S3-Dienst nutzen willst, kannst du die Services `minio` und `createbuckets` entfernen und nur die entsprechenden S3-Umgebungsvariablen auf den externen Anbieter zeigen lassen. -Der Stack enthält zusätzlich Seafile CE als vorbereitetes File-Backend. Seafile läuft unter `https://DOMAIN/files`, nutzt MariaDB und Redis intern und ist damit ohne zusätzliche Subdomain erreichbar. Die technischen Seafile-Pfade `/media`, `/seafhttp` und `/seafdav` bleiben auf derselben Domain und werden vom Reverse Proxy an Seafile geleitet. FEDEO nutzt aktuell weiter S3 als Standard; `FEDEO_FILE_BACKEND=s3` bleibt deshalb gesetzt, bis das Backend die Seafile-Integration vollständig unterstützt. +Seafile wird bewusst nicht im Standard-Compose-Stack gestartet. FEDEO kann später gegen einen extern betriebenen Seafile-Dienst sprechen; dafür bleiben `SEAFILE_BASE_URL`, `SEAFILE_INTERNAL_URL`, `SEAFILE_ADMIN_EMAIL` und `SEAFILE_ADMIN_PASSWORD` als generische Anbindungswerte vorgesehen. `FEDEO_FILE_BACKEND=s3` bleibt der Standard, bis die Backend-Integration für Seafile vollständig umgesetzt ist. Der Matrix-Stack ist im Selfhost-Compose direkt enthalten. Er umfasst Synapse, eine eigene PostgreSQL-Datenbank für Synapse, Redis, `.well-known/matrix`, coturn, LiveKit, den LiveKit-JWT-Service und Element Web. Das einfache Selfhost-Setup nutzt nur `DOMAIN`: Synapse läuft unter `https://DOMAIN/_matrix`, Matrix-Well-Known unter `https://DOMAIN/.well-known/matrix`, LiveKit unter `https://DOMAIN/livekit/sfu`, der JWT-Service unter `https://DOMAIN/livekit/jwt` und Element Web unter `https://DOMAIN/element`. diff --git a/docker-compose.selfhost.yml b/docker-compose.selfhost.yml index daf3a5e..4e292a4 100644 --- a/docker-compose.selfhost.yml +++ b/docker-compose.selfhost.yml @@ -80,111 +80,6 @@ services: networks: - internal - seafile-db: - image: ${SEAFILE_DB_IMAGE:-mariadb:10.11} - container_name: fedeo-seafile-db - restart: unless-stopped - environment: - MYSQL_ROOT_PASSWORD: ${INIT_SEAFILE_MYSQL_ROOT_PASSWORD} - MYSQL_LOG_CONSOLE: "true" - MARIADB_AUTO_UPGRADE: "1" - volumes: - - ./seafile/mysql:/var/lib/mysql - healthcheck: - test: - [ - "CMD", - "/usr/local/bin/healthcheck.sh", - "--connect", - "--mariadbupgrade", - "--innodb_initialized", - ] - interval: 20s - start_period: 30s - timeout: 5s - retries: 10 - networks: - - internal - - seafile-redis: - image: ${SEAFILE_REDIS_IMAGE:-redis:7-alpine} - container_name: fedeo-seafile-redis - restart: unless-stopped - command: - - /bin/sh - - -c - - redis-server --requirepass "$$REDIS_PASSWORD" - environment: - REDIS_PASSWORD: ${SEAFILE_REDIS_PASSWORD} - networks: - - internal - - seafile: - image: ${SEAFILE_IMAGE:-seafileltd/seafile-mc:13.0-latest} - container_name: fedeo-seafile - restart: unless-stopped - depends_on: - seafile-db: - condition: service_healthy - seafile-redis: - condition: service_started - volumes: - - ./seafile/data:/shared - environment: - SEAFILE_MYSQL_DB_HOST: seafile-db - SEAFILE_MYSQL_DB_PORT: 3306 - SEAFILE_MYSQL_DB_USER: ${SEAFILE_MYSQL_DB_USER:-seafile} - SEAFILE_MYSQL_DB_PASSWORD: ${SEAFILE_MYSQL_DB_PASSWORD} - INIT_SEAFILE_MYSQL_ROOT_PASSWORD: ${INIT_SEAFILE_MYSQL_ROOT_PASSWORD} - SEAFILE_MYSQL_DB_CCNET_DB_NAME: ${SEAFILE_MYSQL_DB_CCNET_DB_NAME:-ccnet_db} - SEAFILE_MYSQL_DB_SEAFILE_DB_NAME: ${SEAFILE_MYSQL_DB_SEAFILE_DB_NAME:-seafile_db} - SEAFILE_MYSQL_DB_SEAHUB_DB_NAME: ${SEAFILE_MYSQL_DB_SEAHUB_DB_NAME:-seahub_db} - TIME_ZONE: ${TIME_ZONE:-Europe/Berlin} - INIT_SEAFILE_ADMIN_EMAIL: ${INIT_SEAFILE_ADMIN_EMAIL} - INIT_SEAFILE_ADMIN_PASSWORD: ${INIT_SEAFILE_ADMIN_PASSWORD} - SEAFILE_SERVER_HOSTNAME: ${SEAFILE_SERVER_HOSTNAME:-${DOMAIN}} - SEAFILE_SERVER_PROTOCOL: ${SEAFILE_SERVER_PROTOCOL:-https} - SITE_ROOT: ${SEAFILE_SITE_ROOT:-/files/} - NON_ROOT: ${SEAFILE_NON_ROOT:-false} - JWT_PRIVATE_KEY: ${SEAFILE_JWT_PRIVATE_KEY} - SEAFILE_LOG_TO_STDOUT: ${SEAFILE_LOG_TO_STDOUT:-true} - ENABLE_GO_FILESERVER: ${SEAFILE_ENABLE_GO_FILESERVER:-true} - ENABLE_SEADOC: ${SEAFILE_ENABLE_SEADOC:-false} - CACHE_PROVIDER: redis - REDIS_HOST: seafile-redis - REDIS_PORT: 6379 - REDIS_PASSWORD: ${SEAFILE_REDIS_PASSWORD} - ENABLE_NOTIFICATION_SERVER: ${SEAFILE_ENABLE_NOTIFICATION_SERVER:-false} - ENABLE_SEAFILE_AI: ${SEAFILE_ENABLE_AI:-false} - ENABLE_FACE_RECOGNITION: ${SEAFILE_ENABLE_FACE_RECOGNITION:-false} - MD_FILE_COUNT_LIMIT: ${SEAFILE_MD_FILE_COUNT_LIMIT:-100000} - healthcheck: - test: ["CMD-SHELL", "curl -fsS -o /dev/null http://localhost:80/files/ || exit 1"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - labels: - - traefik.enable=true - - "traefik.http.middlewares.fedeo-seafile-accounts.redirectregex.regex=^https?://([^/]+)/accounts/(.*)" - - "traefik.http.middlewares.fedeo-seafile-accounts.redirectregex.replacement=https://$${1}/files/accounts/$${2}" - - traefik.http.middlewares.fedeo-seafile-accounts.redirectregex.permanent=false - - "traefik.http.routers.fedeo-seafile.rule=Host(`${DOMAIN}`) && (PathPrefix(`/files`) || PathPrefix(`/media`) || PathPrefix(`/seafhttp`) || PathPrefix(`/seafdav`))" - - traefik.http.routers.fedeo-seafile.entrypoints=websecure - - traefik.http.routers.fedeo-seafile.tls.certresolver=letsencrypt - - traefik.http.routers.fedeo-seafile.priority=100 - - traefik.http.routers.fedeo-seafile-accounts.rule=Host(`${DOMAIN}`) && PathPrefix(`/accounts`) - - traefik.http.routers.fedeo-seafile-accounts.entrypoints=websecure - - traefik.http.routers.fedeo-seafile-accounts.tls.certresolver=letsencrypt - - traefik.http.routers.fedeo-seafile-accounts.middlewares=fedeo-seafile-accounts - - traefik.http.routers.fedeo-seafile-accounts.priority=110 - - traefik.http.routers.fedeo-seafile-accounts.service=noop@internal - - traefik.http.services.fedeo-seafile.loadbalancer.server.port=80 - - traefik.docker.network=fedeo_web - networks: - - web - - internal - backend: image: git.federspiel.tech/flfeders/fedeo/backend:dev container_name: fedeo-backend @@ -219,8 +114,8 @@ services: FEDEO_FILE_BACKEND: ${FEDEO_FILE_BACKEND:-s3} SEAFILE_BASE_URL: ${SEAFILE_BASE_URL} SEAFILE_INTERNAL_URL: ${SEAFILE_INTERNAL_URL} - SEAFILE_ADMIN_EMAIL: ${INIT_SEAFILE_ADMIN_EMAIL} - SEAFILE_ADMIN_PASSWORD: ${INIT_SEAFILE_ADMIN_PASSWORD} + SEAFILE_ADMIN_EMAIL: ${SEAFILE_ADMIN_EMAIL} + SEAFILE_ADMIN_PASSWORD: ${SEAFILE_ADMIN_PASSWORD} M2M_API_KEY: ${M2M_API_KEY} API_BASE_URL: ${API_BASE_URL} GOCARDLESS_BASE_URL: ${GOCARDLESS_BASE_URL} diff --git a/scripts/selfhost-setup.sh b/scripts/selfhost-setup.sh index 73b82b0..3fd4a31 100755 --- a/scripts/selfhost-setup.sh +++ b/scripts/selfhost-setup.sh @@ -108,14 +108,6 @@ random_secret() { fi } -random_urlsafe_secret() { - if command -v openssl >/dev/null 2>&1; then - openssl rand -hex 32 | tr -d '\n' - else - LC_ALL=C tr -dc 'A-Za-z0-9' "$ENV_FILE" <