Erreur Bootstrap lors de l'installation de Discourse : ENOENT - /etc/runit/1.d/letsencrypt

Salut, j’essaie d’installer Discourse en utilisant le processus standard ./discourse-setup, mais je rencontre une erreur lors du bootstrap :

FAILED
--------------------
Errno::ENOENT: No such file or directory @ rb_sysopen - /etc/runit/1.d/letsencrypt
Location of failure: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/replace_command.rb:11:in `read'
replace failed with the params {"filename"=>"/etc/runit/1.d/letsencrypt", "from"=>"/--keylength/", "to"=>"-d forum.mysite.org --keylength"}
bootstrap failed with exit code 1
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.

Il semble que l’erreur soit déclenchée par un plugin qui essaie d’exécuter une commande replace sur le fichier /etc/runit/1.d/letsencrypt, qui n’existe pas dans le conteneur pendant le bootstrap. La ligne pertinente dans le plugin ressemble à ceci :

- replace:
    filename: "/etc/runit/1.d/letsencrypt"
    from: "/--keylength/"
    to: "-d forum.mysite.org --keylength"

Des conseils sur la façon de résoudre ce problème ou de régénérer correctement le fichier manquant ?

Merci d’avance.

Un plugin ? C’est du code cups de votre app.yml, n’est-ce pas ? Essayez-vous d’ajouter un autre certificat ? Comme dans Set up Let’s Encrypt with multiple domains / redirects Pouvez-vous inclure le code réel et les deux certificats ?

Comme vous le soulignez, ce runit n’existe plus, et maintenant cette magie se trouve dans /usr/local/bin/letsencrypt (à l’intérieur du conteneur)

Je pense que vous voulez peut-être quelque chose comme ceci si votre site est www.mysite.org et que vous voulez également qu’il ait un certificat pour forum.mysite.org :

- replace:
    filename: "/usr/local/bin/letsencrypt"
    from: "/-d www.mysite.org/"
    to: "-d www.mysite.org -d forum.mysite.org "
    global: true

Ce que je ferais (ce qui peut ne pas vous être utile) serait d’entrer dans le conteneur, apt update;apt install -y vim puis d’éditer /usr/local/bin/letsencrypt de manière à ce qu’il demande les certificats que vous souhaitez.

J’ai ajouté du code au sujet let’s encrypt lié ci-dessus qui devrait vous permettre d’entrer votre domaine et d’obtenir du code que vous pouvez copier/coller dans votre app.yml.

1 « J'aime »

J’ai rencontré ce qui ressemble au même message d’erreur lors d’une tentative de mise à jour.

Je n’essaie de rien changer concernant les certificats.

Mon fichier app.yml affiche actuellement ceci :

 after_ssl:
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /--keylength/
        to: "-d www.nzarchitecture.net.nz --keylength"

J’ai suivi votre suggestion :

 apt update;apt install -y vim

mais le résultat a été « vim est déjà à la dernière version (2:9.1.0016-1ubuntu7.8). »

Quant à la deuxième étape suggérée, je n’ai aucune idée des certificats que je veux, n’ayant eu aucune intention de changer quoi que ce soit.

OK, après quelques heures de lutte, j’ai réussi à remettre mon site en marche.

J’ai trouvé un ancien fichier app.yml et je l’ai substitué, en supprimant simplement les anciennes références aux plugins qui ont depuis été intégrés à Discourse.

Ce fichier app.yml plus ancien ne contenait pas le code ci-dessous, que j’ai trouvé dans un plus récent.

 after_ssl:
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /--keylength/
        to: "-d www.nzarchitecture.net.nz --keylength"

Je ne me souviens pas avoir ajouté ce code moi-même, bien que j’aie configuré mon site pour utiliser letsencrypt pour les certificats de sécurité gratuits, mais les instructions sur Set up HTTPS support with Let's Encrypt ne semblent pas nécessiter ces lignes du tout, donc je ne sais pas à quoi elles auraient servi.

Quelque chose d’autre aurait-il pu écrire ces lignes dans app.yml ? Par exemple, auraient-elles pu être ajoutées lors d’une mise à jour bêta ?

Au moins pour l’instant, ces lignes supprimées, mon site fonctionne à nouveau et est à jour.

Lorsque mon certificat SSL actuel expirera, je découvrirai peut-être à quoi servaient ces lignes supplémentaires.

Eh bien, si, mais vous ne vous en souvenez pas. :wink:

Si vous avez cette section after_ssl dans votre fichier yml, alors à un moment donné, vous avez configuré les choses de telle sorte que si quelqu’un mettait un www devant votre domaine, il irait à l’adresse www et serait redirigé vers l’adresse non-www sans erreur de certificat.

Ma suggestion était d’installer vim à l’intérieur du conteneur et d’essayer de modifier les fichiers là-bas, mais je pense que mon code à ajouter à app.yml devrait fonctionner.

C’est exact. Et maintenant, si vous visitez https://www.nzarchitecture.net.nz/, vous obtenez une erreur de certificat. Vous pourriez utiliser https://forcewww.com/

Vous pourriez aller sur le lien ci-dessus et obtenir le nouveau code qui, je pense, devrait fonctionner, mais que je n’ai pas testé car je n’ai pas trouvé de site que je mets à jour qui en ait besoin.

Ai-je raison de penser que votre code serait dans les lignes ci-dessous, si je veux que www.nzarchitecture.net.nz soit couvert par le même certificat letsencrypt que nzarchitecture.net.nz ?

after_ssl:
    - replace:
        filename: /usr/local/bin/letsencrypt
        from: /-d nzarchitecture.net.nz /
        to: "-d nzarchitecture.net.nz -d www.nzarchitecture.net.nz "
        global: true

J’ai essayé d’ajouter cette section (excellente terminologie, merci !) à la fin de app.yml, à la place de la section after_ssl: d’origine, et je peux maintenant reconstruire Discourse sans erreurs - mais cela ne semble pas m’aider ; mon navigateur affiche toujours une réponse net::ERR_CERT_COMMON_NAME_INVALID si j’essaie d’utiliser un préfixe ‘www’ avant mon domaine principal/certifié nzarchitecture.net.nz.

Mon app.yml complet ci-dessous, au cas où cela aiderait (mot de passe et adresses e-mail masqués)

## voici le modèle de conteneur Docker Discourse autonome tout-en-un
##
## Après avoir apporté des modifications à ce fichier, vous DEVEZ reconstruire
## /var/discourse/launcher rebuild app
##
## SOYEZ *TRÈS* PRUDENT LORS DE L'ÉDITION !
## LES FICHIERS YAML SONT EXTRÊMEMENT SENSIBLES AUX ERREURS D'ESPACEMENT OU D'ALIGNEMENT !
## visitez http://www.yamllint.com/ pour valider ce fichier si nécessaire

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Décommentez ces deux lignes si vous souhaitez ajouter Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/import/mysql-dep.template.yml"

## quels ports TCP/IP ce conteneur doit-il exposer ?
## Si vous souhaitez que Discourse partage un port avec un autre serveur web comme Apache ou nginx,
## voir https://meta.discourse.org/t/17247 pour plus de détails
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Définissez db_shared_buffers à un maximum de 25 % de la mémoire totale.
  ## sera défini automatiquement par bootstrap en fonction de la RAM détectée, ou vous pouvez le remplacer
  db_shared_buffers: "128MB"

  ## peut améliorer les performances de tri, mais augmente l'utilisation de la mémoire par connexion
  #db_work_mem: "40MB"

  ## Quelle révision Git ce conteneur doit-il utiliser ? (défaut : tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## Combien de requêtes web simultanées sont prises en charge ? Dépend de la mémoire et des cœurs CPU.
  ## sera défini automatiquement par bootstrap en fonction des CPU détectés, ou vous pouvez le remplacer
  UNICORN_WORKERS: 2

  ## TODO : Le nom de domaine auquel cette instance Discourse répondra
  ## Obligatoire. Discourse ne fonctionnera pas avec un simple numéro IP.
  DISCOURSE_HOSTNAME: nzarchitecture.net.nz

  ## Décommentez si vous souhaitez que le conteneur soit démarré avec le même
  ## nom d'hôte (-h option) que celui spécifié ci-dessus (défaut "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO : Liste des e-mails séparés par des virgules qui seront faits administrateurs et développeurs
  ## lors de la première inscription exemple 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: '****************'

  ## TODO : Le serveur de messagerie SMTP utilisé pour valider les nouveaux comptes et envoyer des notifications
  # L'adresse SMTP, le nom d'utilisateur et le mot de passe sont requis
  # ATTENTION le caractère '#' dans le mot de passe SMTP peut causer des problèmes !
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: ****************
  DISCOURSE_SMTP_PASSWORD: "****************"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (facultatif, par défaut true)

  ## Si vous avez ajouté le modèle Lets Encrypt, décommentez ci-dessous pour obtenir un certificat SSL gratuit
  LETSENCRYPT_ACCOUNT_EMAIL: ******************

  ## L'adresse CDN http ou https pour cette instance Discourse (configurée pour tirer)
  ## voir https://meta.discourse.org/t/14857 pour plus de détails
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## Le conteneur Docker est sans état ; toutes les données sont stockées dans /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Les plugins vont ici
## voir https://meta.discourse.org/t/19157 pour plus de détails
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-bbcode.git
## Toutes les commandes personnalisées à exécuter après la construction
run:
  - exec: echo "Début des commandes personnalisées"
  ## Si vous souhaitez définir l'adresse e-mail 'De' pour votre première inscription, décommentez et modifiez :
  ## Après avoir reçu le premier e-mail d'inscription, re-commentez la ligne. Elle ne doit s'exécuter qu'une seule fois.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Fin des commandes personnalisées"

after_ssl:
    - replace:
        filename: /usr/local/bin/letsencrypt
        from: /-d nzarchitecture.net.nz /
        to: "-d nzarchitecture.net.nz -d www.nzarchitecture.net.nz "
        global: true

Le fait qu’il n’y ait aucun fichier dans /usr/local/bin/ fait-il partie du problème ?

Où puis-je trouver le fichier letsencrypt correct à y placer, si c’est ce qui est nécessaire ?

Et, si ‘letsencrypt’ est le nom du fichier à la fin de ce chemin, est-il normal qu’il n’y ait pas d’extension de fichier dans ce nom de fichier ?

Mon idée est de supprimer la ligne after_ssl et de désindenter les autres.

Si vous ajoutez ma clé ssh avec

ssh-import-id-gh pfaffman

Et que vous m’envoyez un e-mail, je verrai ce que je peux faire.

Merci ! @pfaffman

Je viens de vous envoyer un e-mail.

Voici une mise à jour.

L’ajout de ceci à la section run en bas de votre app.yml résoudra le problème de la demande de certificats pour DISCOURSE_HOSTNAME et www.DISCOURSE_HOSTNAME à partir de /usr/local/bin/letsencrypt.

- exec: sed -i "s|-d \\${DISCOURSE_HOSTNAME}|-d \\${DISCOURSE_HOSTNAME} -d www.\\${DISCOURSE_HOSTNAME}|g" /usr/local/bin/letsencrypt

Ceci (d’une manière ou d’une autre ?) suffisait auparavant, mais maintenant, lorsque la demande arrive pour http://www.HOSTNAME/.well-known…, elle est redirigée vers le site non www au lieu d’envoyer le défi qu’elle est censée envoyer. J’ai essayé de faire quelque chose comme ceci :

server {
  listen 80;
  listen [::]:80;
  server_name nzarchitecture.net.nz www.nzarchitecture.net.nz;

  # Servir le défi ACME (Let's Encrypt)
  location ^~ /.well-known/acme-challenge/ {
    root /var/www/discourse/public;  # Assurez-vous que cela correspond à votre webroot Let's Encrypt
    allow all;
  }

  # Rediriger tout le reste vers HTTPS
  location / {
    return 301 https://$host$request_uri;
  }
}

mais je n’ai pas tout à fait compris.

Si quelqu’un de l’équipe écoute, il serait bon qu’il y ait un hook letsencrypt afin que cela puisse être appelé dans un after_letsencrypt. Avant d’apporter ces modifications dans after_ssl, cela fonctionnait, mais il semble que maintenant si nous faisons cela, cela s’exécute après ssl, mais avant letsencrypt.

3 « J'aime »

Je rencontre également ce problème. Je vous tiendrai au courant si je parviens à le résoudre.

Mon DISCOURSE_HOSTNAME est www.textkit.com. Je fais l’inverse de nzarchitecture.net.nz et j’ajoute un nom d’hôte sans www à mon certificat. Cela a fonctionné pour moi :

- exec: sed -i \"s|-d \\${DISCOURSE_HOSTNAME}|-d www.textkit.com -d textkit.com|g\" /usr/local/bin/letsencrypt

Je ne peux pas dire pourquoi @pfaffman et nzarchitecture.net.nz auraient un problème avec sa version, bien que l’ordre des noms d’hôtes dans la mienne puisse être lié.

J’ai aussi rencontré ce problème.

J’ai supprimé ceci (en le commentant) :

  after_ssl:
#    - replace:
#        filename: "/etc/runit/1.d/letsencrypt"
#        from: /--keylength/
#        to: "-d example.com --keylength"
#    - replace:
#        filename: "/etc/nginx/conf.d/discourse.conf"
#        from: /return 301 https.+/
#        to: |
#          return 301 https://$host$request_uri;

et ajouté ceci dans la section run en bas, conformément à @pfaffman :

- exec: sed -i "s|-d \\${DISCOURSE_HOSTNAME}|-d \\${DISCOURSE_HOSTNAME} -d www.\\${DISCOURSE_HOSTNAME}|g" /usr/local/bin/letsencrypt

Cela semble avoir été suffisant pour moi :

  • le site a été reconstruit et semble avoir des certificats valides
  • la redirection de l’apex vers www fonctionne

Merci @pfaffman !

4 « J'aime »

Oh ! Génial. Peut-être que le changement qu’ils ont effectué et qui a permis aux renouvellements de certificats de fonctionner a également résolu le problème que je rencontrais.

Je garderai cela à l’esprit si je rencontre d’autres sites qui en ont besoin avant que la PR ne soit acceptée.

1 « J'aime »

Il y a plusieurs éléments à prendre en compte ici. Cela a fonctionné pour moi lors de cette reconstruction, je vous tiendrai informé ici si la situation change !

1 « J'aime »

Le PR pour autoriser les renouvellements de certificats n’a pas encore été fusionné – cette partie est toujours en attente.

Une fois fusionné, cela devrait permettre un app.yml beaucoup plus simplifié.

2 « J'aime »

Étrangement, ce bout de code fonctionne sur l’un de mes sites, mais l’ancien code (et seulement l’ancien code) fonctionne sur mon autre site. :person_shrugging:

Enfin, espérons que tout cela sera bientôt sans objet !

1 « J'aime »

C’est très étrange. Est-ce que discourse_docker est épinglé à une ancienne version ?

Non, ce n’est pas le cas. Il n’y a pas beaucoup de différence entre les instances (thèmes / plugins / configuration similaires), à l’exception d’une instance qui est pas mal plus ancienne que l’autre.

Enfin, espérons que ce ne soit que théorique.

1 « J'aime »

Est-ce que cela a été implémenté du tout ?

Mon certificat LetsEncrypt a expiré hier sans renouvellement automatique. Je ne sais pas si cela a quelque chose à voir avec les changements suggérés à app.yml que j’ai faits selon ce fil de discussion ci-dessus, ou avec les mises à jour ultérieures de Discourse.

Avec l’aide de l’IA (oui, je sais !) j’ai maintenant réussi à le faire renouveler, après avoir suivi l’IA dans un certain nombre de chemins de traverse impliquant l’utilisation de ngix et certbot (ce qui a fini par fonctionner en toute équité), avant d’annuler ces changements et de revenir à la méthode par défaut gérée par Discourse. Dans le processus, j’ai dû reconstruire quelques fois, donc je ne sais pas si c’est ce qui a déclenché le renouvellement.

Désolé pour le dérangement - je suis curieux, quand a eu lieu votre dernière reconstruction avant celle-ci ?

Nous venons de vérifier et de tester à nouveau le processus de renouvellement, mais nous ne parvenons pas à le reproduire - nos tests renouvellent correctement, donc soit quelque chose ne se passe pas de notre côté, soit il y a une différence dans la manière dont le renouvellement de staging par rapport à la production de Let’s Encrypt fonctionne.

Je peux également confirmer que la reconstruction de votre site force le processus de renouvellement à avoir lieu, si tout le reste échoue.

Nous utilisons acme.sh en interne (dans /opt/acme.sh dans le conteneur) - si vous êtes intéressé, vous pouvez entrer dans le conteneur docker en cours d’exécution et exécuter le script pour inspecter/renouveler par ce biais également.

1 « J'aime »