Aller au contenu

Documents & contenus

Paperless-ngx numérise, fait l’OCR et indexe vos documents : recherche plein texte, étiquettes, correspondants, import par dossier ou par e-mail. L’image est publiée par le projet ; ses métadonnées vivent dans un add-on PostgreSQL et sa file de tâches dans un add-on Redis. Deux volumes gardent les originaux et l’index : sans eux, un redéploiement les effacerait.

apiVersion: cassiope.eu/v1alpha2
kind: Blueprint
project:
slug: ged
name: GED
environments:
- slug: production
name: Production
addons:
- slug: metadonnees
name: Métadonnées
templateKey: postgresql
version: "17"
backupEnabled: true
- slug: taches
name: File de traitement
templateKey: redis
version: "7"
services:
- slug: paperless
name: Paperless-ngx
type: web
source:
imageRef: ghcr.io/paperless-ngx/paperless-ngx:3.1.2
portsExposes: "8000"
publiclyExposed: true
resources: { cpuMillicores: 1000, ramMb: 2048 }
volumes:
- name: documents
sizeGb: 50
mountPath: /usr/src/paperless/media
- name: index
sizeGb: 5
mountPath: /usr/src/paperless/data
env:
- key: PAPERLESS_SECRET_KEY
fromSecret: true
- key: PAPERLESS_ADMIN_USER
value: admin
- key: PAPERLESS_ADMIN_PASSWORD
fromSecret: true
- key: PAPERLESS_URL
value: ${CASSIOPE_PUBLIC_URL}
- key: PAPERLESS_TIME_ZONE
value: Europe/Paris
- key: PAPERLESS_OCR_LANGUAGE
value: fra
- key: PAPERLESS_OCR_LANGUAGES
value: fra
- key: PAPERLESS_DBENGINE
value: postgresql
- key: PAPERLESS_DBHOST
value: ${PGDB_HOST}
- key: PAPERLESS_DBPORT
value: ${PGDB_PORT}
- key: PAPERLESS_DBNAME
value: ${PGDB_DATABASE}
- key: PAPERLESS_DBUSER
value: ${PGDB_USER}
- key: PAPERLESS_DBPASS
value: ${PGDB_PASSWORD}
bindings:
- addon: metadonnees
envVarKey: PGDB
derive: split-postgres
- addon: taches
envVarKey: PAPERLESS_REDIS

Paperless ne lit pas d’URL de base de données, mais cinq variables séparées (PAPERLESS_DBHOST…). La liaison derive: split-postgres fournit PGDB_HOST, PGDB_PORT, PGDB_DATABASE, PGDB_USER et PGDB_PASSWORD ; les variables PAPERLESS_DB* les citent avec ${…} (voir Variables d’environnement). PAPERLESS_URL suit l’adresse publique du service. Le premier démarrage crée le compte admin.

Valeurs à fournir à l’import :

{
"production/paperless": {
"PAPERLESS_SECRET_KEY": "une longue chaîne aléatoire",
"PAPERLESS_ADMIN_PASSWORD": "…"
}
}

Ghost (licence MIT) est une plateforme de publication moderne : éditeur fluide, pages et articles, newsletters, abonnements et adhésions payantes, thèmes, SEO et sauvegarde en un clic. L’image officielle ghost tourne sur MySQL 8, uniquement.

Deux services : Ghost et son MySQL. Comme pour PrestaShop, la base est un service plutôt qu’un add-on : Ghost veut l’hôte, le port, l’utilisateur, le mot de passe et le nom de la base séparément, et ses variables d’environnement s’écrivent en minuscules avec des doubles soulignés (database__connection__host), une forme que les variables de la plateforme n’acceptent pas. Le blueprint passe donc par un fichier config.production.json monté dans le conteneur, dont les ${…} sont remplacés au déploiement.

apiVersion: cassiope.eu/v1alpha2
kind: Blueprint
project:
slug: site-editorial
name: Site éditorial
environments:
- slug: production
name: Production
services:
- slug: mysql
name: Base du site
type: worker
source:
imageRef: mysql:8.4
healthcheckCommand: mysqladmin ping -h 127.0.0.1
resources: { cpuMillicores: 500, ramMb: 1024 }
env:
- key: MYSQL_DATABASE
value: ghost
- key: MYSQL_USER
value: ghost
- key: MYSQL_PASSWORD
fromSecret: true
- key: MYSQL_ROOT_PASSWORD
fromSecret: true
volumes:
- { name: donnees, sizeGb: 10, mountPath: /var/lib/mysql }
exposure: { port: 3306, protocol: tcp }
- slug: ghost
name: Ghost
type: web
dependsOn: [mysql]
source:
imageRef: ghost:6.73.0
portsExposes: "2368"
publiclyExposed: true
resources: { cpuMillicores: 500, ramMb: 1024 }
env:
- key: GHOST_URL
value: ${CASSIOPE_PUBLIC_URL}
volumes:
- { name: contenu, sizeGb: 20, mountPath: /var/lib/ghost/content }
files:
- mountPath: /var/lib/ghost/config.production.json
content: |
{
"url": "${GHOST_URL}",
"server": { "host": "0.0.0.0", "port": 2368 },
"database": {
"client": "mysql",
"connection": {
"host": "${DB_HOST}",
"port": ${DB_PORT},
"user": "${DB_USER}",
"password": "${DB_PASSWD}",
"database": "${DB_NAME}"
}
},
"paths": { "contentPath": "/var/lib/ghost/content" }
}
links:
- from: ghost
to: mysql
envKeyPrefix: DB
envCopies:
- { from: MYSQL_DATABASE, as: DB_NAME }
- { from: MYSQL_USER, as: DB_USER }
- { from: MYSQL_PASSWORD, as: DB_PASSWD }

Valeurs à fournir à l’import : les deux mots de passe MySQL (openssl rand -hex 24). Ghost n’a pas de compte administrateur à déclarer.

{
"values": {
"production/mysql": {
"MYSQL_PASSWORD": "à générer",
"MYSQL_ROOT_PASSWORD": "à générer"
}
}
}

Ce qu’il faut savoir :

  • Le compte propriétaire se crée dans le navigateur. Ouvrez https://<adresse>/ghost/ : Ghost affiche son assistant d’installation et vous demande le nom du site, votre e-mail et votre mot de passe. Faites-le tout de suite après le déploiement, c’est le premier arrivé qui devient propriétaire.
  • L’adresse est figée dans la configuration. GHOST_URL reprend l’adresse publique du service (${CASSIOPE_PUBLIC_URL}) ; Ghost s’en sert pour tous ses liens et redirige vers elle. Pour passer à votre propre nom de domaine, ajoutez-le au service, mettez à jour GHOST_URL, puis redéployez.
  • Le volume /var/lib/ghost/content est indispensable. Il porte les images téléversées, les thèmes et les fichiers de l’éditeur ; sans lui, tout disparaît au redéploiement.
  • Ordre de déploiement : mysql, puis ghost. ghost déclare dependsOn: [mysql] et mysql un healthcheck : la plateforme lance la base, attend qu’elle réponde, puis Ghost, qui crée ses tables au premier démarrage.
  • L’envoi d’e-mails n’est pas configuré. Les invitations d’équipe, la réinitialisation de mot de passe et les newsletters en ont besoin : ajoutez un bloc "mail" (SMTP) au fichier de configuration, ou utilisez un service d’envoi comme Mailgun pour les newsletters.