Deploy Discourse senza Docker

Alcuni dettagli sulle mie soluzioni:

  1. Configurazione Nginx:
    Dietro un reverse proxy (haproxy), è necessario copiare /var/discourse/config/nginx-config-sample.conf in /etc/nginx/sites-enabled/discourse.conf o un percorso simile, quindi sostituire listen <yourreverseproxyport> (se necessario) e il _ di server_name con il tuo hostname (subdmain.example.com). Nient’altro deve essere modificato.
  2. Pagine non visualizzate (messaggio “Oops”) e registrazione admin via email non funzionante:
    Magick è stata la causa del mancato caricamento delle pagine dopo le pagine di registrazione admin al primo avvio. Ho seguito il file indicato nel log: /var/www/discourse/lib/letter_avatar.rb:112 alla riga 112, c’erano due comandi magick che effettivamente non rispondevano. convert rispondeva, quindi ho sostituito magick a questa riga con convert. Dopo queste correzioni, è stato registrato un altro errore. Provando la stessa procedura con il comando dato dal file, il comando magick non ha funzionato e convert stava fallendo. NB: magick --version era 7.x e convert --version dava 6.x. La causa è stata che ho installato prima imagemagick con apt, poi magick 7 da sorgente. C’erano alcuni conflitti e magick ha detto al comando convert di essere obsoleto. Quindi ho riavviato il mio script solo con magick 7. Questo ha risolto immediatamente il problema e ho potuto vedere le nuovissime pagine attese da giorni, e anche l’email ha funzionato! Magick è davvero magico.
  3. Rimane il problema del contenuto misto, ma il sito web funziona comunque bene.
    NB: in puma.rb, la riga bind ENV.fetch("PUMA_BIND", "tcp://#{ENV['PUMA_BIND_ALL'] ? '' : '127.0.0.1:'}3000") deve essere così (correzione del primo post.)
  4. EDIT “3.”, riguardo al forzamento https per discourse: Non so esattamente perché, ma i miei browser non mostrano più avvisi di ‘contenuto misto’ (forse a causa dell’aggiornamento della cache), quindi ora va tutto bene. Devo solo finire il mio script.
3 Mi Piace

Funziona!!!
ImageMagick v7 risolve il problema Ooops!
Per quanto ho testato, funziona perfettamente.
Testerò il resto delle funzionalità e vi farò rapporto al più presto.

1 Mi Piace

Quello che ho fatto per testare è stato impostare la variabile d’ambiente PUMA_BIND quando eseguivo puma.

Per quanto riguarda ImageMagick, per qualche motivo Discourse non riesce a eseguire una conversione di immagini nell’interfaccia web, quando carico un’immagine grande gentilmente rifiuta di convertirla… Sto ancora eseguendo il debug del problema.

Ci sono progressi nel debug? Da parte mia, sto lavorando su magick.
Su alcune immagini di circa 50ko, nel browser viene visualizzato un popup:
timeout -k 40.0 20 magick gif:/tmp/RackMultipart20250927-23598-xrrp6e.gif -auto-orient -background white -interlace none -flatten -debug all -quality 90 jpg:/tmp/image20250927-23598-9ujq3d.jpg e nessuna immagine viene caricata
Se la dimensione è maggiore, nessun popup ma la rotella di caricamento gira all’infinito senza alcun risultato. Nessun errore viene registrato in /var/www/discourse/log.

Stesso problema anche per me :joy::sob:

L’unico modo in cui sono riuscito a farlo funzionare è stato usando imagemagick dal repository di brew.

MA fallisce quando l’immagine è più di 3MB… forse ho impostato una configurazione di policy molto restrittiva.

Provalo!!!

Sto testando l’installazione di docker ma penso o che sia molto stupido distribuire nginx, unicorn, redis, postgresql e il resto in UN SOLO container… non ha alcun senso. E non c’è documentazione sull’infrastruttura per grandi distribuzioni… Lavoro nell’IT da più di 20 anni e vedo solo problemi arrivare nel prossimo futuro usando tale infrastruttura.

Senza parlare di “docker The Space Eater” (come Dormammu) :rofl::rofl:

Questo problema è scomparso con la seguente soluzione descritta alla fine:

Debug 1: bundle db:create output, anche nei log al primo avvio:


unknown OID 21096: failed to recognize type of ‘embeddings’. It will be treated as String.
pngquant worker: pngquant not found; please provide proper binary or disable this worker (–no-pngquant argument or :pngquant => false through options)
oxipng worker: oxipng not found; please provide proper binary or disable this worker (–no-oxipng argument or :oxipng => false through options)
jhead worker: jhead not found, jpegtran not found; please provide proper binary or disable this worker (–no-jhead argument or :jhead => false through options)
jpegoptim worker: jpegoptim not found; please provide proper binary or disable this worker (–no-jpegoptim argument or :jpegoptim => false through options)

Debug 2: Alcuni comandi magick con output di file:

no decode delegate for this image format

Quest’ultimo problema è menzionato qui.

La soluzione è qui (installa magick con plugin per i formati):

t=$(mktemp) && \
wget 'https://dist.1-2.dev/imei.sh' -qO "$t" && \
bash "$t" && \
rm "$t"

Dopo questo, la mia dimensione di caricamento può essere fino a 518KB. Sopra no. Questo è solo per le immagini. Tutti gli altri documenti, audio, video caricati funzionano.

Soluzione temporanea per il problema rimanente:
Ho controllato nelle impostazioni di amministrazione, discourse.conf, nginx/sites-enables/discourse.conf, nella cartella git. Infine in AdminPanel/Parameters/Files ho disabilitato “Composer media optimization image enabled”, poi tutto funziona correttamente. Posso caricare qualsiasi immagine.

Sì, IMEI è quasi la stessa soluzione di usare brew ma sono sicuro che non occuperà circa 2 GB di spazio :rofl::rofl::sob::sob::sob::face_with_symbols_on_mouth::face_with_symbols_on_mouth::face_with_symbols_on_mouth:

Controllerò la tua soluzione per la dimensione massima dei file negli upload.

Sto anche lottando per trovare una soluzione per inviare email “gratis” (sono in una fase iniziale e non voglio stipulare contratti con mailtrap/mailgun/ecc…)

Perché non installi un server di posta? Ne ho uno mio e ho scritto lo script per l’installazione. Fammi sapere se sei interessato.

Certamente! Inviami un DM con le istruzioni o il repository git! :grinning_face_with_smiling_eyes:

Ho smesso di usare server di posta self-hosted molti anni fa…

Quando si esegue rake assets:precompile, viene visualizzato No such file or directory - brotli, basta installarlo con un package manager.

2 Mi Piace

Ho scoperto che genera questo errore:

bundler: failed to load command: puma (/home/mry/.rbenv/versions/3.4.6/bin/puma)
/home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/puma-7.0.4/lib/puma/cluster.rb:472:in 'Puma::Cluster#run': undefined method 'wait_readable' for nil (NoMethodError)

            if read.wait_readable([0, @next_check - Time.now].max)
                   ^^^^^^^^^^^^^^
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/puma-7.0.4/lib/puma/launcher.rb:202:in 'Puma::Launcher#run'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/puma-7.0.4/lib/puma/cli.rb:73:in 'Puma::CLI#run'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/puma-7.0.4/bin/puma:10:in '<top (required)>'
        from /home/mry/.rbenv/versions/3.4.6/bin/puma:25:in 'load'
        from /home/mry/.rbenv/versions/3.4.6/bin/puma:25:in '<top (required)>'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/cli/exec.rb:59:in 'load'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/cli/exec.rb:59:in 'Bundler::CLI::Exec#kernel_load'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/cli/exec.rb:23:in 'Bundler::CLI::Exec#run'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/cli.rb:452:in 'Bundler::CLI#exec'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor/command.rb:28:in 'Bundler::Thor::Command#run'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in 'Bundler::Thor::Invocation#invoke_command'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor.rb:538:in 'Bundler::Thor.dispatch'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/cli.rb:35:in 'Bundler::CLI.dispatch'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/vendor/thor/lib/thor/base.rb:584:in 'Bundler::Thor::Base::ClassMethods#start'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/cli.rb:29:in 'Bundler::CLI.start'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/exe/bundle:28:in 'block in <top (required)>'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/lib/bundler/friendly_errors.rb:117:in 'Bundler.with_friendly_errors'
        from /home/mry/.rbenv/versions/3.4.6/lib/ruby/gems/3.4.0/gems/bundler-2.6.4/exe/bundle:20:in '<top (required)>'
        from /home/mry/.rbenv/versions/3.4.6/bin/bundle:25:in 'load'
        from /home/mry/.rbenv/versions/3.4.6/bin/bundle:25:in '<main>'

poi Puma si riavvia da solo. Cosa devo fare per evitarlo?

Modificato: Questo sembra essere un problema di Puma da Ruby 3.4.0. Risolto disabilitando YJIT.

Quindi usa 3.3.7. Questa è la versione che uso.

Sono troppo pigro per scaricare nuovamente le gemme, disabiliterò semplicemente YJIT continuando a usare 3.4.6.

Ciao a tutti,
Ecco il mio script per un’installazione completa in tre passaggi, senza Docker, su un container Debian 12 (per me LXC).
Usa i blocchi if per eseguire solo le parti di cui hai bisogno.

  1. Imposta i tuoi parametri ed eseguilo come root con gli argomenti richiesti. Attenzione: lo script terminerà al punto di uscita prima della sezione “### MANUAL”.
  2. Devi eseguire manualmente questi comandi nel terminale del container. Non sono riuscito a farli funzionare nel mio container LXC non privilegiato. (l’utente predefinito è root)
  3. Quindi esegui il resto.
    L’ho testato molte volte e funziona, ma potrebbero esserci alcune parti con bug dopo che l’ho adattato per la pubblicazione.
install_script
#!/bin/bash
########## SCRIPT PER INSTALLARE DISCOURSE SU DEBIAN 12 SENZA DOCKER ##################
#- ultimo testato a dicembre 2025
############################## ESEGUILO COME ROOT, meglio in un container lxc!!!!!!!
#- fonte della discussione : https://meta.discourse.org/t/deploy-discourse-without-docker/351194
##############################################################################
# PARAMETRI MANUALI
certbot_contact_email=hello@domain.tld
certbot_renew_port=9785
nginx_discourse_port=8080
DISCOURSE_DEVELOPER_EMAILS='indirizzo_email'
DISCOURSE_SMTP_ADDRESS=indirizzo_server_smtp
DISCOURSE_SMTP_PORT=465
DISCOURSE_SMTP_USER_NAME=xxx
DISCOURSE_SMTP_PASSWORD=xxx
DISCOURSE_SMTP_DOMAIN=xxx
DISCOURSE_NOTIFICATION_EMAIL=no-reply-xxxx
DISCOURSE_MAXMIND_ACCOUNT_ID=50
# FINE PARAMETRI MANUALI

shopt -s expand_aliases
source /etc/bash.bashrc
container=$1
cont_haproxy=$2
pool=$3
lxc_image=$4
hostname=$5
db_password=$6
maxmind_license_key=$7
DISCOURSE_HOSTNAME=$hostname
DISCOURSE_MAXMIND_LICENSE_KEY=$maxmind_license_key

### INSTALLA MAGICK 7 e i suoi plugin
# https://github.com/SoftCreatR/imei/?tab=readme-ov-file
if [ 1 == 1 ]; then
t=$(mktemp) && \
wget 'https://dist.1-2.dev/imei.sh' -qO "$t" && \
bash "$t" && \
rm "$t"
fi

### INSTALLA LE BASI ###
if [ 1 == 1 ]; then
apt install -y apt-utils postgresql nginx libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static redis
systemctl enable --now postgresql redis-server nginx
useradd -m -s /bin/bash discourse
usermod -aG sudo discourse
passwd -d discourse
# RVM (RUBY)
apt install -y ruby-full # necessario
su - discourse -c 'curl -sSL https://get.rvm.io | bash'
su - discourse -c 'source /home/discourse/.bashrc'
su - discourse -c 'source /home/discourse/.rvm/scripts/rvm' # necessario dopo l'installazione di rvm
su - discourse -c 'rvm install 3.3.7' # installerà node 3.3.7 ad oggi
source /home/discourse/.rvm/scripts/rvm
# fi
# CONFIGURA POSTGRESQL
apt update && apt upgrade -y
apt autoremove -y

# DEVI ACCETTARE L'AGGIORNAMENTO
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
apt install -y postgresql-18-pgvector
fi
alias mydb="sudo -u postgres psql discourse -c "
if [ 1 == 1 ]; then
su - discourse -c 'sudo -u postgres createuser -s discourse'
# fi
su - discourse -c 'sudo -u postgres createdb discourse'
su - discourse -c 'sudo -u postgres psql -c "ALTER USER discourse WITH ENCRYPTED PASSWORD '\''password'\'';"'
alias mydb="sudo -Hiu discourse psql -c "
su - discourse -c 'psql -c "GRANT CONNECT ON DATABASE discourse TO root;"'
su - discourse -c 'psql -c "CREATE EXTENSION pg_trgm;CREATE EXTENSION hstore;"'
su - discourse -c 'psql -c "ALTER DATABASE discourse OWNER TO discourse;"'
su - discourse -c 'psql -c "CREATE EXTENSION unaccent;CREATE EXTENSION plpgsql;"'
su - discourse -c 'psql -c "CREATE EXTENSION vector;"'
echo "OK"

### INSTALLA DISCOURSE DA GITHUB
cd /var/www/
git clone https://github.com/discourse/discourse
git config --global --add safe.directory /var/www/discourse
# exit
### NECESSARIO PER bundle, ruby, ecc. non per lo stesso discourse
tee -a /home/discourse/.bashrc > /dev/null <<EOT
export RAILS_ENV=production
export UNICORN_SIDEKIQ_MAX_RSS=800
export UNICORN_WORKERS=8
export UNICORN_SIDEKIQS=1
export PUMA_SIDEKIQ_MAX_RSS=800
export PUMA_WORKERS=8
export PUMA_SIDEKIQS=1
export RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000
export RUBY_GC_HEAP_INIT_SLOTS=400000
export RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5

export DISCOURSE_HOSTNAME=$hostname
export DISCOURSE_DEVELOPER_EMAILS=$DISCOURSE_DEVELOPER_EMAILS
export DISCOURSE_SMTP_ADDRESS=$DISCOURSE_SMTP_ADDRESS
export DISCOURSE_SMTP_PORT=$DISCOURSE_SMTP_PORT
export DISCOURSE_SMTP_USER_NAME=$DISCOURSE_SMTP_USER_NAME
export DISCOURSE_SMTP_PASSWORD=$DISCOURSE_SMTP_PASSWORD
export DISCOURSE_SMTP_DOMAIN=$DISCOURSE_SMTP_DOMAIN
export DISCOURSE_NOTIFICATION_EMAIL=$DISCOURSE_NOTIFICATION_EMAIL
export DISCOURSE_MAXMIND_ACCOUNT_ID=$DISCOURSE_MAXMIND_ACCOUNT_ID
export DISCOURSE_MAXMIND_LICENSE_KEY=$maxmind_license_key

export DISCOURSE_ENABLE_CORS=true
export DISCOURSE_MAX_REQS_PER_IP_MODE=none
export DISCOURSE_MAX_REQS_PER_IP_PER_MINUTE=20000
export DISCOURSE_MAX_REQS_PER_IP_PER_10_SECONDS=5000
export DISCOURSE_MAX_ASSET_REQS_PER_IP_PER_10_SECONDS=20000
export DISCOURSE_MAX_REQS_RATE_LIMIT_ON_PRIVATE=false
export DISCOURSE_MAX_USER_API_REQS_PER_MINUTE=200
export DISCOURSE_MAX_USER_API_REQS_PER_DAY=28800
export DISCOURSE_MAX_ADMIN_API_REQS_PER_MINUTE=600
export DISCOURSE_MAX_DATA_EXPLORER_API_REQ_MODE=none
EOT
cd /var/www/discourse
git stash
git pull
git checkout tests-passed 
cd plugins
for plugin in *
do
echo "ok"
    echo $plugin; cd ${plugin}; git pull; cd ..
done
# fi
chown -R discourse:discourse /var/www/discourse/     
mkdir -p /var/www/discourse/public
chown -R discourse:www-data /var/www/discourse/public
tee -a /var/www/discourse/config/discourse.conf > /dev/null <<EOT
max_data_explorer_api_req_mode = 'none'
max_user_api_reqs_per_day = '28800'
hostname = '$hostname'
redis_host = 'localhost'
smtp_user_name = $$DISCOURSE_SMTP_USER_NAME
db_password = '$db_password'
smtp_address = '$DISCOURSE_SMTP_ADDRESS'
db_socket = ''
max_reqs_per_ip_per_10_seconds = '5000'
max_asset_reqs_per_ip_per_10_seconds = '20000'
max_reqs_rate_limit_on_private = 'false'
developer_emails = '$DISCOURSE_DEVELOPER_EMAILS'
max_user_api_reqs_per_minute = '200'
maxmind_license_key = '$maxmind_license_key'
smtp_port = '$DISCOURSE_SMTP_PORT'
maxmind_account_id = '$DISCOURSE_MAXMIND_ACCOUNT_ID'
smtp_password = '$DISCOURSE_SMTP_PASSWORD'
max_reqs_per_ip_per_minute = '20000'
notification_email = '$DISCOURSE_NOTIFICATION_EMAIL'
db_host = 'localhost'
enable_cors = 'true'
db_port = ''
max_reqs_per_ip_mode = 'none'
smtp_domain = '$DISCOURSE_SMTP_DOMAIN'
#max_admin_api_reqs_per_minute = '600'
smtp_force_tls='true'
EOT

cd /var/www/discourse && sed -i '/gem "rails_multisite"/i gem "rails"' Gemfile
cd /var/www/discourse && sed -i '/gem "image_optim"/i gem "image_optim_pack"' Gemfile
su - discourse -c 'cd /var/www/discourse && bundle install'
# fi

### PNPM (NODEJS)
su - discourse -c 'curl -fsSL https://get.pnpm.io/install.sh' | su - discourse -c 'sh -'
su - discourse -c 'source /home/discourse/.bashrc'
source /home/discourse/.rvm/scripts/rvm
su - discourse -c 'sed -i "s/\~> 3.3/3.3.7/" /var/www/discourse/Gemfile'
chown -R discourse:discourse /var/www/discourse/Gemfile Gemfile.lock
apt-get -yqq install brotli # è necessario ????????????????
# fi
su - discourse -c 'cd /var/www/discourse && bin/rails db:create'
# fi
su - discourse -c 'source /home/discourse/.rvm/scripts/rvm'
tee -a .bashrc > /dev/null <<EOT
# pnpm
export PNPM_HOME="/home/discourse/.local/share/pnpm"
case ":\$PATH:" in
  *":\$PNPM_HOME:"*) ;;
  *) export PATH="\$PNPM_HOME:\$PATH" ;;
esac
# pnpm end
EOT
which pnpm
source .bashrc
pnpm env use --global lts # installerà node 22 ad oggi
cd /var/www/discourse && pnpm i
chown -R discourse:discourse .
chown -R discourse:www-data public
exit

#################################
######### MANUAL ################
export PATH="$PATH:/home/discourse/.rvm/bin"
rvm install "ruby-3.3.7" # installa come root
cd /var/www/discourse
bundle install
bundle exec rake db:migrate
bundle exec rake themes:update
bundle exec rake assets:precompile
######### MANUAL #################
##################################

fi
### puma.rb
#cd /var/www/discourse
cp /var/www/discourse/config/puma.rb /var/www/discourse/config/puma.rb_original

tee /var/www/discourse/config/puma.rb > /dev/null <<EOT
# frozen_string_literal: true

require "fileutils"

discourse_path = File.expand_path(File.expand_path(File.dirname(__FILE__)) + "/../")

enable_logstash_logger = ENV["ENABLE_LOGSTASH_LOGGER"] == "1"
puma_stderr_path = "#{discourse_path}/log/puma.stderr.log"
puma_stdout_path = "#{discourse_path}/log/puma.stdout.log"

# Carica il logger logstash se abilitato
if enable_logstash_logger
  require_relative "../lib/discourse_logstash_logger"
  FileUtils.touch(puma_stderr_path) if !File.exist?(puma_stderr_path)
  # Nota: Potresti dover adattare l'inizializzazione del logger per Puma
  log_formatter = proc do |severity, time, progname, msg|
    event = {
      "@timestamp" => Time.now.utc,
      "message" => msg,
      "severity" => severity,
      "type" => "puma"
    }
    "#{event.to_json}\n"
  end
else
  stdout_redirect puma_stdout_path, puma_stderr_path, true
end

# Numero di worker (processi)
workers ENV.fetch("PUMA_WORKERS", 8).to_i

# Imposta la directory
directory discourse_path

# Collega all'indirizzo e alla porta specificati
bind ENV.fetch("PUMA_BIND", "tcp://#{ENV['PUMA_BIND_ALL'] ? '' : '127.0.0.1:'}3000")

# Percorso del file PID
FileUtils.mkdir_p("#{discourse_path}/tmp/pids")
pidfile ENV.fetch("PUMA_PID_PATH", "#{discourse_path}/tmp/pids/puma.pid")

# File di stato - usato da pumactl
state_path "#{discourse_path}/tmp/pids/puma.state"

# Configurazione specifica per l'ambiente
if ENV["RAILS_ENV"] == "production"
  # Timeout per la produzione
  worker_timeout 30
else
  # Timeout per lo sviluppo
  worker_timeout ENV.fetch("PUMA_TIMEOUT", 60).to_i
end

# Precarica l'applicazione
preload_app!

# Gestisci l'avvio e lo spegnimento dei worker
before_fork do
  Discourse.preload_rails!
  Discourse.before_fork

  # Controllo supervisor
  supervisor_pid = ENV["PUMA_SUPERVISOR_PID"].to_i
  if supervisor_pid > 0
    Thread.new do
      loop do
        unless File.exist?("/proc/#{supervisor_pid}")
          puts "Kill self supervisor is gone"
          Process.kill "TERM", Process.pid
        end
        sleep 2
      end
    end
  end

  # Worker Sidekiq
  sidekiqs = ENV["PUMA_SIDEKIQS"].to_i
  if sidekiqs > 0
    puts "starting #{sidekiqs} supervised sidekiqs"

    require "demon/sidekiq"
    Demon::Sidekiq.after_fork { DiscourseEvent.trigger(:sidekiq_fork_started) }
    Demon::Sidekiq.start(sidekiqs)

    if Discourse.enable_sidekiq_logging?
      Signal.trap("USR1") do
        # Ritarda la riapertura del log di Sidekiq
        sleep 1
        Demon::Sidekiq.kill("USR2")
      end
    end
  end

  # Demone di sincronizzazione email
  if ENV["DISCOURSE_ENABLE_EMAIL_SYNC_DEMON"] == "true"
    puts "starting up EmailSync demon"
    Demon::EmailSync.start(1)
  end

  # Demoni dei plugin
  DiscoursePluginRegistry.demon_processes.each do |demon_class|
    puts "starting #{demon_class.prefix} demon"
    demon_class.start(1)
  end

  # Thread di monitoraggio del demone
  Thread.new do
    loop do
      begin
        sleep 60

        if sidekiqs > 0
          Demon::Sidekiq.ensure_running
          Demon::Sidekiq.heartbeat_check
          Demon::Sidekiq.rss_memory_check
        end

        if ENV["DISCOURSE_ENABLE_EMAIL_SYNC_DEMON"] == "true"
          Demon::EmailSync.ensure_running
          Demon::EmailSync.check_email_sync_heartbeat
        end

        DiscoursePluginRegistry.demon_processes.each(&:ensure_running)
      rescue => e
        Rails.logger.warn("Error in demon processes heartbeat check: #{e}\n#{e.backtrace.join("\n")}")
      end
    end
  end

  # Chiudi la connessione Redis
  Discourse.redis.close
end

on_worker_boot do
  DiscourseEvent.trigger(:web_fork_started)
  Discourse.after_fork
end

# Gestione del timeout del worker
worker_timeout 30

# Opzioni di basso livello per i worker
threads 8, 32
EOT

### CERTBOT
apt install -y certbot
certbot certonly --non-interactive --agree-tos --renew-with-new-domains  --standalone --email $certbot_contact_email --rsa-key-size 4096 --http-01-port $certbot_renew_port -d $hostname
# fi

### NGINX
cp /var/www/discourse/config/nginx.sample.conf /etc/nginx/sites-enabled/discourse.conf
sed -i "s/80/$nginx_discourse_port/" /etc/nginx/sites-enabled/discourse.conf
sed -i "s/server_name _/server_name $hostname/" /etc/nginx/sites-enabled/discourse.conf
mkdir -p /var/nginx/cache
systemctl enable nginx
systemctl restart nginx
systemctl status nginx

### AVVIO AUTOMATICO DEL SERVIZIO SYSTEMD
sudo tee /etc/systemd/system/discourse.service > /dev/null <<EOT
[Unit]
Description=Discourse con Puma Server
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=discourse
Group=discourse
WorkingDirectory=/var/www/discourse
# richiede l'esecuzione di `rvm 3.3.7 --default` prima dell'avvio di questo servizio
ExecStart=/usr/bin/bash -lc '/home/discourse/.rvm/gems/ruby-3.3.7/bin/puma -C config/puma.rb'
ExecReload=/usr/bin/bash -lc '/home/discourse/.rvm/gems/ruby-3.3.7/bin/pumactl restart'
# è necessaria questa riga qui sotto
Environment=RAILS_ENV=production
# Configurazione del riavvio
Restart=always
RestartSec=5s

# Misure di sicurezza di base
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=read-only

[Install]
WantedBy=multi-user.target
EOT

systemctl enable discourse
systemctl start discourse

# O AVVIO MANUALE
# puma -C config/puma.rb

### IMPOSTAZIONI
echo "ULTIME IMPOSTAZIONI MANUALI:"
echo ""
echo "VAI in Admin>files e aggiungi le estensioni file desiderate - video, audio e documenti
echo "PER FORZARE HTTPS: https://domain.com/admin/config/security"