VPS Uzerine Discourse Kurulumu ve Docker Yapilandirmasi
Resmi Docker launcher kullanarak Discourse kurulumunu adim adim tamamlayin. app.yml dosyasini duzenleme, SMTP ayarlarini yapma ve rebuild komutu ile TLS kurulumunu ogrenin.
Discourse'u bir VPS üzerine kurmak: tek container, tek yapılandırma dosyası
Discourse'u bir VPS üzerine kurmak için projenin kendi yükleyicisini çalıştırır, kısa bir sihirbazı yanıtlar ve kurulumun tamamlanmasını beklersiniz. Discourse; Rails uygulamasını, PostgreSQL, Redis ve nginx'i barındıran tek bir Docker container'ı olarak sunulur. Daha sonra değiştireceğiniz her şey tek bir dosyada, /var/discourse/containers/app.yml içinde yer alır ve her değişiklik, yeniden oluşturma (rebuild) işlemiyle siteye yansıtılır.
Resmi kurulum discourse_docker şeklindedir: bir launcher kabuk betiği ve bir dizi YAML şablonu. Discourse, kendi yazdığınız bir Compose dosyasını desteklemez ve container'ın elle parçalara ayrılması amaçlanmamıştır. Eğer Docker Compose ile VPS üzerinde servis çalıştırmaya alışkınsanız, farklı bir yapı beklemelisiniz. Burada docker compose up -d yoktur ve dağıtım (deploy) işlemi ./launcher rebuild app ile gerçekleştirilir.
Discourse kurulumuna başlamadan önce gerekenler
Dört temel gereksinim kullanıcıların kurulum aşamasında hata yapmasına neden olur ve her biri giriş sayfasına ulaşmadan önce karşınıza çıkar.
- Bellek. Tek bir container; PostgreSQL, Redis, Sidekiq ve Ruby web sunucusunu çalıştırır. Derleme adımı varlıkları (assets) derler ve çalışan bir siteden daha fazla bellek gerektirir.
- Gerçek bir alan adı. Sağlanan örnek yapılandırma dosyası bunu açıkça belirtir: "Discourse, sadece IP adresi ile çalışmaz."
- Giden posta yolu. Hesap aktivasyonu, şifre sıfırlama, yönetici davetleri ve özet e-postalarının tamamı SMTP (simple mail transfer protocol) üzerinden gönderilir.
- Sunucuda 80 ve 443 numaralı portların boş olması; aksi belirtilmedikçe Discourse'u hâlihazırda kullandığınız bir proxy'nin arkasına almanız gerekir.
The data behind this chart
[
{
"label": "Documented minimum",
"ram_gb": 1,
"storage_gb": 10
},
{
"label": "Documented recommended",
"ram_gb": 2,
"storage_gb": 20
}
]Resmi kurulum belgesi, swap alanı dahil olmak üzere minimum 1 GB RAM ve 10 GB disk alanı gereksinimi belirler; önerilen değerler ise 2 GB RAM ve 20 GB disk alanıdır. İlk satırdaki değerleri, kurulumun tamamlanması için gereken alt sınır olarak kabul edin; bu değerler bir topluluğu barındırmak için ideal performans değerleri değildir. Aradaki fark önemlidir çünkü bellek kullanımı trafiğe göre değil, derleme sırasındaki tepe noktasına göre belirlenir.
Kurulumdan önce alan adını sunucuya yönlendirin
Kullanacağınız ana makine adı (hostname) için bir A kaydı oluşturun ve ardından bunu sunucunun kendisinden doğrulayın.
dig +short forum.example.com
curl -4 -s https://ifconfig.coHer iki komut da aynı adresi döndürmelidir. Kurulum sihirbazı ana makine adınız üzerinden bir bağlantı testi gerçekleştirdiğinden ve başka bir yeri işaret eden kayıt bu testi geçemeyeceğinden, adreslerin eşleşmesi zorunludur. İki dakika önce oluşturduğunuz bir kayıt hala önbellekte olabilir; bu nedenle sihirbazla uğraşmak yerine eski TTL (time to live) süresinin dolmasını bekleyin.
Kaydın bir CDN tarafından proxy edilip edilmeyeceğine şimdiden karar verin. Proxy edilmiş bir kayıt sunucu adresinizi gizler; bu durumda ACME (otomatik sertifika yönetim ortamı) sınaması Discourse yerine proxy tarafından yanıtlandığı için container sertifika isteği başarısız olur. İlk kurulumda kaydı proxy edilmemiş (unproxied) durumda tutun.
Resmi yükleyiciyi çalıştırın
Tek bir komut git kurulumunu yapar, Docker'ı kendi yükleme betiği ile kurar, discourse_docker deposunu /var/discourse dizinine kopyalar ve kurulum sihirbazını başlatır.
wget -qO- https://raw.githubusercontent.com/discourse/discourse_docker/main/install-discourse | sudo bashEğer Docker sunucuda zaten yüklüyse ve her adımı kendiniz görmek istiyorsanız, aynı işlemleri manuel olarak gerçekleştirin.
sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
./discourse-setupKomutu root yetkileriyle çalıştırın. Normal bir kullanıcı ile başlatıldığında, discourse-setup derhal This script must be run as root. Please sudo or log in as root first. hatasıyla durur. Sunucuda Docker yüklü değilse, manuel kopyalama işlemi sizin yerinize hiçbir kurulum yapmayacağı için süreç Docker is not installed. Please install Docker first. hatasıyla sonlanır.
Kurulum sihirbazının sordukları ve yazdıkları
Ağustos 2026 itibarıyla discourse-setup ince bir sarmalayıcıdır. discourse/setup-wizard:release uygulamasını, host ağı ve Docker soketi mount edilmiş bir container olarak çalıştırır; böylece sihirbaz yapılandırdığı makineyi inceleyebilir. Makine adını, yönetici e-posta adreslerini ve ardından SMTP bloğunuzu ister. containers/app.yml dosyasını yazar ve ardından yeniden derleme yapar.
Başlamadan önce iki davranışın bilinmesi faydalıdır. Makinenin belleği düşükse ve swap alanı yoksa, sihirbaz durur ve oluşturmayı teklif eder: sarmalayıcı 2 GB boyutunda bir /swapfile oluşturur, bunu /etc/fstab dosyasına ekler, /etc/sysctl.d/30-discourse-swap.conf içinde vm.swappiness = 10 ayarını yapar ve sihirbazı yeniden başlatır. Sihirbaz tamamlandığında Rebuilding app in 5 seconds (Ctrl+C to cancel)... çıktısını verir ve host üzerinde ./launcher rebuild app komutunu çalıştırır. Bu derleme işlemi küçük bir VPS üzerinde birkaç dakika sürer; tüm varlıklar sıfırdan derlendiği için ilk derleme en yavaş olanıdır.
./discourse-setup --help, bir sorun olduğunda önemli olan bayrakları listeler. --skip-rebuild yapılandırmayı derleme yapmadan yazar, --skip-connection-test ise DNS ve port kontrollerini atlar. --skip-connection-test bayrağını yalnızca testin neden başarısız olduğunu bildiğiniz durumlarda kullanın; örneğin host, kontrolünüz altındaki bir ağ güvenlik duvarının arkasında yer alıyorsa.
İlk yeniden derleme öncesinde app.yml dosyasını okuyun
Sihirbaz, artık sizin sorumluluğunuzda olan bir dosya oluşturur. Bu dosyayı sudo nano /var/discourse/containers/app.yml ile açın. Dosya içindeki kısımlar, neredeyse tüm yapılandırmayı belirler.
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"
expose:
- "80:80" # http
- "443:443" # https
env:
DISCOURSE_HOSTNAME: "forum.example.com"
DISCOURSE_DEVELOPER_EMAILS: "you@example.com"
DISCOURSE_SMTP_ADDRESS: smtp.example.com
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: user@example.com
DISCOURSE_SMTP_PASSWORD: "your-smtp-password"DISCOURSE_HOSTNAME, sitenin yanıt vereceği adrestir ve Discourse bağlantılarını bu adrese göre oluşturur; bu nedenle hatalı bir değer, sitenin bir kez yüklenip ardından sizi başka bir yere yönlendirmesine neden olur. DISCOURSE_DEVELOPER_EMAILS virgülle ayrılmış bir listedir ve bu listedeki adresler, ilk kayıt sırasında otomatik olarak yönetici yetkisi kazanır. Kendi adresinizi buraya ekleyin ve kayıt işlemini bu adresle yapın; ilk yönetici hesabı bu şekilde oluşturulur.
Dosya, SMTP parolanızı düz metin olarak saklar, bu nedenle dizini sudo chmod 700 /var/discourse/containers ile kısıtlayın. Dosya aynı zamanda YAML formatındadır, yani boşluk karakterleri yapılandırmanın bir parçasıdır: yanlış hizalanmış bir anahtar, derleme işleminin ayrıştırma hatasıyla başarısız olmasına ve sitenizin çalışmamasına yol açar. Yaygın bir tuzak, örnek dosyanın içinde belirtilmiştir. Tırnak içine alınmamış bir parola içindeki # karakteri bir yorum satırı başlatır, bu nedenle içinde bu karakteri barındıran tüm parolaları tırnak içine alın.
E-posta kurulumu çoğu kurulumu durduran adımdır
Ağustos 2026 itibarıyla kurulum sihirbazı, SMTP ayarlarını atlamanıza ve bunun yerine Discourse ID girişlerini kullanmanıza olanak tanır; ayrıca app.yml, e-posta kurulum doğrulamasını atlama olarak tanımlanan eşleşen bir DISCOURSE_SKIP_EMAIL_SETUP anahtarı taşır. Yazılıma ilk bakış için bu adımı atlamak makuldür. Ancak bir topluluk için bu kötü bir tercihtir; çünkü giden e-posta olmadığında kimse hesabını etkinleştiremez veya parolasını sıfırlayamaz.
Pratik sorun, çoğu VPS sağlayıcısının 25 numaralı giden portu engellemesidir; bu nedenle sunucu üzerindeki standart bir posta sunucusu teslimat yapamaz. 587 numaralı port üzerinden veya örtük TLS (aktarım katmanı güvenliği) ile 465 numaralı port üzerinden kimlik doğrulamalı bir aktarıcı (relay) kullanın. 465 numaralı port için, örnek yapılandırmada bu port için önerilen DISCOURSE_SMTP_FORCE_TLS: true ayarını yapın. Yeniden oluşturma (rebuild) işleminden önce ana makineden erişilebilirliği test edin.
nc -vz smtp.example.com 587Sağlıklı bir sonuç, succeeded! ile biten tek bir satırdır. Yanıt vermeyip zaman aşımına uğrayan bir komut, portun VPS'nizden çıkış yolunda engellendiği anlamına gelir ve hiçbir Discourse ayarı bunu düzeltemez. Sağlayıcınızın izin verdiği bir porta geçin veya sağlayıcıdan portu açmasını talep edin.
Site ayağa kalktığında, Yönetim panelindeki E-posta sayfasından bir test iletisi gönderin, ardından aynı sayfadaki Atlananlar (Skipped) ve Geri Dönenler (Bounced) sekmelerini okuyun. Bu sekmeler, Discourse'un göndermeyi reddettiği veya aktarıcının geri çevirdiği postaları kaydettiği ve nedenini belirttiği yerdir; bu yöntem günlükleri okumaktan daha hızlıdır.
TLS: sertifikayı container'ın almasını sağlama
Discourse 80 ve 443 numaralı portları yönetiyorsa, kendi yerleşik sertifika oluşturma mekanizmasını kullanın. Yukarıda gösterilen iki SSL şablon satırının yorum işaretlerini kaldırın ve ardından yeniden derleme yapın. Şablon, acme.sh sürecini yönetir, sertifikaları /shared/ssl altındaki paylaşımlı birimde saklar, bunları container içinde belirli bir takvime göre yeniler ve Discourse'u HTTPS kullanmaya zorlayacak şekilde yapılandırır.
HTTP sınaması (challenge) bu port üzerinden yanıtlandığı için, bu işlemin çalışması adına 80 numaralı portun internetten erişilebilir olması gerekir. Yalnızca 443 numaralı porta izin veren bir güvenlik duvarı, derlemenin tamamlanmasına ancak sertifikanın hiçbir zaman oluşturulamamasına neden olur. Yeniden derleme işleminden hemen sonra sonucu ./launcher logs app ile kontrol edin.
Nginx veya Caddy'yi ön tarafa koymalı mısınız?
Eğer Discourse, VPS üzerindeki tek web servisi ise bunu yapmayın. Konteyner zaten optimize edilmiş bir nginx çalıştırır; ikinci bir proxy ise fazladan bir sekme, yenilenmesi gereken bir sertifika ve yeni bir başlık (header) hatası kaynağı ekler.
Aynı VPS üzerinde başka siteler de barındırıyorsa ön tarafa bir proxy koyun. Şablon listesine templates/web.socketed.template.yml ekleyin, her iki expose satırını yorum satırı haline getirin ve iki SSL şablonunu yorum satırı olarak bırakın. Bu durumda konteyner, /var/discourse/shared/standalone/nginx.http.sock adresindeki bir unix socket üzerinde dinleme yapar ve hiçbir portu işgal etmez; böylece 80 ve 443 portları kendi proxy'niz için boşa çıkar.
server {
listen 443 ssl;
server_name forum.example.com;
location / {
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}.sock sonrasındaki iki nokta üst üste işareti, nginx'in unix socket sözdiziminin bir parçasıdır ve sudo nginx -t bu işaret olmadan yapılandırmayı reddeder. X-Forwarded-Proto de isteğe bağlı değildir. Discourse mutlak bağlantılar (absolute links) yazdığı için, bu başlık olmadan HTTPS sayfasında http:// bağlantıları üretir ve tarayıcılar bunları karma içerik (mixed content) olarak engelleyerek görüntüler. Konteyner socket üzerinden bağlandığında TLS yönetimi sizin sorumluluğunuzdadır; bu nedenle sertifikayı ana makine üzerinde Ubuntu 24.04 ve nginx üzerinde Certbot kullanarak oluşturun. Henüz bir proxy seçmediyseniz, nginx, Caddy ve Traefik karşılaştırması yapacağınız tercihin getireceği sonuçları açıklar.
Yeniden oluşturmalar, yükseltmeler ve fiilen kullanacağınız komutlar
cd /var/discourse
./launcher rebuild apprebuild, çalışan container'ı yok eder, app.yml üzerinden yeni bir tane oluşturur ve başlatır. Site, oluşturma süreci boyunca çevrimdışı kalır; bu nedenle her yapılandırma değişikliğini birkaç dakikalık planlı kesinti olarak değerlendirin.
Yalnızca env: altındaki değerleri değiştirmek için bu işleme gerek yoktur. ./launcher destroy app && ./launcher start app, container'ı halihazırda oluşturduğunuz imajdan yeniden yaratır ve bu işlem saniyeler sürer. templates: veya hooks: altındaki herhangi bir değişiklik imajın kendisini etkilediği için tam bir yeniden oluşturma gerektirir.
Yükseltmeler iki şekilde gerçekleşir. Nokta sürümleri, app.yml tarafından oluşturma sırasında klonlanan docker_manager eklentisi aracılığıyla /admin/upgrade üzerindeki web arayüzünden uygulanır. Temel imaj veya şablonlardaki değişiklikler ise git üzerinden gelir.
cd /var/discourse
git pull
./launcher rebuild appVarlık derleme işlemi sistemin bellek kullanımının zirveye ulaştığı an olduğu için, küçük sunucular yeniden oluşturma sırasında başarısız olabilir. dmesg üzerinde Out of memory: Killed process gibi bir satırın göründüğü ve ruby sürecinden bahseden bir hata ile yarıda kalan bir oluşturma işlemi, site öncesinde düzgün çalışıyor olsa bile oluşturma sırasında belleğin tükendiğini gösterir. Swap alanı ekleyin ve yeniden oluşturma işlemini tekrar çalıştırın.
./launcher logs app
./launcher enter app
./launcher cleanuplogs, container'ın çıktısını yazdırır; enter, içerisinde bir kabuk (shell) açar ve cleanup, 24 saatten uzun süredir durdurulmuş olan container'ları kaldırır. Her yeniden oluşturma işlemi eski bir container'ı geride bıraktığından ve küçük bir VPS üzerindeki disk alanı sessizce tükenebileceğinden, cleanup komutunu zaman zaman çalıştırın.
Yedeklemeler ve yedeğin içermediği dosya
Yedekleri Admin panelindeki Backups sayfasından alın. Arşiv, sunucuda /var/discourse/shared/standalone/backups/default/ dizinine kaydedilir. Aynı işlem bir kabuk (shell) üzerinden de çalıştırılabilir.
cd /var/discourse
./launcher enter app
discourse backupdiscourse restore <filename> komutu işlemi tersine çevirir; discourse enable_restore komutunu çalıştırmadığınız sürece geri yükleme işlemleri reddedilir. Bu koruma, hatalı bir komutun canlı bir forumun üzerine yazmasını engellemek için mevcuttur.
Kendi başınıza kapatmanız gereken iki açık bulunmaktadır. Arşiv veritabanını içerir; yüklenen dosyaları ise yalnızca yüklemeleri dahil etme yedekleme ayarı açık olduğunda içerir, bu nedenle güvenmeden önce ilgili ayarı kontrol edin. Arşiv asla app.yml dosyasını içermez; bu nedenle yeni bir VPS üzerine yapılan geri yükleme işlemi hala hostname ve SMTP bloğunuzu gerektirir. Bu, söz konusu dosyanın da sunucudan başka bir yere kopyalanması gerektiği anlamına gelir.
Arşiv ayrıca koruduğu siteyle aynı disk üzerinde durur, bu bir yedekleme değildir. Arşivi düzenli bir zamanlamayla başka bir yere aktarın.
rsync -avz root@forum.example.com:/var/discourse/shared/standalone/backups/default/ ~/discourse-backups/Yoğun bir forumun RAM maliyeti
Bootstrap süreci, algıladığı bellek ve CPU değerlerine göre UNICORN_WORKERS ve db_shared_buffers ayarlarını yapılandırır; örnek yapılandırma dosyası ise paylaşılan arabellekleri (shared buffers) toplam belleğin dörtte biri ile sınırlar. Her bir unicorn çalışanı tam bir Ruby sürecidir ve Sidekiq arka plan işlerini bunların yanında yürütür; bu nedenle bellek kullanımı, kayıtlı üye sayısından ziyade eş zamanlı istek sayısına göre artar. Birkaç yüz üyeye sahip sakin bir forum ağır bir iş yükü oluşturmaz.
Sunucu boyutlandırmasını, bu makale de dahil olmak üzere herhangi bir yazıdaki sayıya göre yapmayın. Kendi ölçümlerinizi gerçekleştirin.
free -m
docker stats --no-streamSürekli kullanımda olan swap alanı ve yavaş sayfalar, RAM kapasitenizin yetersiz olduğu anlamına gelir. Sabit bellek kullanımı ile birlikte görülen yavaş sayfalar genellikle başka bir soruna işaret eder; bu nedenle daha yüksek bir plana geçmeden önce ./launcher logs app kısmını okuyun. Ayrıca sunucu dışından bir denetim mekanizması ekleyin; çünkü gece saat 03:00'te belleği tükenen bir forum sessizce hata verir: ayrı bir sunucuda çalışan self-hosted Uptime Kuma durum izleyicisi, üyeleriniz fark etmeden önce sizi bilgilendirir.
Discourse'un yanlış tercih olduğu durumlar
Discourse, kurulumu ağır olan ve app.yml içinde yer alan her ayar için yeniden derleme döngüsü gerektiren büyük bir uygulamadır. Bu maliyet, gerçek moderasyon araçları ve arşiv büyüdüğünde dahi çalışmaya devam eden bir arama özelliği sağlar. Konuşacak bir yere ihtiyaç duyan otuz kişilik bir grup için bu, sohbetin gerektirdiğinden çok daha fazla kaynak tüketen bir yapıdır. Öncelikle kendi kendine barındırılan forum yazılımlarının karşılaştırmasını okuyun ve Discourse'u sadece bildiğiniz bir isim olduğu için değil, sunduğu özelliklere ihtiyaç duyduğunuz için seçin.
FAQ
Discourse'u alan adı olmadan bir VPS üzerine kurabilir miyim?
Hayır. Dağıtılan yapılandırma, Discourse'un salt IP adresiyle çalışmayacağını belirtir ve DISCOURSE_HOSTNAME gereklidir. Discourse, mutlak bağlantıları bu ana bilgisayar adından oluşturur; bu nedenle orada bir IP adresi kullanmak bağlantıları bozar ve sertifika düzenlenmesini engeller. Başlamadan önce bir A kaydı oluşturun ve dig +short forum.example.com ile bu kaydın sunucunuzun adresine çözümlendiğini doğrulayın.
Kurulumu tamamlamak için SMTP yapılandırmam gerekiyor mu?
Ağustos 2026 itibarıyla bu adımı atlayabilirsiniz. Kurulum sihirbazı bunun yerine Discourse ID ile giriş seçeneği sunar ve app.yml, e-posta kurulum doğrulamasını atlayan bir anahtar içerir. İlk incelemenin ötesindeki her kullanım için SMTP yapılandırılmalıdır; çünkü hesap aktivasyonu ve parola sıfırlama işlemleri e-posta yoluyla gerçekleştirilir. Çoğu VPS sağlayıcısı 25 numaralı porttan giden trafiği engellediğinden, 587 veya 465 numaralı portlar üzerinden kimlik doğrulamalı bir aktarıcı (relay) kullanın.
Discourse yeniden oluşturma (rebuild) işlemim neden yarıda kesildi?
Genel neden bellek yetersizliğidir. Derleme sırasındaki varlık derleme (asset compilation) işlemi, çalışan siteden daha fazla bellek gerektirir; bu nedenle forumu sorunsuz çalıştıran bir sunucu, yeniden oluşturma sırasında başarısız olabilir. Eğer dmesg, Out of memory: Killed process içerisinde bir ruby sürecini işaret ediyorsa, swap alanı ekleyin (sihirbazın kendi swap dosyası 2 GB'tır) ve ./launcher rebuild app komutunu tekrar çalıştırın. YAML hatasında duran bir derleme ise app.yml dosyasındaki bir girinti hatasına işaret eder.
Discourse kendi nginx veya Caddy sunucumun arkasında mı çalışmalı?
Yalnızca VPS üzerinde başka siteler de barındırılıyorsa bu yöntem tercih edilmelidir. Sunucuda tek başına çalışıyorsa, container'ın 80 ve 443 numaralı portları tutmasına ve kendi sertifikasını düzenlemesine izin verin; bu, daha az hareketli parça anlamına gelir. Makineyi paylaşmak için templates/web.socketed.template.yml ekleyin, expose satırlarını yorum satırı yapın ve /var/discourse/shared/standalone/nginx.http.sock adresindeki unix soketine proxy yapın. X-Forwarded-Proto başlığını iletin, aksi takdirde Discourse, HTTPS sayfası üzerinde http:// bağlantıları üretir.
Kendi barındırdığım Discourse'un yedeğini nasıl alırım?
Yönetim panelindeki Yedekler (Backups) sayfasını kullanın veya ./launcher enter app komutundan sonra discourse backup komutunu çalıştırın. Arşivler ana makinede /var/discourse/shared/standalone/backups/default/ dizinine kaydedilir. Yüklemeleri içeren ayarın açık olduğundan emin olun, /var/discourse/containers/app.yml dosyasını arşivle birlikte kopyalayın ve her ikisini de başka bir makineye taşıyın; çünkü siteyle aynı diskte bulunan bir yedek, varlık sebebi olan disk arızasında hayatta kalamaz.