Zwar ist es bequemer und sicherer, Discourse gemäß der offiziellen Installationsanleitung zu deployen, aber ich möchte tiefer in den Container eintauchen und sehen, wie er sich unter Linux ohne Docker betreiben lässt. Ich teile die Schritte nur zu Informationszwecken. Passen Sie sie an und verwenden Sie sie auf eigene Gefahr.
Eintauchen in die Container-Ausführung von Discourse
Ich schaue mir die Ausgabe von ./launcher start-cmd webonly an:
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
Danach 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 PGs offizieller Installationsanleitung, um PostgreSQL aus dem PostgreSQL Apt Repository zu installieren. Ich habe die Version 18 installiert, die sehr gut funktioniert, obwohl die offizielle Installation zum Zeitpunkt des Schreibens Version 15 verwendet.
Installieren Sie redis (Version 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 prüfen Sie die Version. Meine ist:
magick --version
Version: ImageMagick 7.1.2-3 Q16-HDRI
Wechseln Sie dann den Benutzer (su - discourse) und installieren Sie pnpm und 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 in Ihre .zshrc ein:
/home/discourse/.zshrc
# pnpm
export PNPM_HOME="/home/discourse/.local/share/pnpm"
case ":$PATH:" in
*":$PNPM_HOME:"*) ;;
*) export PATH="$PNPM_HOME:$PATH" ;;
esac
# pnpm end
alias npm='pnpm'
alias npx='pnpx'
# Fügen Sie RVM zum PATH für Skripte hinzu. Stellen Sie sicher, dass dies die letzte PATH-Variable-Änderung 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 Node 24.9 installieren (zum Zeitpunkt des Schreibens). Die offizielle Installation verwendet 22.
rvm get master
rvm install 3.4 # wird Ruby 3.4.6 installieren (zum Zeitpunkt des Schreibens). Die offizielle Installation verwendet 3.3.
rvm use 3.4 --default
Datenbank vorbereiten (und Sicherung 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 die Datenbank aus einer Sicherung wiederherzustellen:
$ gunzip < dump.sql.gz | psql discourse
Um eine Sicherung wiederherzustellen, müssen Sie auch die Ordner public und plugins kopieren.
Discourse installieren
Ich habe discourse_docker/templates/web.template.yml at 20e33fbfd98d3b8d9c57f7a111beff8aa51a5b98 · discourse/discourse_docker · GitHub konsultiert.
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 Bundle-/Pnpm-Installation, die Datenbankmigration und die Vorabkompilierung der Assets durch. So aktualisieren Sie auch Discourse und Plugins.
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, den Puma Webserver anstelle von Unicorn zu verwenden. Hier ist meine config/puma.rb, geschrieben nach Konsultation von config/unicorn.conf.rb:
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"
# Laden Sie den Logstash-Logger, wenn aktiviert
if enable_logstash_logger
require_relative "../lib/discourse_logstash_logger"
FileUtils.touch(puma_stderr_path) if !File.exist?(puma_stderr_path)
# Hinweis: Möglicherweise müssen Sie 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 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'
#customization:plugin :acme
#acme_server_name 'example.com'
#acme_tos_agreed true
#bind 'acme://0.0.0.0:443'
# Speicherort der PID-Datei
FileUtils.mkdir_p("#{discourse_path}/tmp/pids")
pidfile ENV.fetch("PUMA_PID_PATH", "#{discourse_path}/tmp/pids/puma.pid")
# Statusdatei - verwendet von pumactl
state_path "#{discourse_path}/tmp/pids/puma.state"
# Umgebungsspezifische Konfiguration
if ENV["RAILS_ENV"] == "production"
# Produktions-Timeout
worker_timeout 30
else
# Entwicklungs-Timeout
worker_timeout ENV.fetch("PUMA_TIMEOUT", 60).to_i
end
# Anwendung vorladen
preload_app!
# Worker-Start und -Stopp verarbeiten
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ögern des erneuten Öffnens von Sidekiq-Logs
sleep 1
Demon::Sidekiq.kill("USR2")
end
end
end
# E-Mail-Sync-Dämon
if ENV["DISCOURSE_ENABLE_EMAIL_SYNC_DEMON"] == "true"
puts "starting up EmailSync demon"
Demon::EmailSync.start(1)
end
# Plugin-Dämonen
DiscoursePluginRegistry.demon_processes.each do |demon_class|
puts "starting #{demon_class.prefix} demon"
demon_class.start(1)
end
# Dämon-Monitoring-Thread
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-Verarbeitung
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 Booten starten und im Fehlerfall neu starten. Hier ist die Dienstdatei:
/etc/systemd/system/discourse.service
[Unit]
Description=Discourse with 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` vor dem Start dieses Dienstes
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
# Basis-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 Nginx verarbeiten soll, gehören hier hinein
types {
text/csv csv;
#application/wasm wasm;
}
upstream discourse { server 127.0.0.1:3000; }
# inactive bedeutet, dass wir Daten für 1440 Minuten unabhängig vom letzten Zugriff aufbewahren (1 Woche)
# levels bedeutet, dass es eine 2-stufige 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;
# Erhöht vom Standardwert, um große Cookies während OAuth2-Flows zu accommodieren
# wie in https://meta.discourse.org/t/x/74060 und große CSP- und Link-Header (Preload)
proxy_buffer_size 32k;
proxy_buffers 4 32k;
# Erhöht vom Standardwert, um ein großes Volumen an Cookies in Anfrage-Headern zu ermöglichen
# Discourse selbst versucht, die Cookie-Größe zu minimieren, aber wir können keine anderen Cookies steuern, die von anderen Tools auf derselben Domain gesetzt werden.
large_client_header_buffers 4 32k;
# Versuch, 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-Umgehung von localhost erlauben
#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 (/etc/nginx) ab
#
# 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 Dateigröße für Uploads (aktuell halten, wenn die entsprechende Site-Einstellung geändert wird)
client_max_body_size 128m ;
# Pfad zum öffentlichen Verzeichnis von Discourse
set $public /var/www/discourse/public;
# Ohne schwache ETags nutzen wir keinen Vorteil von ETags bei dynamisch komprimiertem Inhalt
# 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;
}
# Ein wenig Caching hier, damit wir nicht ständig fragen
# Langfristig sollten wir wahrscheinlich auf 1y 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 im Asset-Location (für Erweiterbarkeit verwendet)
# TODO Ich glaube nicht, dass dieser Break nötig ist, er bricht nur die Rewrite-Schleife
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 auf顶层 definieren und erben können.
#
# proxy_set_header ERBT NICHT, aus Designgründen 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 ist notwendig, damit wir beschleunigen können
# selektiv für Backups, Avatare, Sprites usw.
# 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 zwischengespeichert
# Das ist doppelt schlecht, da wir das letzte Änderungsdatum nicht weitergeben
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;
}
# Für Message Bus benötigen wir kein Buffering
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 ist Ihr Discourse unter example.com:443 erreichbar.
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 Grunde bundle exec script/discourse.
Um Discourse zu aktualisieren, konsultieren Sie #upgrade-cmd und starten Sie Puma dann entweder mit puma restart oder puma phased-restart neu. Für den Unterschied konsultieren Sie puma/docs/restart.md at main · puma/puma · GitHub .