fix: nextcloud test
This commit is contained in:
parent
61acf79feb
commit
fa60bf6165
14 changed files with 221 additions and 6 deletions
52
CLAUDE.md
Normal file
52
CLAUDE.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## What this repo is
|
||||
|
||||
Coolify stack definitions for LAIL — a French cooperative cloud infrastructure. Stacks are Docker Compose files deployed via Coolify (no local build/run tooling exists; deployment is done through the Coolify UI against the remote host).
|
||||
|
||||
## Repository structure
|
||||
|
||||
```
|
||||
stacks/
|
||||
├── lail-apps/ # Shared LAIL applications (one instance per service)
|
||||
├── lail-infra/ # Infrastructure services (Authentik SSO, SFTPGo)
|
||||
├── lail-sites/ # Website deployments
|
||||
└── structures/ # Multi-tenant per-organization Nextcloud instances
|
||||
└── _templates/ # Copy and replace XXXXXX placeholders for new orgs
|
||||
```
|
||||
|
||||
## Docker Compose patterns used across stacks
|
||||
|
||||
**Environment variables** — Coolify injects these automatically; reference them in compose files as-is:
|
||||
- `SERVICE_URL_<NAME>` — public URL for the service
|
||||
- `SERVICE_USER_<NAME>` / `SERVICE_PASSWORD_<NAME>` — generated credentials
|
||||
- `SERVICE_PASSWORD_64_<NAME>` — 64-char password (used for Redis, long secrets)
|
||||
- `SERVICE_HEX_32_<NAME>` — 32-char hex value (used for encryption keys/secrets)
|
||||
|
||||
**Data paths** — all persistent data lives on the host at:
|
||||
- `/data/lail-apps/<app-name>/` — shared apps
|
||||
- `/data/lail-structures/<org-name>/` — per-organization data
|
||||
|
||||
**Database readiness** — always use `depends_on` with `condition: service_healthy` and define `healthcheck` on the DB service (`pg_isready` for Postgres, `redis-cli ping` for Redis).
|
||||
|
||||
**Database version** — PostgreSQL 16-alpine is the standard.
|
||||
|
||||
## SSO/OIDC
|
||||
|
||||
Central identity provider is Authentik at `sso.lail.cloud`. When adding SSO to a new service, use its OIDC endpoints. Each app's README.md contains notes on SSO configuration status and any app-specific quirks.
|
||||
|
||||
## Adding a new structure (multi-tenant org)
|
||||
|
||||
1. Copy `stacks/structures/_templates/` into `stacks/structures/<org-name>/`
|
||||
2. Replace every occurrence of `XXXXXX` with the org name
|
||||
3. Update data paths: `/data/lail-structures/XXXXXX/` → `/data/lail-structures/<org-name>/`
|
||||
|
||||
## Special requirements
|
||||
|
||||
**Collabora** requires Docker host-level capabilities: `cap_add: [SYS_ADMIN]`, device `/dev/fuse`, and AppArmor profile `unconfined`. This cannot run in a constrained Docker environment.
|
||||
|
||||
**Paheko** embeds its PHP config (`config.local.php`) as an inline file written via `docker-compose.yaml` — edits to PHP config go in the compose file itself, not a separate file.
|
||||
|
||||
**N8N** uses a queue-mode architecture: separate `worker` and `task-runner` services alongside the main service, all sharing a Redis queue and Postgres DB.
|
||||
1
stacks/lail-apps/lail-forgejo/README.md
Normal file
1
stacks/lail-apps/lail-forgejo/README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
- docker-compose sans SSO, défini à la main après installation
|
||||
1
stacks/lail-apps/lail-n8n/README.md
Normal file
1
stacks/lail-apps/lail-n8n/README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
- Premier docker-compose sans SSO
|
||||
138
stacks/lail-apps/lail-n8n/docker-compose.yml
Normal file
138
stacks/lail-apps/lail-n8n/docker-compose.yml
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
services:
|
||||
n8n:
|
||||
image: 'n8nio/n8n:2.10.4'
|
||||
environment:
|
||||
- SERVICE_URL_N8N_5678
|
||||
- 'N8N_EDITOR_BASE_URL=${SERVICE_URL_N8N}'
|
||||
- 'WEBHOOK_URL=${SERVICE_URL_N8N}'
|
||||
- 'N8N_HOST=${SERVICE_URL_N8N}'
|
||||
- 'N8N_PROTOCOL=${N8N_PROTOCOL:-https}'
|
||||
- 'GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-UTC}'
|
||||
- 'TZ=${TZ:-UTC}'
|
||||
- DB_TYPE=postgresdb
|
||||
- 'DB_POSTGRESDB_DATABASE=${POSTGRES_DB:-n8n}'
|
||||
- DB_POSTGRESDB_HOST=postgresql
|
||||
- DB_POSTGRESDB_PORT=5432
|
||||
- DB_POSTGRESDB_USER=$SERVICE_USER_POSTGRES
|
||||
- DB_POSTGRESDB_SCHEMA=public
|
||||
- DB_POSTGRESDB_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- EXECUTIONS_MODE=queue
|
||||
- QUEUE_BULL_REDIS_HOST=redis
|
||||
- QUEUE_HEALTH_CHECK_ACTIVE=true
|
||||
- 'N8N_ENCRYPTION_KEY=${SERVICE_PASSWORD_ENCRYPTION}'
|
||||
- N8N_RUNNERS_ENABLED=true
|
||||
- N8N_RUNNERS_MODE=external
|
||||
- 'N8N_RUNNERS_BROKER_LISTEN_ADDRESS=${N8N_RUNNERS_BROKER_LISTEN_ADDRESS:-0.0.0.0}'
|
||||
- 'N8N_RUNNERS_BROKER_PORT=${N8N_RUNNERS_BROKER_PORT:-5679}'
|
||||
- N8N_RUNNERS_AUTH_TOKEN=$SERVICE_PASSWORD_N8N
|
||||
- 'N8N_NATIVE_PYTHON_RUNNER=${N8N_NATIVE_PYTHON_RUNNER:-true}'
|
||||
- 'N8N_RUNNERS_MAX_CONCURRENCY=${N8N_RUNNERS_MAX_CONCURRENCY:-5}'
|
||||
- OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true
|
||||
- 'N8N_BLOCK_ENV_ACCESS_IN_NODE=${N8N_BLOCK_ENV_ACCESS_IN_NODE:-true}'
|
||||
- 'N8N_GIT_NODE_DISABLE_BARE_REPOS=${N8N_GIT_NODE_DISABLE_BARE_REPOS:-true}'
|
||||
- 'N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-true}'
|
||||
- 'N8N_PROXY_HOPS=${N8N_PROXY_HOPS:-1}'
|
||||
- 'N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=${N8N_SKIP_AUTH_ON_OAUTH_CALLBACK:-false}'
|
||||
volumes:
|
||||
- '/data/lail-apps/lail-n8n/n8n-data:/home/node/.n8n'
|
||||
depends_on:
|
||||
postgresql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- 'wget -qO- http://127.0.0.1:5678/'
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
n8n-worker:
|
||||
image: 'n8nio/n8n:2.10.4'
|
||||
command: worker
|
||||
environment:
|
||||
- 'GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-UTC}'
|
||||
- 'TZ=${TZ:-UTC}'
|
||||
- DB_TYPE=postgresdb
|
||||
- 'DB_POSTGRESDB_DATABASE=${POSTGRES_DB:-n8n}'
|
||||
- DB_POSTGRESDB_HOST=postgresql
|
||||
- DB_POSTGRESDB_PORT=5432
|
||||
- DB_POSTGRESDB_USER=$SERVICE_USER_POSTGRES
|
||||
- DB_POSTGRESDB_SCHEMA=public
|
||||
- DB_POSTGRESDB_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- EXECUTIONS_MODE=queue
|
||||
- QUEUE_BULL_REDIS_HOST=redis
|
||||
- QUEUE_HEALTH_CHECK_ACTIVE=true
|
||||
- 'N8N_ENCRYPTION_KEY=${SERVICE_PASSWORD_ENCRYPTION}'
|
||||
- N8N_RUNNERS_ENABLED=true
|
||||
- N8N_RUNNERS_MODE=external
|
||||
- 'N8N_RUNNERS_BROKER_LISTEN_ADDRESS=${N8N_RUNNERS_BROKER_LISTEN_ADDRESS:-0.0.0.0}'
|
||||
- 'N8N_RUNNERS_BROKER_PORT=${N8N_RUNNERS_BROKER_PORT:-5679}'
|
||||
- N8N_RUNNERS_AUTH_TOKEN=$SERVICE_PASSWORD_N8N
|
||||
- 'N8N_NATIVE_PYTHON_RUNNER=${N8N_NATIVE_PYTHON_RUNNER:-true}'
|
||||
- 'N8N_RUNNERS_MAX_CONCURRENCY=${N8N_RUNNERS_MAX_CONCURRENCY:-5}'
|
||||
- 'N8N_BLOCK_ENV_ACCESS_IN_NODE=${N8N_BLOCK_ENV_ACCESS_IN_NODE:-true}'
|
||||
- 'N8N_GIT_NODE_DISABLE_BARE_REPOS=${N8N_GIT_NODE_DISABLE_BARE_REPOS:-true}'
|
||||
- 'N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-true}'
|
||||
- 'N8N_PROXY_HOPS=${N8N_PROXY_HOPS:-1}'
|
||||
- 'N8N_SKIP_AUTH_ON_OAUTH_CALLBACK=${N8N_SKIP_AUTH_ON_OAUTH_CALLBACK:-false}'
|
||||
volumes:
|
||||
- '/data/lail-apps/lail-n8n/n8n-data:/home/node/.n8n'
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- 'wget -qO- http://127.0.0.1:5678/healthz'
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
depends_on:
|
||||
n8n:
|
||||
condition: service_healthy
|
||||
postgresql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
postgresql:
|
||||
image: 'postgres:16-alpine'
|
||||
volumes:
|
||||
- 'postgresql-data:/var/lib/postgresql/data'
|
||||
environment:
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- 'POSTGRES_DB=${POSTGRES_DB:-n8n}'
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
redis:
|
||||
image: 'redis:6-alpine'
|
||||
volumes:
|
||||
- 'redis-data:/data'
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- redis-cli
|
||||
- ping
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
task-runners:
|
||||
image: 'n8nio/runners:2.10.4'
|
||||
environment:
|
||||
- 'N8N_RUNNERS_TASK_BROKER_URI=${N8N_RUNNERS_TASK_BROKER_URI:-http://n8n-worker:5679}'
|
||||
- N8N_RUNNERS_AUTH_TOKEN=$SERVICE_PASSWORD_N8N
|
||||
- 'N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT=${N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT:-15}'
|
||||
- 'N8N_RUNNERS_MAX_CONCURRENCY=${N8N_RUNNERS_MAX_CONCURRENCY:-5}'
|
||||
depends_on:
|
||||
- n8n
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- 'wget -qO- http://127.0.0.1:5680/'
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
|
||||
3
stacks/lail-apps/lail-paheko/README.md
Normal file
3
stacks/lail-apps/lail-paheko/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
- Impossible de le faire marcher correctement via les variables d'environnement
|
||||
- Image Docker non maintenue par libretic (ancienne version)
|
||||
- Image Docker "bololo/paheko" devrait fonctionner, mais pas de containers séparés...
|
||||
|
|
@ -1,24 +1,26 @@
|
|||
|
||||
services:
|
||||
nextcloud:
|
||||
image: 'lscr.io/linuxserver/nextcloud:latest'
|
||||
image: 'nextcloud:latest'
|
||||
environment:
|
||||
- SERVICE_URL_NEXTCLOUD_80
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- 'TZ=${TZ:-Europe/Paris}'
|
||||
- 'POSTGRES_DB=${POSTGRES_DB:-nextcloud}'
|
||||
- 'POSTGRES_USER=${SERVICE_USER_POSTGRES}'
|
||||
- 'POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}'
|
||||
- POSTGRES_HOST=nextcloud-db
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_HOST_PORT=6379
|
||||
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER:-lailadmin}
|
||||
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
|
||||
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN}
|
||||
- OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
|
||||
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
|
||||
- OIDC_SLUG=${OIDC_SLUG}
|
||||
volumes:
|
||||
- '/data/lail-structures/structest/nextcloud/nextcloud-config:/config'
|
||||
- '/data/lail-structures/structest/nextcloud/nextcloud-data:/data'
|
||||
- '/data/lail-structures/structest/nextcloud/nextcloud-app:/var/www/html'
|
||||
- '/data/lail-structures/structest/nextcloud/nextcloud-data:/var/www/html/data'
|
||||
- './post-install-oidc.sh:/docker-entrypoint-hooks.d/post-installation/010-oidc.sh:ro'
|
||||
depends_on:
|
||||
nextcloud-db:
|
||||
condition: service_healthy
|
||||
|
|
|
|||
18
stacks/structures/structest/nextcloud/post-install-oidc.sh
Normal file
18
stacks/structures/structest/nextcloud/post-install-oidc.sh
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
OCC="php /var/www/html/occ"
|
||||
|
||||
# Install or enable user_oidc app
|
||||
$OCC app:install user_oidc 2>/dev/null || $OCC app:enable user_oidc
|
||||
|
||||
# Register Authentik as OIDC provider
|
||||
$OCC user_oidc:provider "Authentik" \
|
||||
--clientid="${OIDC_CLIENT_ID}" \
|
||||
--clientsecret="${OIDC_CLIENT_SECRET}" \
|
||||
--discoveryuri="https://sso.lail.cloud/application/o/${OIDC_SLUG}/.well-known/openid-configuration" \
|
||||
--mapping-uid="preferred_username" \
|
||||
--unique-uid=0 \
|
||||
--check-bearer=1
|
||||
|
||||
echo "OIDC provider Authentik configured."
|
||||
Loading…
Reference in a new issue