From 846e853a99c54a68a5c299d40b3e7138de43e574 Mon Sep 17 00:00:00 2001 From: Nak0x Date: Thu, 9 Jul 2026 15:55:46 +0200 Subject: [PATCH] Claude work --- cantaloupe.properties | 32 ++++++ docker-compose.coolify.yml | 196 +++++++++++++++++++++++++++++++++ docker-compose.yml | 214 +++++++++++++++++++++++++++++++++++++ 3 files changed, 442 insertions(+) create mode 100644 cantaloupe.properties create mode 100644 docker-compose.coolify.yml create mode 100644 docker-compose.yml diff --git a/cantaloupe.properties b/cantaloupe.properties new file mode 100644 index 0000000..4f914fb --- /dev/null +++ b/cantaloupe.properties @@ -0,0 +1,32 @@ +http.enabled = true +http.host = 0.0.0.0 +http.port = 80 +http.http2.enabled = false +https.enabled = false + +endpoint.iiif.1.enabled = false +endpoint.iiif.2.enabled = true + +source.static = S3Source +S3Source.endpoint = http://ark-garage:3900 +S3Source.region = local +S3Source.top_domain = iiif.ark.nak0x.dev +S3Source.lookup_strategy = ScriptLookupStrategy +S3Source.BasicLookupStrategy.bucket.name = + +cache.server.derivative.enabled = true +cache.server.derivative = S3Cache +cache.server.derivative.ttl_seconds = 604800 +S3Cache.endpoint = http://ark-garage:3900 +S3Cache.region = local +S3Cache.bucket.name = iiif-cache + +log.application.level = info +log.application.ConsoleAppender.enabled = true +log_error_responses = true + +HeapCache.target_size = 512M +HeapCache.persist = false + +processor.downscale_filter = lanczos3 +processor.upscale_filter = lanczos3 diff --git a/docker-compose.coolify.yml b/docker-compose.coolify.yml new file mode 100644 index 0000000..8094e26 --- /dev/null +++ b/docker-compose.coolify.yml @@ -0,0 +1,196 @@ +--- +# Variante pour adoption comme ressource "Docker Compose" gérée par Coolify. +# Différences vs docker-compose.yml (CLI) : +# - noms de SERVICE uniques ark-* (Coolify écrase container_name mais garde le nom de service +# comme alias DNS ; les noms génériques db/redis entreraient en collision sur le réseau coolify) +# - volumes déclarés "external" avec les noms existants (arkindex-deploy_*) -> aucune perte de données +# - montages de config en chemins absolus (Coolify gère son propre répertoire de service) +# - secrets (PG_PASS, GK_ID, GK_SECRET) fournis via les variables d'env de la ressource Coolify + +services: + + ark-database: + image: postgis/postgis:17-3.5 + restart: unless-stopped + shm_size: '256mb' + environment: + POSTGRES_USER: arkindex + POSTGRES_PASSWORD: ${PG_PASS} + POSTGRES_DB: arkindex + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U arkindex -d arkindex"] + interval: 10s + timeout: 5s + retries: 10 + mem_limit: 1g + networks: [ark] + + ark-redis: + image: redis:alpine + restart: unless-stopped + volumes: + - redisdata:/data + mem_limit: 256m + networks: [ark] + + ark-solr: + image: solr:9 + restart: unless-stopped + command: ["solr", "-f", "-cloud", "-noprompt"] + environment: + SOLR_JAVA_MEM: "-Xms256m -Xmx512m" + volumes: + - solrdata:/var/solr + mem_limit: 768m + networks: [ark] + + ark-garage: + image: dxflrs/garage:v2.1.0 + restart: unless-stopped + volumes: + - garagedata:/var/lib/garage + - /home/nak0x/arkindex-deploy/garage.toml:/etc/garage.toml:ro + mem_limit: 512m + networks: [ark, coolify] + labels: + - traefik.enable=true + - traefik.docker.network=coolify + - traefik.http.routers.ark-s3.entrypoints=https + - traefik.http.routers.ark-s3.tls=true + - traefik.http.routers.ark-s3.tls.certresolver=letsencrypt + - traefik.http.routers.ark-s3.service=ark-s3 + - traefik.http.routers.ark-s3.rule=Host(`s3.ark.nak0x.dev`) || Host(`staging.s3.ark.nak0x.dev`) || Host(`thumbnails.s3.ark.nak0x.dev`) || Host(`export.s3.ark.nak0x.dev`) || Host(`training.s3.ark.nak0x.dev`) || Host(`ponos-logs.s3.ark.nak0x.dev`) || Host(`ponos-artifacts.s3.ark.nak0x.dev`) || Host(`ingest.s3.ark.nak0x.dev`) || Host(`uploads.s3.ark.nak0x.dev`) || Host(`iiif-cache.s3.ark.nak0x.dev`) + - traefik.http.routers.ark-s3.middlewares=ark-s3-cors + - traefik.http.services.ark-s3.loadbalancer.server.port=3900 + - traefik.http.middlewares.ark-s3-cors.headers.accesscontrolallowmethods=GET,OPTIONS,PUT,POST,DELETE,HEAD + - traefik.http.middlewares.ark-s3-cors.headers.accesscontrolallowheaders=* + - traefik.http.middlewares.ark-s3-cors.headers.accesscontrolalloworiginlist=https://ark.nak0x.dev + - traefik.http.middlewares.ark-s3-cors.headers.addvaryheader=true + - traefik.http.routers.ark-s3-http.entrypoints=http + - traefik.http.routers.ark-s3-http.rule=Host(`s3.ark.nak0x.dev`) || Host(`staging.s3.ark.nak0x.dev`) || Host(`thumbnails.s3.ark.nak0x.dev`) || Host(`export.s3.ark.nak0x.dev`) || Host(`training.s3.ark.nak0x.dev`) || Host(`ponos-logs.s3.ark.nak0x.dev`) || Host(`ponos-artifacts.s3.ark.nak0x.dev`) || Host(`ingest.s3.ark.nak0x.dev`) || Host(`uploads.s3.ark.nak0x.dev`) || Host(`iiif-cache.s3.ark.nak0x.dev`) + - traefik.http.routers.ark-s3-http.middlewares=ark-redir-https + - traefik.http.middlewares.ark-redir-https.redirectscheme.scheme=https + + ark-cantaloupe: + image: registry.gitlab.teklia.com/iiif/cantaloupe:5.0.7 + restart: unless-stopped + environment: + AWS_ACCESS_KEY_ID: ${GK_ID} + AWS_SECRET_ACCESS_KEY: ${GK_SECRET} + volumes: + - /home/nak0x/arkindex-deploy/cantaloupe.properties:/etc/cantaloupe.properties:ro + depends_on: + - ark-garage + mem_limit: 1g + networks: [ark, coolify] + labels: + - traefik.enable=true + - traefik.docker.network=coolify + - traefik.http.routers.ark-iiif.entrypoints=https + - traefik.http.routers.ark-iiif.tls=true + - traefik.http.routers.ark-iiif.tls.certresolver=letsencrypt + - traefik.http.routers.ark-iiif.service=ark-iiif + - traefik.http.routers.ark-iiif.rule=Host(`iiif.ark.nak0x.dev`) || Host(`uploads.iiif.ark.nak0x.dev`) || Host(`ingest.iiif.ark.nak0x.dev`) + - traefik.http.services.ark-iiif.loadbalancer.server.port=80 + - traefik.http.routers.ark-iiif-http.entrypoints=http + - traefik.http.routers.ark-iiif-http.rule=Host(`iiif.ark.nak0x.dev`) || Host(`uploads.iiif.ark.nak0x.dev`) || Host(`ingest.iiif.ark.nak0x.dev`) + - traefik.http.routers.ark-iiif-http.middlewares=ark-redir-https + + ark-backend: + image: registry.gitlab.teklia.com/arkindex/backend:1.12.2 + restart: unless-stopped + environment: + CONFIG_PATH: /arkindex.yml + MAX_WORKERS: "3" + volumes: + - /home/nak0x/arkindex-deploy/config.yml:/arkindex.yml:ro + depends_on: + ark-database: + condition: service_healthy + ark-redis: + condition: service_started + healthcheck: + test: ["CMD-SHELL", "wget --spider --quiet http://localhost:8000/api/v1/health/ || exit 1"] + interval: 15s + timeout: 5s + retries: 10 + start_period: 30s + mem_limit: 1g + networks: [ark, coolify] + labels: + - traefik.enable=true + - traefik.docker.network=coolify + - traefik.http.routers.ark-api.entrypoints=https + - traefik.http.routers.ark-api.tls=true + - traefik.http.routers.ark-api.tls.certresolver=letsencrypt + - traefik.http.routers.ark-api.priority=100 + - traefik.http.routers.ark-api.rule=Host(`ark.nak0x.dev`) && (PathPrefix(`/api/`) || PathPrefix(`/api-docs/`) || PathPrefix(`/admin/`) || PathPrefix(`/rq/`) || PathPrefix(`/static/`)) + - traefik.http.routers.ark-api.service=ark-api + - traefik.http.services.ark-api.loadbalancer.server.port=8000 + - traefik.http.routers.ark-api-http.entrypoints=http + - traefik.http.routers.ark-api-http.priority=100 + - traefik.http.routers.ark-api-http.rule=Host(`ark.nak0x.dev`) && (PathPrefix(`/api/`) || PathPrefix(`/api-docs/`) || PathPrefix(`/admin/`) || PathPrefix(`/rq/`) || PathPrefix(`/static/`)) + - traefik.http.routers.ark-api-http.middlewares=ark-redir-https + + ark-worker: + image: registry.gitlab.teklia.com/arkindex/backend:1.12.2 + restart: unless-stopped + command: ["arkindex", "rqworker-pool", "--num-workers", "1", "-v", "1", "default", "high", "tasks", "export", "iiif"] + environment: + CONFIG_PATH: /arkindex.yml + user: root + volumes: + - /home/nak0x/arkindex-deploy/config.yml:/arkindex.yml:ro + - /tmp:/tmp + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + ark-database: + condition: service_healthy + ark-redis: + condition: service_started + mem_limit: 1500m + networks: [ark, coolify] + + ark-front: + image: registry.gitlab.teklia.com/arkindex/frontend:1.12.2 + restart: unless-stopped + depends_on: + - ark-backend + mem_limit: 256m + networks: [ark, coolify] + labels: + - traefik.enable=true + - traefik.docker.network=coolify + - traefik.http.routers.ark-front.entrypoints=https + - traefik.http.routers.ark-front.tls=true + - traefik.http.routers.ark-front.tls.certresolver=letsencrypt + - traefik.http.routers.ark-front.priority=1 + - traefik.http.routers.ark-front.rule=Host(`ark.nak0x.dev`) + - traefik.http.routers.ark-front.service=ark-front + - traefik.http.services.ark-front.loadbalancer.server.port=80 + - traefik.http.routers.ark-front-http.entrypoints=http + - traefik.http.routers.ark-front-http.priority=1 + - traefik.http.routers.ark-front-http.rule=Host(`ark.nak0x.dev`) + - traefik.http.routers.ark-front-http.middlewares=ark-redir-https + +volumes: + pgdata: + external: true + name: arkindex-deploy_pgdata + redisdata: + external: true + name: arkindex-deploy_redisdata + solrdata: + external: true + name: arkindex-deploy_solrdata + garagedata: + external: true + name: arkindex-deploy_garagedata + +networks: + ark: + name: ark + coolify: + external: true diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..83df3bf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,214 @@ +--- +# Arkindex — déploiement mono-projet sur Coolify (domaine ark.nak0x.dev) +# Routage/TLS délégués au proxy Traefik de Coolify (réseau externe "coolify"). +# Réseau interne "ark" pour la communication entre services. + +x-restart: &restart + restart: unless-stopped + +services: + + db: + <<: *restart + container_name: ark-database + image: postgis/postgis:17-3.5 + shm_size: '256mb' + environment: + POSTGRES_USER: arkindex + POSTGRES_PASSWORD: ${PG_PASS} + POSTGRES_DB: arkindex + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U arkindex -d arkindex"] + interval: 10s + timeout: 5s + retries: 10 + mem_limit: 1g + networks: + - ark + + redis: + <<: *restart + container_name: ark-redis + image: redis:alpine + volumes: + - redisdata:/data + mem_limit: 256m + networks: + - ark + + solr: + <<: *restart + container_name: ark-solr + image: solr:9 + command: ["solr", "-f", "-cloud", "-noprompt"] + environment: + SOLR_JAVA_MEM: "-Xms256m -Xmx512m" + volumes: + - solrdata:/var/solr + mem_limit: 768m + networks: + - ark + + garage: + <<: *restart + container_name: ark-garage + image: dxflrs/garage:v2.1.0 + volumes: + - garagedata:/var/lib/garage + - ./garage.toml:/etc/garage.toml:ro + mem_limit: 512m + networks: + - ark + - coolify + labels: + - traefik.enable=true + - traefik.docker.network=coolify + # --- S3 API (virtual-hosted style: un host par bucket) --- + - traefik.http.routers.ark-s3.entrypoints=https + - traefik.http.routers.ark-s3.tls=true + - traefik.http.routers.ark-s3.tls.certresolver=letsencrypt + - traefik.http.routers.ark-s3.service=ark-s3 + - traefik.http.routers.ark-s3.rule=Host(`s3.ark.nak0x.dev`) || Host(`staging.s3.ark.nak0x.dev`) || Host(`thumbnails.s3.ark.nak0x.dev`) || Host(`export.s3.ark.nak0x.dev`) || Host(`training.s3.ark.nak0x.dev`) || Host(`ponos-logs.s3.ark.nak0x.dev`) || Host(`ponos-artifacts.s3.ark.nak0x.dev`) || Host(`ingest.s3.ark.nak0x.dev`) || Host(`uploads.s3.ark.nak0x.dev`) || Host(`iiif-cache.s3.ark.nak0x.dev`) + - traefik.http.routers.ark-s3.middlewares=ark-s3-cors + - traefik.http.services.ark-s3.loadbalancer.server.port=3900 + # CORS: Garage ne gère pas CORS sur l'API S3, on le fait dans Traefik + - traefik.http.middlewares.ark-s3-cors.headers.accesscontrolallowmethods=GET,OPTIONS,PUT,POST,DELETE,HEAD + - traefik.http.middlewares.ark-s3-cors.headers.accesscontrolallowheaders=* + - traefik.http.middlewares.ark-s3-cors.headers.accesscontrolalloworiginlist=https://ark.nak0x.dev + - traefik.http.middlewares.ark-s3-cors.headers.addvaryheader=true + # http -> https + - traefik.http.routers.ark-s3-http.entrypoints=http + - traefik.http.routers.ark-s3-http.rule=Host(`s3.ark.nak0x.dev`) || Host(`staging.s3.ark.nak0x.dev`) || Host(`thumbnails.s3.ark.nak0x.dev`) || Host(`export.s3.ark.nak0x.dev`) || Host(`training.s3.ark.nak0x.dev`) || Host(`ponos-logs.s3.ark.nak0x.dev`) || Host(`ponos-artifacts.s3.ark.nak0x.dev`) || Host(`ingest.s3.ark.nak0x.dev`) || Host(`uploads.s3.ark.nak0x.dev`) || Host(`iiif-cache.s3.ark.nak0x.dev`) + - traefik.http.routers.ark-s3-http.middlewares=ark-redir-https + - traefik.http.middlewares.ark-redir-https.redirectscheme.scheme=https + + cantaloupe: + <<: *restart + container_name: ark-cantaloupe + image: registry.gitlab.teklia.com/iiif/cantaloupe:5.0.7 + environment: + AWS_ACCESS_KEY_ID: ${GK_ID} + AWS_SECRET_ACCESS_KEY: ${GK_SECRET} + volumes: + - ./cantaloupe.properties:/etc/cantaloupe.properties:ro + depends_on: + - garage + mem_limit: 1g + networks: + - ark + - coolify + labels: + - traefik.enable=true + - traefik.docker.network=coolify + - traefik.http.routers.ark-iiif.entrypoints=https + - traefik.http.routers.ark-iiif.tls=true + - traefik.http.routers.ark-iiif.tls.certresolver=letsencrypt + - traefik.http.routers.ark-iiif.service=ark-iiif + - traefik.http.routers.ark-iiif.rule=Host(`iiif.ark.nak0x.dev`) || Host(`uploads.iiif.ark.nak0x.dev`) || Host(`ingest.iiif.ark.nak0x.dev`) + - traefik.http.services.ark-iiif.loadbalancer.server.port=80 + - traefik.http.routers.ark-iiif-http.entrypoints=http + - traefik.http.routers.ark-iiif-http.rule=Host(`iiif.ark.nak0x.dev`) || Host(`uploads.iiif.ark.nak0x.dev`) || Host(`ingest.iiif.ark.nak0x.dev`) + - traefik.http.routers.ark-iiif-http.middlewares=ark-redir-https + + backend: + <<: *restart + container_name: ark-backend + image: registry.gitlab.teklia.com/arkindex/backend:1.12.2 + environment: + CONFIG_PATH: /arkindex.yml + MAX_WORKERS: "3" + volumes: + - ./config.yml:/arkindex.yml:ro + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + healthcheck: + test: ["CMD-SHELL", "wget --spider --quiet http://localhost:8000/api/v1/health/ || exit 1"] + interval: 15s + timeout: 5s + retries: 10 + start_period: 30s + mem_limit: 1g + networks: + - ark + - coolify + labels: + - traefik.enable=true + - traefik.docker.network=coolify + # API / admin / docs / rq / static -> backend (priorité haute) + - traefik.http.routers.ark-api.entrypoints=https + - traefik.http.routers.ark-api.tls=true + - traefik.http.routers.ark-api.tls.certresolver=letsencrypt + - traefik.http.routers.ark-api.priority=100 + - traefik.http.routers.ark-api.rule=Host(`ark.nak0x.dev`) && (PathPrefix(`/api/`) || PathPrefix(`/api-docs/`) || PathPrefix(`/admin/`) || PathPrefix(`/rq/`) || PathPrefix(`/static/`)) + - traefik.http.routers.ark-api.service=ark-api + - traefik.http.services.ark-api.loadbalancer.server.port=8000 + - traefik.http.routers.ark-api-http.entrypoints=http + - traefik.http.routers.ark-api-http.priority=100 + - traefik.http.routers.ark-api-http.rule=Host(`ark.nak0x.dev`) && (PathPrefix(`/api/`) || PathPrefix(`/api-docs/`) || PathPrefix(`/admin/`) || PathPrefix(`/rq/`) || PathPrefix(`/static/`)) + - traefik.http.routers.ark-api-http.middlewares=ark-redir-https + + worker: + <<: *restart + container_name: ark-worker + image: registry.gitlab.teklia.com/arkindex/backend:1.12.2 + command: ["arkindex", "rqworker-pool", "--num-workers", "1", "-v", "1", "default", "high", "tasks", "export", "iiif"] + environment: + CONFIG_PATH: /arkindex.yml + # root requis pour accéder au socket Docker (tâches Ponos) + user: root + volumes: + - ./config.yml:/arkindex.yml:ro + - /tmp:/tmp + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + mem_limit: 1500m + networks: + - ark + - coolify + + front: + <<: *restart + container_name: ark-front + image: registry.gitlab.teklia.com/arkindex/frontend:1.12.2 + depends_on: + - backend + mem_limit: 256m + networks: + - ark + - coolify + labels: + - traefik.enable=true + - traefik.docker.network=coolify + # SPA -> front (catch-all, priorité basse) + - traefik.http.routers.ark-front.entrypoints=https + - traefik.http.routers.ark-front.tls=true + - traefik.http.routers.ark-front.tls.certresolver=letsencrypt + - traefik.http.routers.ark-front.priority=1 + - traefik.http.routers.ark-front.rule=Host(`ark.nak0x.dev`) + - traefik.http.routers.ark-front.service=ark-front + - traefik.http.services.ark-front.loadbalancer.server.port=80 + - traefik.http.routers.ark-front-http.entrypoints=http + - traefik.http.routers.ark-front-http.priority=1 + - traefik.http.routers.ark-front-http.rule=Host(`ark.nak0x.dev`) + - traefik.http.routers.ark-front-http.middlewares=ark-redir-https + +volumes: + pgdata: + redisdata: + solrdata: + garagedata: + +networks: + ark: + name: ark + coolify: + external: true