Bootsnap::CompileCache::PermissionError

Hallo zusammen. Ich habe eine frische Installation von Discourse in Docker.
Das Problem ist, dass der Container nach einem Neustart zwar hochfährt und ich auf die App-Seite zugreifen kann, jedoch eine 502-Fehlermeldung erhalte. In den Logs oder wenn ich versuche, z. B. rails c (innerhalb des Containers) auszuführen, sehe ich nur diesen Fehler:
`permission_error’: bootsnap hat keine Berechtigung, Cache-Einträge in ‘tmp/cache/bootsnap/compile-cache’ zu schreiben (oder, weniger wahrscheinlich, keine Berechtigung, ‘/usr/local/lib/ruby/2.7.0/set.rb’ zu lesen) (Bootsnap::CompileCache::PermissionError)

Um dies zu beheben, muss ich im Container manuell chown -R discourse:discourse /var/www/discourse/tmp (genauer gesagt: das Verzeichnis /var/www/discourse/tmp/cache/bootsnap) ausführen. Direkt danach funktioniert die App einwandfrei, sogar ohne Neustart. Es ist jedoch sehr mühsam, dies nach jedem Neustart manuell durchzuführen.

Ich habe überlegt, dies über den Abschnitt für benutzerdefinierte Befehle in der app.yml-Datei mit dem oben genannten Befehl chown -R discourse:discourse /var/www/discourse/tmp zu lösen, aber leider funktioniert das nicht. Die Befehle scheinen zwar ausgeführt zu werden (ich habe es mit mkdir getestet), aber die Dateiberechtigungen werden nicht geändert.

Was könnte hier das Problem sein und wie lässt es sich lösen? Gibt es vielleicht eine Möglichkeit, die Dateiberechtigungen korrekt zu ändern?

Das ist seltsam. Haben Sie die offizielle Standardinstallation von Discourse befolgt?

Natürlich. Es wurden keine weiteren Schritte unternommen.

Kannst du deine container.yml-Datei (ohne Passwörter) einfügen?

Klar. Hier ist es:

## Dies ist die All-in-One, eigenständige Discourse Docker-Container-Vorlage
##
## Nach Änderungen an dieser Datei MÜSSEN Sie neu aufbauen
## /var/discourse/launcher rebuild app
##
## SEIEN SIE *SEHR* VORSICHTIG BEIM BEARBEITEN!
## YAML-DATEIEN SIND ÄUSSERST EMPFINDLICH GEGENÜBER FEHLERN IN 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"

## Welche TCP/IP-Ports soll dieser Container offenlegen?
## 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 gesamten Speichers.
  ## wird automatisch vom Bootstrap basierend auf dem erkannten RAM gesetzt, oder Sie können es überschreiben
  #db_shared_buffers: "256MB"

  ## 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:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

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

  ## TODO: Der Domainname, auf den diese Discourse-Instanz reagiert
  ## Erforderlich. Discourse funktioniert nicht mit einer bloßen IP-Nummer.
  DISCOURSE_HOSTNAME: 'example.com'

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

  ## TODO: Liste der durch Komma getrennten E-Mail-Adressen, die bei der ersten Anmeldung zu Administratoren und Entwicklern werden
  ## Beispiel 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'test@mail.com'

  ## TODO: Der SMTP-Mailserver, der zur Validierung neuer Konten und zum Senden von Benachrichtigungen verwendet wird
  # SMTP-Adresse, Benutzername und Passwort sind erforderlich
  # WARNUNG: Das Zeichen '#' im SMTP-Passwort kann Probleme verursachen!
  DISCOURSE_SMTP_ADDRESS: smtp.mail.io
  #DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: 111
  DISCOURSE_SMTP_PASSWORD: 111
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, Standard: true)
  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (von einigen Anbietern erforderlich)
  #DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com    # (Adresse, von der Benachrichtigungen gesendet werden)

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

  ## 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 Maxmind-Geolokalisierungs-IP-Adresse-Schlüssel für die IP-Adressen-Suche
  ## siehe https://meta.discourse.org/t/-/137387/23 für Details
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## 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 hin
## 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

## 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 dies aus und ändern Sie:
  ## Nach Erhalt der ersten Anmelde-E-Mail kommentieren Sie die Zeile erneut aus. Sie muss nur einmal ausgeführt werden.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  #- exec: chown -R discourse:discourse /var/www/discourse/tmp/cache/bootsnap  # Beispielbefehl, wie ich versucht habe, Dateiberechtigungen zu reparieren
  - exec: echo "Ende der benutzerdefinierten Befehle"

Du hast discourse-setup nicht ausgeführt, oder? Es sollte einige Dinge definiert haben, die du auskommentiert hast. Ich habe diese Änderungen gerade vorgenommen und möchte sicherstellen, dass alles wie erwartet funktioniert.

Gibt es einen Grund, warum du Let’s Encrypt nicht verwendest?

Ich sehe jedoch keine Erklärung für dein Problem.

Zunächst wurde die Anwendung mit discourse-setup erstellt. Nach mehreren Versuchen, sie neu zu erstellen, ohne ein positives Ergebnis zu erzielen, wechselte ich zu einer der vordefinierten .yml-Konfigurationen aus dem Verzeichnis /samples und bearbeitete sie anschließend einfach mit meinen Zugangsdaten.
Warum nicht Let’s Encrypt? Es wurde verlangt, die Zertifikate des Kunden zu verwenden. Soweit ich verstehe, haben die Zertifikate jedoch nichts damit zu tun, da sie gültig sind und keine Probleme verursachen.
Das Problem scheint auf Projektebene zu liegen und betrifft speziell die Berechtigungen der Bootsnap-Cache-Datei (möglicherweise liegt das Problem auf der Seite von Bootsnap).

Danke. Ich stimme zu, dass dies wahrscheinlich nicht das Problem ist. Ich habe gestern ein paar Installationen durchgeführt, die problemlos funktioniert haben. Ich sehe keine Erklärung für dein Problem.

Wir hatten das gleiche Problem, und ich kann bestätigen, dass die Ausführung (innerhalb des Docker-Containers):

chown -R discourse:discourse /var/www/discourse/tmp

Das Problem behoben hat! Es waren keine Neustarts erforderlich. Vor der Besitzeränderung waren die Berechtigungen des Verzeichnisses ‘tmp’ auf ‘discourse:www-data’ festgelegt. Hoffentlich kann dies in Zukunft so behoben werden, dass nach jedem Neuaufbau keine manuelle Aktion mehr erforderlich ist.

Führen Sie den Launcher als root aus?

Ja @pfaffman, das bin ich. Ist das das Problem?

Das glaube ich nicht. Ich starte meine selbst gehosteten Instanzen immer als root und habe noch nie ein solches Problem gesehen.

Wer ist der Besitzer des Verzeichnisses, wenn du chown nicht verwendest? In einem kürzlich neu aufgebauten Container sieht es so aus:

# ls -l /var/www/discourse/tmp
total 36
lrwxrwxrwx 1 root      root         19 Mar  2 14:56 backups -> /shared/tmp/backups
drwxr-xr-x 1 discourse discourse  4096 Mar  2 14:57 cache
drwxr-xr-x 1 discourse discourse  4096 Mar  2 14:57 ember-rails
drwxr-xr-x 1 discourse root       4096 Mar  2 15:04 pids
lrwxrwxrwx 1 root      root         20 Mar  2 14:56 restores -> /shared/tmp/restores
drwxr-xr-x 2 discourse root       4096 Mar  2 14:56 sockets
drwxr-xr-x 2 discourse discourse 12288 Mar  2 15:02 stylesheet-cache

Hast du deinem app.yml neben dem Klonen von Plugins weitere benutzerdefinierte Befehle oder Hooks hinzugefügt?

Der Eigentümer-Benutzer und die Gruppe des Verzeichnisses /var/www/discourse/tmp waren nach dem Start des Containers discourse:www-data. Die Neuzuweisung zu discourse:discourse hat das Problem behoben. Das ist mir bisher noch nie passiert, obwohl ich Discourse bereits seit mehreren Monaten nutze. Wie auch immer, es war eine einfache Lösung und könnte zufällig gewesen sein, also möchte ich dich nicht weiter damit belästigen. Vielen Dank @gerhard!