Errore Bootstrap durante l'installazione di Discourse: ENOENT - /etc/runit/1.d/letsencrypt

Ciao, sto cercando di installare Discourse utilizzando il processo standard ./discourse-setup, ma sto riscontrando un errore durante il bootstrap:

FAILED
--------------------
Errno::ENOENT: Nessun file o directory di questo tipo @ rb_sysopen - /etc/runit/1.d/letsencrypt
Posizione del fallimento: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/replace_command.rb:11:in `read'
sostituzione fallita con i parametri {\"filename\"=>\"/etc/runit/1.d/letsencrypt\", \"from\"=>\"/--keylength/\", \"to\"=>\"-d forum.mysite.org --keylength\"}
bootstrap fallito con codice di uscita 1
** IMPOSSIBILE EFFETTUARE IL BOOTSTRAP ** si prega di scorrere verso l'alto e cercare messaggi di errore precedenti, potrebbero essercene più di uno.

Sembra che l’errore sia attivato da un plugin che tenta di eseguire un comando replace sul file /etc/runit/1.d/letsencrypt, che non esiste all’interno del container durante il bootstrap. La riga pertinente nel plugin è la seguente:

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

Qualsiasi consiglio su come risolvere questo problema o rigenerare correttamente il file mancante?

Grazie in anticipo.

Un plugin? Quello è codice cups dal tuo app.yml, giusto? Stai cercando di aggiungere un altro certificato? Come in Set up Let’s Encrypt with multiple domains / redirects Puoi includere il codice effettivo e entrambi i certificati?

Come fai notare, quel runit non esiste più, e ora quella magia è in /usr/local/bin/letsencrypt (all’interno del container)

Penso che potresti volere qualcosa di simile se il tuo sito è www.mysite.org e vuoi anche che abbia un certificato per 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

Quello che farei (il che potrebbe non esserti d’aiuto) è entrare nel container, apt update;apt install -y vim e poi modificare /usr/local/bin/letsencrypt in modo che richieda i certificati che desideri.

Ho aggiunto del codice all’argomento lets encrypt collegato sopra che dovrebbe permetterti di inserire il tuo dominio e ottenere il codice che puoi copiare/incollare nel tuo app.yml.

1 Mi Piace

Ho riscontrato quello che sembra essere lo stesso messaggio di errore durante un tentativo di aggiornamento.

Non sto cercando di cambiare nulla relativo ai certificati.

Il mio file app.yml mostra attualmente questo

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

Ho seguito il tuo suggerimento

 apt update;apt install -y vim

ma il risultato è stato ‘vim è già alla versione più recente (2:9.1.0016-1ubuntu7.8).’

Per quanto riguarda il secondo passaggio suggerito, non ho idea di quali certificati desideri, non avendo avuto intenzione di cambiare nulla.

OK, dopo qualche ora di tentativi, sono riuscito a rimettere tutto in funzione.

Ho trovato un vecchio file app.yml e l’ho sostituito, eliminando semplicemente i vecchi riferimenti a plugin che nel frattempo sono stati incorporati in Discourse.

Questo file app.yml più vecchio non conteneva il codice sottostante, che ho trovato in uno più recente.

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

Non ricordo di aver inserito io stesso quel codice, anche se avevo configurato il mio sito per utilizzare letsencrypt per i certificati di sicurezza gratuiti, ma le istruzioni su Set up HTTPS support with Let's Encrypt non sembrano richiedere affatto quelle righe, quindi non ho idea a cosa sarebbero servite.

Potrebbe esserci qualcos’altro che ha potenzialmente inserito quelle righe in app.yml? Ad esempio, potrebbero essere state aggiunte durante un aggiornamento beta?

Almeno per ora, con quelle righe rimosse, il mio sito funziona di nuovo ed è aggiornato.

Quando scadrà il mio attuale certificato ssl, immagino che scoprirò a cosa servivano quelle righe extra.

Beh, sì, lo stai facendo, ma non te lo ricordi. :wink:

Se hai quella direttiva after_ssl nel tuo file yml, allora a un certo punto hai configurato le cose in modo tale che se qualcuno mettesse www davanti al tuo dominio, questo andrebbe all’indirizzo www e verrebbe reindirizzato all’indirizzo non-www senza un errore di certificato.

Il mio suggerimento era di installare vim all’interno del container e provare a modificare i file lì, ma penso che il mio codice da aggiungere ad app.yml dovrebbe funzionare.

Giusto. E ora, se visiti https://www.nzarchitecture.net.nz/, ottieni un errore di certificato. Potresti usare https://forcewww.com/

Potresti andare al link sopra e ottenere il nuovo codice che penso dovrebbe funzionare, ma non l’ho testato poiché non ho trovato un sito che sto aggiornando che ne abbia bisogno.

Corretto nel pensare che il mio codice dovrebbe essere simile a quanto segue, se voglio che www.nzarchitecture.net.nz sia coperto dallo stesso certificato letsencrypt di 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

Ho provato ad aggiungere questa sezione (ottima terminologia, grazie!) alla fine di app.yml, al posto della sezione originale ‘after_ssl:’, e ora posso ricostruire Discourse senza errori - ma questo non sembra aiutarmi; il mio browser restituisce ancora una risposta ‘net::ERR_CERT_COMMON_NAME_INVALID’ se provo a usare un prefisso ‘www’ prima del mio dominio principale/certificato nzarchitecture.net.nz

Il mio app.yml completo qui sotto, nel caso possa essere d’aiuto (password e indirizzi email oscurati)

## questo è il template del container Docker Discourse standalone all-in-one
##
## Dopo aver apportato modifiche a questo file, DEVI ricostruire
## /var/discourse/launcher rebuild app
##
## FAI *MOLTA* ATTENZIONE QUANDO EDITI!
## I FILE YAML SONO SUPER SUPER SENSIBILI A ERRORI DI SPAZIATURA O ALLINEAMENTO!
## visita http://www.yamllint.com/ per validare questo file se necessario

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Decommenta queste due righe se desideri aggiungere Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/import/mysql-dep.template.yml"

## quali porte TCP/IP deve esporre questo container?
## Se vuoi che Discourse condivida una porta con un altro webserver come Apache o nginx,
## vedi https://meta.discourse.org/t/17247 per i dettagli
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Imposta db_shared_buffers al massimo del 25% della memoria totale.
  ## verrà impostato automaticamente da bootstrap in base alla RAM rilevata, o puoi sovrascriverlo
  db_shared_buffers: "128MB"

  ## può migliorare le prestazioni di ordinamento, ma aggiunge utilizzo di memoria per connessione
  #db_work_mem: "40MB"

  ## Quale revisione Git dovrebbe usare questo container? (default: tests-passed)
  #version: tests-passed

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

  ## Quante richieste web concorrenti sono supportate? Dipende da memoria e core CPU.
  ## verrà impostato automaticamente da bootstrap in base alle CPU rilevate, o puoi sovrascriverlo
  UNICORN_WORKERS: 2

  ## TODO: Il nome di dominio a cui risponderà questa istanza Discourse
  ## Obbligatorio. Discourse non funzionerà con un semplice numero IP.
  DISCOURSE_HOSTNAME: nzarchitecture.net.nz

  ## Decommenta se vuoi che il container venga avviato con lo stesso
  ## hostname (-h opzione) specificato sopra (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Elenco di email separate da virgola che diventeranno admin e sviluppatore
  ## alla prima registrazione esempio 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: '****************'

  ## TODO: Il server di posta SMTP utilizzato per convalidare nuovi account e inviare notifiche
  # INDIRIZZO SMTP, nome utente e password sono obbligatori
  # ATTENZIONE il carattere '#' nella password SMTP può causare problemi!
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: ****************
  DISCOURSE_SMTP_PASSWORD: "****************"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (opzionale, default true)

  ## Se hai aggiunto il template Lets Encrypt, decommenta qui sotto per ottenere un certificato SSL gratuito
  LETSENCRYPT_ACCOUNT_EMAIL: ******************

  ## L'indirizzo CDN http o https per questa istanza Discourse (configurato per il pull)
  ## vedi https://meta.discourse.org/t/14857 per i dettagli
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## Il container Docker è stateless; tutti i dati sono memorizzati in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## I plugin vanno qui
## vedi https://meta.discourse.org/t/19157 per i dettagli
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
## Qualsiasi comando personalizzato da eseguire dopo la build
run:
  - exec: echo "Inizio comandi personalizzati"
  ## Se vuoi impostare l'indirizzo email 'Da' per la tua prima registrazione, decommenta e cambia:
  ## Dopo aver ricevuto la prima email di registrazione, ri-commenta la riga. Deve essere eseguita solo una volta.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Fine comandi personalizzati"

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

Il fatto che non ci siano file in /usr/local/bin/ è parte del problema?

Dove trovo il file letsencrypt corretto da mettere lì, se è quello che serve?

E, se ‘letsencrypt’ è il nome del file alla fine di quel percorso, è normale che non ci sia un’estensione di file come parte di questo nome?

La mia idea è di rimuovere la riga after_ssl e di spostare le altre a sinistra.

Se aggiungerai la mia chiave ssh con

ssh-import-id-gh pfaffman

e mi invierai un’email, vedrò cosa posso fare.

Grazie! @pfaffman

Ti ho appena inviato un’email.

Ecco un aggiornamento.

Aggiungere questo alla sezione run in fondo al tuo app.yml risolverà il problema di ottenere /usr/local/bin/letsencrypt per richiedere certificati per DISCOURSE_HOSTNAME e www.DISCOURSE_HOSTNAME.

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

Questo (in qualche modo?) era sufficiente, ma ora quando arriva la richiesta per http://www.HOSTNAME/.well-known… viene reindirizzata al sito non www anziché inviare la sfida che dovrebbe inviare. Ho provato a fare qualcosa del genere:

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

  # Serve ACME challenge (Let's Encrypt)
  location ^~ /.well-known/acme-challenge/ {
    root /var/www/discourse/public;  # Assicurati che corrisponda alla tua webroot Let's Encrypt
    allow all;
  }

  # Reindirizza tutto il resto a HTTPS
  location / {
    return 301 https://$host$request_uri;
  }
}

ma non ho capito bene.

Se qualcuno del team sta ascoltando, sarebbe utile se ci fosse un hook letsencrypt in modo che questo possa essere chiamato in un after_letsencrypt. Prima di apportare queste modifiche in after_ssl funzionava, ma sembra che ora se lo facciamo questo viene eseguito dopo ssl, ma prima di letsencrypt.

3 Mi Piace

Sto riscontrando questo problema anch’io. Ti farò sapere se riesco a risolverlo.

Il mio DISCOURSE_HOSTNAME è www.textkit.com. Sto facendo l’opposto di nzarchitecture.net.nz e aggiungendo un hostname senza www al mio certificato. Questo ha funzionato per me:

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

Non posso dire perché @pfaffman e nzarchitecture.net.nz avrebbero problemi con la sua versione, anche se forse l’ordinamento degli hostname nel mio è correlato.

Ho anche riscontrato questo problema.

Ho rimosso questo (commentandolo):

  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;

e aggiunto questo nella sezione run in fondo come indicato da @pfaffman

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

Questo sembra essere stato sufficiente per me:

  • il sito è stato ricostruito e apparentemente ha certificati validi
  • il reindirizzamento dall’apex a www funziona

Grazie @pfaffman!

4 Mi Piace

Oh! Fantastico. Forse la modifica che hanno apportato per consentire il rinnovo dei certificati ha risolto anche il problema che stavo riscontrando.

Lo terrò a mente se dovessi imbattermi in altri siti che necessitano di questo prima che la PR venga accettata.

1 Mi Piace

Ci sono alcune parti in movimento qui. Ha funzionato per me in quella ricostruzione, tornerò qui se la situazione dovesse cambiare!

1 Mi Piace

La PR per consentire il rinnovo dei certificati non è ancora stata unita: quella parte è ancora in sospeso.

Una volta unita, tuttavia, dovrebbe consentire un app.yml molto più semplificato.

2 Mi Piace

Stranamente, quel pezzo di codice funziona su uno dei miei siti, ma il vecchio codice (e solo il vecchio codice) funziona sull’altro sito. :person_shrugging:

Beh, speriamo che presto tutto questo diventi irrilevante!

1 Mi Piace

È molto strano. discourse_docker è bloccato a una vecchia versione?

No, non lo è. Non c’è molta differenza tra le istanze (temi / plugin / configurazioni simili), tranne che un’istanza è piuttosto più vecchia dell’altra.

Beh, speriamo che sia solo accademico.

1 Mi Piace

Questo è stato implementato?

Il mio certificato LetsEncrypt è scaduto ieri senza rinnovo automatico. Non sono sicuro se questo abbia a che fare con le modifiche suggerite a app.yml che ho apportato in base a questa discussione sopra, o con i successivi aggiornamenti di Discourse.

Con l’assistenza dell’IA (sì, lo so!) sono riuscito a farlo rinnovare, dopo aver seguito l’IA in una serie di vicoli ciechi che coinvolgevano l’uso di ngix e certbot (che alla fine ha funzionato, a dire il vero), prima di annullare tali modifiche e tornare al metodo predefinito gestito da Discourse. Nel processo ho dovuto ricostruire un paio di volte, quindi non sono sicuro se sia stato questo a innescare il rinnovo.

Siamo spiacenti per il problema - sono curioso, quando è stata l’ultima volta che hai ricostruito prima di questo?

Abbiamo appena controllato e testato nuovamente il processo di rinnovo ma non siamo riusciti a riprodurre l’errore - i nostri test rinnovano correttamente, quindi o qualcosa non sta succedendo da parte nostra, oppure c’è qualcosa di diverso nel modo in cui funziona il rinnovo dello staging rispetto alla produzione di Let’s Encrypt.

Posso anche confermare che la ricostruzione del tuo sito forza l’avvio del processo di rinnovo, se tutto il resto fallisce.

Usiamo acme.sh sotto il cofano (in /opt/acme.sh nel container) - se sei incline puoi entrare nel container docker in esecuzione ed eseguire lo script per ispezionare/rinnovare anche da lì.

1 Mi Piace