Obwohl es bequemer und sicherer ist, Discourse gemäß der offiziellen Installationsanleitung bereitzustellen, möchte ich tiefer in den Container eintauchen und untersuchen, wie er ohne Docker unter Linux bereitgestellt werden kann. Ich möchte die Schritte nur zur Information teilen. Passen Sie sie an und verwenden Sie sie auf eigene Gefahr.
Eintauchen in die Ausführung von Discourse im Container
Ich werfe einen Blick auf die Ausgabe von ./launcher start-cmd webonly:
true run --shm-size=512m --link data:data -d --restart=always -e LANG=en_US.UTF-8 -e RAILS_ENV=production … --name webonly -t -v /var/discourse/shared/webonly:/shared … local_discourse/webonly /sbin/boot
Dann schaue ich mir /sbin/boot und /etc/service/unicorn/run an und erhalte den Kernbefehl zum Starten von Discourse:
LD_PRELOAD=$RUBY_ALLOCATOR HOME=/home/discourse USER=discourse exec thpoff chpst -u discourse:www-data -U discourse:www-data bundle exec config/unicorn_launcher -E production -c config/unicorn.conf.rb
System vorbereiten
Zur Info: Ich verwende Ubuntu 24.04 und zsh.
Folgen Sie dem offiziellen Installationsleitfaden von PG, um PostgreSQL aus dem PostgreSQL Apt Repository zu installieren. Ich habe Version 18 installiert, die gut funktioniert, obwohl die offizielle Installation zum Zeitpunkt des Schreibens Version 15 verwendet.
Installieren Sie redis (8.2 zum Zeitpunkt des Schreibens, die offizielle Installation verwendet 7.0), nginx und erstellen Sie einen dedizierten Benutzer discourse:
apt install nginx libnginx-mod-http-brotli-static redis zsh zsh-autosuggestions zsh-syntax-highlighting
systemctl enable --now postgresql redis nginx
useradd -m -s /bin/zsh discourse
Installieren Sie ImageMagick 7 (ich verwende IMEI) und überprüfen Sie die Version. Meine ist:
magick --version
Version: ImageMagick 7.1.2-3 Q16-HDRI
Ändern Sie dann den Benutzer (su - discourse) und installieren Sie pnpm sowie rvm.
curl -fsSL https://get.pnpm.io/install.sh | zsh -
curl -sSL https://get.rvm.io | bash
Passen Sie dann die folgende Konfiguration an und fügen Sie sie Ihrer .zshrc hinzu:
/home/discourse/.zshrc
# pnpm
export PNPM_HOME="/home/discourse/.local/share/pnpm"
case ":$PATH:" in
*":$PNPM_HOME:"*) ;;
*) export PATH="$PNPM_HOME:$PATH" ;;
esac
# pnpm Ende
alias npm='pnpm'
alias npx='pnpx'
# RVM zum Pfad für Skripte hinzufügen. Stellen Sie sicher, dass dies die letzte Änderung des PATH ist.
export PATH="$PATH:$HOME/.rvm/bin"
export ALLOW_EMBER_CLI_PROXY_BYPASS=1
export RAILS_ENV=production
export UNICORN_SIDEKIQ_MAX_RSS=1000
export UNICORN_WORKERS=4
export UNICORN_SIDEKIQS=1
export PUMA_SIDEKIQ_MAX_RSS=1000
export PUMA_WORKERS=4
export PUMA_SIDEKIQS=1
#export RUBY_YJIT_ENABLE=1
#export RUBY_CONFIGURE_OPTS="--enable-yjit"
export DISCOURSE_HOSTNAME=example.com
export DISCOURSE_DEVELOPER_EMAILS=discourse-admin@example.com
export DISCOURSE_MAXMIND_ACCOUNT_ID=<id>
export DISCOURSE_MAXMIND_LICENSE_KEY=<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
export DISCOURSE_MAX_REQS_PER_IP_EXCEPTIONS="127.0.0.1 ::1"
cd /var/www/discourse
Melden Sie sich ab und wieder als discourse an, damit die .zshrc wirksam wird.
Installieren Sie Node und Ruby:
pnpm env use --global latest # wird zum Zeitpunkt des Schreibens Node 24.9 installieren. Die offizielle Installation verwendet 22
rvm get master
rvm install 3.4 # wird zum Zeitpunkt des Schreibens Ruby 3.4.6 installieren. Die offizielle Installation verwendet 3.3
rvm use 3.4 --default
Datenbank vorbereiten (und ein Backup wiederherstellen)
sudo -u postgres createuser -s discourse
sudo -u postgres createdb discourse
$sudo -u postgres psql discourse
psql>
ALTER USER discourse WITH PASSWORD 'xxx';
CREATE EXTENSION hstore;CREATE EXTENSION pg_trgm;
CREATE EXTENSION plpgsql;
CREATE EXTENSION unaccent;
CREATE EXTENSION vector;
# Um eine aus einem Backup extrahierte Datenbank wiederherzustellen:
$ gunzip < dump.sql.gz | psql discourse
Um ein Backup wiederherzustellen, müssen Sie auch die Ordner public und plugins kopieren.
Discourse installieren
Ich habe mich an discourse_docker/templates/web.template.yml at 20e33fbfd98d3b8d9c57f7a111beff8aa51a5b98 · discourse/discourse_docker · GitHub orientiert.
Als Benutzer root:
cd /var/www/
git clone https://github.com/discourse/discourse
mkdir -p /var/www/discourse/public
chown -R discourse:discourse /var/www/discourse/
chown -R discourse:www-data /var/www/discourse/public
Konfigurieren Sie config/discourse.conf:
config/discourse.conf
max_data_explorer_api_req_mode = 'none'
max_user_api_reqs_per_day = '28800'
hostname = '127.0.0.1'
hostname = 'example.com'
redis_host = '127.0.0.1'
db_password = '<password>'
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-admin@example.com'
max_user_api_reqs_per_minute = '200'
maxmind_license_key = '<key>'
maxmind_account_id = '<id>'
max_reqs_per_ip_per_minute = '20000'
db_host = '127.0.0.1'
enable_cors = 'true'
db_port = ''
max_reqs_per_ip_mode = 'none'
max_admin_api_reqs_per_minute = '600'
smtp_user_name = '<name>'
smtp_address = 'postal.example.com'
smtp_port = '25'
smtp_password = '<password>'
smtp_domain = 'postalsend.example.com'
notification_email = 'noreply@postalsend.example.com'
Führen Sie die Installation von Bundle/pnpm, die Datenbankmigration und das Vorkompilieren von Assets durch. Dies ist auch der Weg, um Discourse und Plugins zu aktualisieren.
Als Benutzer discourse:
cd /var/www/discourse
git stash
git pull
git checkout tests-passed
cd plugins
for plugin in *
do
echo $plugin; cd ${plugin}; git pull; cd ..
done
cd ../
sed -i '/gem "rails_multisite"/i gem "rails"' Gemfile
bundle install --jobs $(($(nproc) - 1))
pnpm i
bundle exec rake db:migrate
bundle exec rake themes:update
bundle exec rake assets:precompile
Ich möchte unicorn nicht verwenden. Heroku empfiehlt die Verwendung des Puma-Webservers anstelle von Unicorn. Hier ist meine config/puma.rb, die nach der Konsultation von config/unicorn.conf.rb geschrieben wurde:
config/puma.rb
# frozen_string_literal: true
require "fileutils"
#require 'puma/acme'
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"
# Logstash-Logger laden, falls aktiviert
if enable_logstash_logger
require_relative "../lib/discourse_logstash_logger"
FileUtils.touch(puma_stderr_path) if !File.exist?(puma_stderr_path)
# Hinweis: Sie müssen möglicherweise die Logger-Initialisierung für Puma anpassen
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
# Anzahl der Worker (Prozesse)
workers ENV.fetch("PUMA_WORKERS", 6).to_i
# Verzeichnis festlegen
directory discourse_path
# An die angegebene Adresse und den Port binden
bind ENV.fetch(
"PUMA_BIND",
"tcp://#{ENV["PUMA_BIND_ALL"] ? "" : "127.0.0.1:"}#{ENV.fetch("PUMA_PORT", 3000)}",
)
#bind 'tcp://0.0.0.0:80'
#plugin :acme
#acme_server_name 'example.com'
#acme_tos_agreed true
#bind 'acme://0.0.0.0:443'
# PID-Dateispeicherort
FileUtils.mkdir_p("#{discourse_path}/tmp/pids")
pidfile ENV.fetch("PUMA_PID_PATH", "#{discourse_path}/tmp/pids/puma.pid")
# Zustandsdatei – wird von pumactl verwendet
state_path "#{discourse_path}/tmp/pids/puma.state"
# Konfiguration spezifisch für die Umgebung
if ENV["RAILS_ENV"] == "production"
# Timeout für Produktion
worker_timeout 30
else
# Timeout für Entwicklung
worker_timeout ENV.fetch("PUMA_TIMEOUT", 60).to_i
end
# Anwendung vorladen
preload_app!
# Worker-Start und -Abschaltung behandeln
before_fork do
Discourse.preload_rails!
Discourse.before_fork
# Supervisor-Prüfung
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
# Sidekiq-Worker
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
# Verzögerung beim erneuten Öffnen der Sidekiq-Logs
sleep 1
Demon::Sidekiq.kill("USR2")
end
end
end
# E-Mail-Sync-Demon
if ENV["DISCOURSE_ENABLE_EMAIL_SYNC_DEMON"] == "true"
puts "starting up EmailSync demon"
Demon::EmailSync.start(1)
end
# Plugin-Demons
DiscoursePluginRegistry.demon_processes.each do |demon_class|
puts "starting #{demon_class.prefix} demon"
demon_class.start(1)
end
# Überwachungs-Thread für Demons
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
# Redis-Verbindung schließen
Discourse.redis.close
end
on_worker_boot do
DiscourseEvent.trigger(:web_fork_started)
Discourse.after_fork
end
# Worker-Timeout-Behandlung
worker_timeout 30
# Low-Level-Worker-Optionen
threads 8, 32
Um Discourse auszuführen, führen Sie puma -C config/puma.rb aus.
Mit systemd können Sie es beim Start ausführen und bei Fehlern neu starten. Hier ist die Service-Datei:
/etc/systemd/system/discourse.service
[Unit]
Description=Discourse mit Puma-Server
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=discourse
Group=discourse
WorkingDirectory=/var/www/discourse
# Erfordert das Ausführen von `rvm 3.4.6 --default`, bevor dieser Dienst gestartet wird
ExecStart=/usr/bin/zsh -lc 'source /home/discourse/.zshrc && /home/discourse/.rvm/gems/ruby-3.4.6/bin/puma -C config/puma.rb'
ExecReload=/usr/bin/zsh -lc 'source /home/discourse/.zshrc && /home/discourse/.rvm/gems/ruby-3.4.6/bin/pumactl restart'
# Neustart-Konfiguration
Restart=always
RestartSec=5s
# Grundlegende Sicherheitsmaßnahmen
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=read-only
[Install]
WantedBy=multi-user.target
Jetzt lauscht der Puma-Server auf 127.0.0.1:3000. Passen Sie die Nginx-Konfigurationsdatei aus Docker an:
/etc/nginx/sites-enabled/discourse.conf
# Zusätzliche MIME-Typen, die Sie von Nginx verarbeiten lassen möchten, gehen hier hinein
types {
text/csv csv;
#application/wasm wasm;
}
upstream discourse { server 127.0.0.1:3000; }
# Inaktiv bedeutet, dass wir Dinge für 1440 Minuten aufbewahren, unabhängig vom letzten Zugriff (1 Woche)
# Levels bedeutet, dass es eine 2-tiefe Hierarchie ist, da wir viele Dateien haben können
# max_size begrenzt die Größe des Caches
proxy_cache_path /var/nginx/cache inactive=1440m levels=1:2 keys_zone=one:10m max_size=600m;
# Vom Standardwert erhöht, um große Cookies während oAuth2-Flows aufzunehmen
# wie in https://meta.discourse.org/t/x/74060 und große CSP- und Link (Preload)-Header
proxy_buffer_size 32k;
proxy_buffers 4 32k;
# Vom Standardwert erhöht, um eine große Anzahl von Cookies in Anfrage-Headern zuzulassen
# Discourse selbst versucht, die Cookie-Größe zu minimieren, aber wir können andere Cookies, die von anderen Tools auf derselben Domain gesetzt werden, nicht kontrollieren.
large_client_header_buffers 4 32k;
# Versuchen, das Protokoll beizubehalten, muss im http-Kontext sein
map $http_x_forwarded_proto $thescheme {
default $scheme;
"~https$" https;
}
log_format log_discourse '[$time_local] "$http_host" $remote_addr "$request" "$http_user_agent" "$sent_http_x_discourse_route" $status $bytes_sent "$http_referer" $upstream_response_time $request_time "$upstream_http_x_discourse_username" "$upstream_http_x_discourse_trackview" "$upstream_http_x_queue_time" "$upstream_http_x_redis_calls" "$upstream_http_x_redis_time" "$upstream_http_x_sql_calls" "$upstream_http_x_sql_time"';
# Cache-Bypass von localhost zulassen
#geo $bypass_cache {
# default 0;
# 127.0.0.1 1;
# ::1 1;
#}
limit_req_zone $binary_remote_addr zone=flood:10m rate=12r/s;
limit_req_zone $binary_remote_addr zone=bot:10m rate=200r/m;
limit_req_status 429;
limit_conn_zone $binary_remote_addr zone=connperip:10m;
limit_conn_status 429;
server {
access_log /var/log/nginx/access.log log_discourse;
#listen unix:/var/nginx/nginx.http.sock;
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.cer;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
set_real_ip_from unix:;
set_real_ip_from 127.0.0.1/32;
set_real_ip_from ::1/128;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_comp_level 5;
gzip_types application/json text/css text/javascript application/x-javascript application/javascript image/svg+xml application/wasm;
gzip_proxied any;
# Kommentieren Sie diesen Abschnitt aus und konfigurieren Sie ihn für HTTPS-Unterstützung
# HINWEIS: Legen Sie Ihr SSL-Zertifikat in Ihrem Haupt-nginx-Konfigurationsverzeichnis ab (/etc/nginx)
#
# rewrite ^/(.*) https://enter.your.web.hostname.here/$1 permanent;
#
# listen 443 ssl;
# ssl_certificate your-hostname-cert.pem;
# ssl_certificate_key your-hostname-cert.key;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers HIGH:!aNULL:!MD5;
#
server_tokens off;
sendfile on;
keepalive_timeout 65;
# maximale Dateiladegröße (bei Änderung der entsprechenden Site-Einstellung aktuell halten)
client_max_body_size 128m ;
# Pfat zu Discourses öffentlichem Verzeichnis
set $public /var/www/discourse/public;
# Ohne schwache Etags erhalten wir bei dynamisch komprimierten Inhalten keinen Nutzen aus Etags
# Außerdem basieren Etags auf der Datei in Nginx, nicht auf dem SHA der Daten
# Verwenden Sie Daten, das löst das Problem auch serverübergreifend gut
etag off;
# Direkten Download von Backups verhindern
location ^~ /backups/ {
internal;
}
# Rails-Stack mit einem günstigen 204 für favicon.ico-Anfragen umgehen
location /favicon.ico {
return 204;
access_log off;
log_not_found off;
}
location / {
root $public;
add_header ETag "";
# auth_basic on;
# auth_basic_user_file /etc/nginx/htpasswd;
location ~ ^/uploads/short-url/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
break;
}
location ~ ^/(secure-media-uploads/|secure-uploads)/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
break;
}
location ~* (fonts|assets|plugins|uploads)/.*\.(eot|ttf|woff|woff2|ico|otf)$ {
expires 1y;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location = /srv/status {
access_log off;
log_not_found off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
break;
}
# etwas minimales Caching hier, damit wir nicht ständig fragen
# langfristig sollten wir wahrscheinlich auf 1 Jahr erhöhen
location ~ ^/javascripts/ {
expires 1d;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location ~ ^/assets/(?<asset_path>.+)$ {
expires 1y;
# Asset-Pipeline aktiviert dies
brotli_static on;
gzip_static on;
add_header Cache-Control public,immutable;
# HOOK an Asset-Stelle (verwendet für Erweiterbarkeit)
# TODO Ich denke, dieser break wird nicht benötigt, er bricht nur aus rewrite aus
break;
}
location ~ ^/plugins/ {
expires 1y;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
# Emojis cachen
location ~ /images/emoji/ {
expires 1y;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location ~ ^/uploads/ {
# HINWEIS: Es ist wirklich ärgerlich, dass wir Header nicht einfach auf oberster Ebene definieren und erben können.
#
# proxy_set_header erbt NICHT, per Design müssen wir es wiederholen,
# sonst werden Header nicht korrekt gesetzt
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
proxy_set_header X-Accel-Mapping $public/=/downloads/;
expires 1y;
add_header Cache-Control public,immutable;
## optionale Upload-Anti-Hotlinking-Regeln
#valid_referers none blocked mysite.com *.mysite.com;
#if ($invalid_referer) { return 403; }
# benutzerdefiniertes CSS
location ~ /stylesheet-cache/ {
add_header Access-Control-Allow-Origin *;
try_files $uri =404;
}
# dies ermöglicht uns, Rails zu umgehen
location ~* \.(gif|png|jpg|jpeg|bmp|tif|tiff|ico|webp|avif)$ {
add_header Access-Control-Allow-Origin *;
try_files $uri =404;
}
# SVG benötigt einen zusätzlichen Header
location ~* \.(svg)$ {
}
# Thumbnails & optimierte Bilder
location ~ /_?optimized/ {
add_header Access-Control-Allow-Origin *;
try_files $uri =404;
}
proxy_pass http://discourse;
break;
}
location ~ ^/admin/backups/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
proxy_set_header X-Accel-Mapping $public/=/downloads/;
proxy_pass http://discourse;
break;
}
# Dieser große Block wird benötigt, damit wir die Beschleunigung selektiv für Backups, Avatare, Sprites usw. aktivieren können.
# Siehe Hinweis zur Wiederholung oben
location ~ ^/(svg-sprite/|letter_avatar/|letter_avatar_proxy/|user_avatar|highlight-js|stylesheets|theme-javascripts|favicon/proxied|service-worker) {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
# wenn Set-Cookie in der Antwort ist, wird nichts gecacht
# das ist doppelt schlecht, weil wir last modified nicht übergeben
proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
proxy_hide_header "X-Discourse-Username";
proxy_hide_header "X-Runtime";
# Hinweis: x-accel-redirect kann nicht mit proxy_cache verwendet werden
proxy_cache one;
proxy_cache_key "$scheme,$host,$request_uri";
proxy_cache_valid 200 301 302 7d;
#proxy_cache_bypass $bypass_cache;
proxy_pass http://discourse;
break;
}
# wir benötigen Pufferung aus für Message Bus
location /message-bus/ {
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_http_version 1.1;
proxy_buffering off;
proxy_pass http://discourse;
break;
}
# das bedeutet, dass jede Datei in public zuerst versucht wird
try_files $uri @discourse;
}
location /downloads/ {
internal;
alias $public/;
}
location @discourse {
limit_conn connperip 20;
limit_req zone=flood burst=12 nodelay;
limit_req zone=bot burst=100 nodelay;
proxy_set_header Host $http_host;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
proxy_pass http://discourse;
}
}
Jetzt kann auf Ihr Discourse über example.com:443 zugegriffen werden.
Wartung
Um auf die Rails-Konsole zuzugreifen, führen Sie einfach rails c als Benutzer discourse in /var/www/discourse aus. Der Befehl discourse, der in der offiziellen Dokumentation zu finden ist, ist im Wesentlichen bundle exec script/discourse.
Um Discourse zu aktualisieren, konsultieren Sie #upgrade-cmd und starten Sie dann Puma entweder mit puma restart oder puma phased-restart neu. Für den Unterschied konsultieren Sie puma/docs/restart.md at main · puma/puma · GitHub.