Bootstrap-Fehler bei Discourse-Installation: ENOENT - /etc/runit/1.d/letsencrypt

Hallo, ich versuche, Discourse mit dem Standardprozess ./discourse-setup zu installieren, stoße aber während des Bootstrap-Vorgangs auf einen Fehler:

FAILED
--------------------
Errno::ENOENT: No such file or directory @ rb_sysopen - /etc/runit/1.d/letsencrypt
Ort des Fehlers: /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 ** bitte scrollen Sie nach oben und suchen Sie nach früheren Fehlermeldungen, es kann mehr als eine geben.

Es sieht so aus, als ob der Fehler durch ein Plugin ausgelöst wird, das versucht, einen replace-Befehl für die Datei /etc/runit/1.d/letsencrypt auszuführen, die während des Bootstrap-Vorgangs nicht im Container vorhanden ist. Die relevante Zeile im Plugin sieht so aus:

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

Haben Sie Ratschläge, wie ich das beheben oder die fehlende Datei ordnungsgemäß neu generieren kann?

Vielen Dank im Voraus.

Ein Plugin? Das ist cups-Code aus deiner app.yml, richtig? Versucht du, ein weiteres Zertifikat hinzuzufügen? Wie in Set up Let’s Encrypt with multiple domains / redirects Kannst du den tatsächlichen Code und beide Zertifikate einfügen?

Wie du richtig bemerkst, existiert dieses runit nicht mehr, und diese Magie steckt jetzt in /usr/local/bin/letsencrypt (innerhalb des Containers)

Ich denke, vielleicht möchtest du etwas Ähnliches wie das hier, wenn deine Seite www.mysite.org ist und du auch ein Zertifikat für forum.mysite.org haben möchtest:

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

Was ich tun würde (was dir vielleicht nicht hilft) ist, in den Container zu gehen, apt update;apt install -y vim auszuführen und dann /usr/local/bin/letsencrypt zu bearbeiten, sodass es die gewünschten Zertifikate anfordert.

Ich habe dem oben verlinkten Let’s Encrypt-Thema Code hinzugefügt, der es dir ermöglichen sollte, deine Domain einzugeben und Code zu erhalten, den du in deine app.yml kopieren/einfügen kannst.

1 „Gefällt mir“

Ich bin auf eine Fehlermeldung gestoßen, die bei einem Updateversuch ähnlich aussieht.

Ich versuche nicht, etwas im Zusammenhang mit Zertifikaten zu ändern.

Meine app.yml-Datei zeigt derzeit Folgendes an:

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

Ich habe Ihren Vorschlag befolgt:

 apt update;apt install -y vim

aber das Ergebnis war: „vim ist bereits in der neuesten Version (2:9.1.0016-1ubuntu7.8).“

Was den zweiten vorgeschlagenen Schritt betrifft, habe ich keine Ahnung, welche Zertifikate ich möchte, da ich keine Absicht hatte, etwas zu ändern.

OK, nach ein paar Stunden des Hin und Her habe ich es wieder zum Laufen gebracht.

Ich habe eine alte app.yml-Datei gefunden und diese ersetzt, indem ich einfach die alten Verweise auf Plugins gelöscht habe, die inzwischen in Discourse integriert wurden.

Diese ältere app.yml-Datei enthielt nicht den unten stehenden Code, den ich in einer späteren gefunden habe.

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

Ich erinnere mich nicht, diesen Code selbst dort eingefügt zu haben, obwohl ich meine Website so eingerichtet hatte, dass sie Letsencrypt für die kostenlosen Sicherheitszertifikate verwendet. Die Anweisungen unter Set up HTTPS support with Let's Encrypt scheinen diese Zeilen überhaupt nicht zu erfordern, daher habe ich keine Ahnung, wofür sie gewesen wären.

Könnte etwas anderes diese Zeilen potenziell zu app.yml hinzugefügt haben? Z. B. könnten sie während eines Beta-Updates hinzugefügt worden sein?

Zumindest vorerst, da diese Zeilen entfernt wurden, funktioniert meine Website wieder und ist auf dem neuesten Stand.

Wenn mein aktuelles SSL-Zertifikat abläuft, werde ich vielleicht herausfinden, wofür diese zusätzlichen Zeilen waren.

Nun, ja, das tust du, aber du erinnerst dich nicht. :wink:

Wenn du diese after_ssl-Anweisung in deiner yml-Datei hast, dann hast du irgendwann die Dinge so eingerichtet, dass, wenn jemand www vor deine Domain setzt, diese zur www-Adresse geht und ohne Zertifikatsfehler zur Nicht-www-Adresse weitergeleitet wird.

Mein Vorschlag war, vim in den Container zu installieren und die Dateien dort zu bearbeiten, aber ich denke, mein Code, der zu app.yml hinzugefügt werden soll, sollte funktionieren.

Richtig. Und jetzt, wenn du https://www.nzarchitecture.net.nz/ besuchst, erhältst du einen Zertifikatsfehler. Du könntest https://forcewww.com/ verwenden.

Du könntest den obigen Link aufrufen und den neuen Code erhalten, von dem ich denke, dass er funktionieren sollte, den ich aber noch nicht getestet habe, da ich keine Website gefunden habe, die ich aktualisiere und die ihn benötigt.

Habe ich Recht, dass Ihr Code in etwa den folgenden Zeilen entsprechen würde, wenn ich möchte, dass www.nzarchitecture.net.nz vom selben letsencrypt-Zertifikat wie nzarchitecture.net.nz abgedeckt wird?

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

Ich habe versucht, diese Klausel (tolle Terminologie, danke!) am Ende von app.yml einzufügen, anstelle der ursprünglichen ‘after_ssl:’-Klausel, und kann jetzt Discourse ohne Fehler neu erstellen - aber das scheint mir nicht zu helfen; mein Browser wirft immer noch eine ‘net::ERR_CERT_COMMON_NAME_INVALID’-Antwort aus, wenn ich versuche, ein ‘www’-Präfix vor meiner Haupt-/zertifizierten Domain nzarchitecture.net.nz zu verwenden.

Meine vollständige app.yml unten, falls sie überhaupt hilft (Passwort und E-Mail-Adressen geschwärzt)

## Dies ist die All-in-One-, Standalone-Discourse-Docker-Container-Vorlage
##
## Nach Änderungen an dieser Datei MÜSSEN Sie neu erstellen
## /var/discourse/launcher rebuild app
##
## SEIEN SIE *SEHR* VORSICHTIG BEIM BEARBEITEN!
## YAML-DATEIEN SIND SUPER SUPER EMPFINDLICH GEGENÜBER FEHLERN BEI LEERZEICHEN ODER AUSRICHTUNG!
## Besuchen Sie http://www.yamllint.com/, um diese Datei bei Bedarf zu validieren.

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Kommentieren Sie diese beiden Zeilen aus, wenn Sie Lets Encrypt (https) hinzufügen möchten.
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/import/mysql-dep.template.yml"

## Welche TCP/IP-Ports soll dieser Container verfügbar machen?
## Wenn Sie möchten, dass Discourse einen Port mit einem anderen Webserver wie Apache oder nginx teilt,
## siehe https://meta.discourse.org/t/17247 für Details
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Setzen Sie db_shared_buffers auf maximal 25 % des Gesamtspeichers.
  ## wird automatisch vom Bootstrap basierend auf dem erkannten RAM gesetzt, oder Sie können ihn überschreiben
  db_shared_buffers: "128MB"

  ## kann die Sortierleistung verbessern, erhöht aber den Speicherverbrauch pro Verbindung
  #db_work_mem: "40MB"

  ## Welche Git-Revision soll dieser Container verwenden? (Standard: tests-passed)
  #version: tests-passed

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

  ## Wie viele gleichzeitige Webanfragen werden unterstützt? Hängt von Speicher und CPU-Kernen ab.
  ## wird automatisch vom Bootstrap basierend auf den erkannten CPUs gesetzt, oder Sie können ihn überschreiben
  UNICORN_WORKERS: 2

  ## TODO: Der Domainname, auf den diese Discourse-Instanz reagieren wird
  ## Erforderlich. Discourse funktioniert nicht mit einer reinen IP-Nummer.
  DISCOURSE_HOSTNAME: nzarchitecture.net.nz

  ## Kommentieren Sie dies aus, wenn der Container mit demselben
  ## Hostnamen (-h Option) wie oben angegeben gestartet werden soll (Standard "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Liste der durch Kommas getrennten E-Mails, die bei der ersten Anmeldung Administrator und Entwickler werden
  ## Beispiel 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: '****************'

  ## TODO: Der SMTP-Mailserver, der zum Überprüfen neuer Konten und zum Senden von Benachrichtigungen verwendet wird
  # SMTP-ADRESSE, Benutzername und Passwort sind erforderlich
  # ACHTUNG: das Zeichen '#' im SMTP-Passwort kann Probleme verursachen!
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: ****************
  DISCOURSE_SMTP_PASSWORD: "****************"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, Standard true)

  ## Wenn Sie die Lets Encrypt-Vorlage hinzugefügt haben, kommentieren Sie unten aus, um ein kostenloses SSL-Zertifikat zu erhalten
  LETSENCRYPT_ACCOUNT_EMAIL: ******************

  ## Die http- oder https-CDN-Adresse für diese Discourse-Instanz (konfiguriert zum Abrufen)
  ## siehe https://meta.discourse.org/t/14857 für Details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## Der Docker-Container ist zustandslos; alle Daten werden in /shared gespeichert
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins gehen hier
## siehe https://meta.discourse.org/t/19157 für Details
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
## Alle benutzerdefinierten Befehle, die nach dem Erstellen ausgeführt werden sollen
run:
  - exec: echo "Beginn der benutzerdefinierten Befehle"
  ## Wenn Sie die 'Von'-E-Mail-Adresse für Ihre erste Registrierung festlegen möchten, kommentieren Sie sie aus und ändern Sie sie:
  ## Nachdem Sie die erste Registrierungs-E-Mail erhalten haben, kommentieren Sie die Zeile wieder aus. Sie muss nur einmal ausgeführt werden.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Ende der benutzerdefinierten Befehle"

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

Ist die Tatsache, dass sich keine Dateien in /usr/local/bin/ befinden, Teil des Problems?

Wo finde ich die richtige letsencrypt-Datei, um sie dort abzulegen, falls das nötig ist?

Und wenn ‘letsencrypt’ der Dateiname am Ende dieses Pfades ist, ist es normal, dass keine Dateierweiterung Teil dieses Dateinamens ist?

Meine Idee ist, die after_ssl-Zeile zu entfernen und die anderen einzurücken.

Wenn Sie meinen SSH-Schlüssel mit

ssh-import-id-gh pfaffman

hinzufügen und mir eine E-Mail senden, werde ich sehen, was ich tun kann.

Danke! @pfaffman

Habe dir gerade eine E-Mail geschickt

Hier ist ein Update.

Wenn Sie dies zum run-Abschnitt am Ende Ihrer app.yml hinzufügen, wird das Problem behoben, dass /usr/local/bin/letsencrypt Zertifikate für DISCOURSE_HOSTNAME und www.DISCOURSE_HOSTNAME anfordert.

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

Dies war (irgendwie?) früher ausreichend, aber jetzt, wenn die Anfrage für http://www.HOSTNAME/.well-known… eingeht, wird sie zur Nicht-www-Seite umgeleitet, anstatt die Herausforderung zu senden, die sie senden soll. Ich habe versucht, so etwas zu tun:

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

  # ACME-Herausforderung bedienen (Let's Encrypt)
  location ^~ /.well-known/acme-challenge/ {
    root /var/www/discourse/public;  # Stellen Sie sicher, dass dies mit Ihrem Let's Encrypt Webroot übereinstimmt
    allow all;
  }

  # Alles andere zu HTTPS umleiten
  location / {
    return 301 https://$host$request_uri;
  }
}

aber es nicht ganz herausgefunden.

Wenn jemand vom Team zuhört, wäre es gut, wenn es einen Letsencrypt-Hook gäbe, damit dies in einem after_letsencrypt aufgerufen werden könnte. Bevor diese Änderungen in after_ssl vorgenommen wurden, funktionierte es, aber jetzt scheint es, dass dies nach SSL ausgeführt wird, aber vor Letsencrypt.

3 „Gefällt mir“

Ich sehe dieses Problem auch. Ich werde Sie wissen lassen, wenn ich es beheben kann.

Mein DISCOURSE_HOSTNAME ist www.textkit.com. Ich mache das Gegenteil von nzarchitecture.net.nz und füge meinem Zertifikat einen Hostnamen ohne www hinzu. Das hat bei mir funktioniert:

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

Ich kann nicht sagen, warum @pfaffman und nzarchitecture.net.nz Probleme mit seiner Version haben könnten, obwohl die Reihenfolge der Hostnamen in meiner vielleicht damit zusammenhängt.

Ich bin auch auf dieses Problem gestoßen.

Ich habe Folgendes entfernt (indem ich es auskommentiert habe):

  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;

und habe dies am Ende im Abschnitt „run“ gemäß @pfaffman hinzugefügt:

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

Das scheint für mich ausreichend gewesen zu sein:

  • Die Website wurde neu erstellt und hat anscheinend gültige Zertifikate.
  • Die Umleitung von Apex zu www funktioniert.

Danke @pfaffman!

4 „Gefällt mir“

Oh! Cool. Vielleicht hat die Änderung, die sie vorgenommen haben, um die Zertifikatserneuerung zu ermöglichen, auch das Problem gelöst, mit dem ich konfrontiert war.

Ich werde das im Hinterkopf behalten, wenn ich auf andere Websites stoße, die dies benötigen, bevor der PR akzeptiert wird.

1 „Gefällt mir“

Hier gibt es ein paar bewegliche Teile. Es hat bei mir bei diesem Wiederaufbau funktioniert, ich werde hier berichten, wenn sich die Situation ändert!

1 „Gefällt mir“

Der PR zur Genehmigung von Zertifikatsverlängerungen wurde noch nicht zusammengeführt – dieser Teil steht noch aus.

Sobald er jedoch zusammengeführt ist, sollte dies eine deutlich vereinfachte app.yml ermöglichen.

2 „Gefällt mir“

Seltsamerweise funktioniert dieser Codeausschnitt auf einer meiner Websites, aber der alte Code (und nur der alte Code) funktioniert auf meiner anderen Website. :person_shrugging:

Nun, hoffentlich ist das bald sowieso alles gegenstandslos!

1 „Gefällt mir“

Das ist sehr seltsam. Ist discourse_docker an eine alte Version angepinnt?

Nein, ist es nicht. Es gibt keine großen Unterschiede zwischen den Instanzen (ähnliche Themen / Plugins / Konfigurationen), außer dass eine Instanz deutlich älter ist als die andere.

Nun, hoffentlich ist das nur akademisch.

1 „Gefällt mir“

Wurde dies überhaupt umgesetzt?

Mein LetsEncrypt-Zertifikat ist gestern ohne automatische Verlängerung abgelaufen. Ich bin mir nicht sicher, ob dies mit den von mir vorgeschlagenen Änderungen an der app.yml in diesem Thread oder mit nachfolgenden Updates von Discourse zusammenhängt.

Mithilfe von KI-Unterstützung (ja, ich weiß!) ist es mir inzwischen gelungen, es zur Verlängerung zu bringen, nachdem ich der KI in eine Reihe von Sackgassen gefolgt war, die die Verwendung von ngix und certbot beinhalteten (was am Ende tatsächlich funktionierte), bevor ich diese Änderungen rückgängig machte und zur Standardmethode zurückkehrte, die von Discourse verwaltet wird. Dabei musste ich ein paar Mal neu erstellen, bin mir also nicht sicher, ob das der Auslöser für die Verlängerung war.

Entschuldigung für die Umstände – ich bin neugierig, wann Sie das letzte Mal vor diesem Vorfall ein Rebuild durchgeführt haben?

Wir haben den Erneuerungsprozess gerade noch einmal überprüft und getestet, können ihn aber nicht reproduzieren – unsere Tests erneuern sich ordnungsgemäß, daher passiert entweder auf unserer Seite etwas nicht, oder es gibt einen Unterschied in der Funktionsweise der Erneuerung zwischen der Staging- und der Produktionsumgebung von Let’s Encrypt.

Ich kann auch bestätigen, dass das Rebuild Ihrer Website den Erneuerungsprozess erzwingt, falls alles andere fehlschlägt.

Wir verwenden acme.sh intern (in /opt/acme.sh im Container) – wenn Sie Lust haben, können Sie in den laufenden Docker-Container wechseln und das Skript von dort aus zur Inspektion/Erneuerung ausführen.

1 „Gefällt mir“