TurkNET Forum, Discourse Migration Azure

Vahit Ustaoğlu
TurkNetDevOps
Published in
6 min readOct 10, 2022

Herkese merhabalar bu yazımda TurkNet olarak müşterilerimizle interaktif bir ortamda iletişim kurmaktan keyif aldığımız ve onları dinlediğimiz forum.turk.net platformunu nasıl Discourse sunucuları üzerinden, kendi Azure Cloud ortamımıza taşıdığımızı, taşıma sürecinde ne gibi engellerle karşılaştığımızı ve çözümleri nasıl uyguladığımızı göstermeye çalışacağım.

Eğer sizler de Discourse altyapısı ile çalışan bir forum sistemine sahipseniz ve platformunuzu taşımak istiyorsanız bu yazıyı takip edebilirsiniz.

İlk Deneme: Bitnami Azure Single-Tier App

Öncelikle direkt Azure üzerinde Bitnami Single-Tier Discourse application olarak kurulum seçeneği ile ilerlediğimizde çok hızlı şekilde discourse’u ayağa kaldırdık. Ancak backup/restore ile discourse’u taşımak istediğimizde karşılaşılan senaryo şaşırtıcı oldu çünkü Bitnami imajı 2.8.9 stable sürümde iken Discourse Cloud üzerinde çalışan uygulamamız 2.9.beta9 olarak görünüyordu. Bu sebeple upgrade ve downgrade işlemleri de mümkün olmadığından backup/restore aşamasında alınan versiyon uyumsuzluğu hatası ile bu yol tıkandı.

Bitnami Discourse Image

Discourse versiyonu ilginç şekilde herhangi bir panel yerine frontend kodunda yazılıyor sayfayı incele denildiğinde CTRL+F ile “version” aratarak görülebilir.

Discourse Version Check

Bu yola geri döneceğiz ancak kullanımda olan sürümümüz 2.9.beta’dan 2.9 stable sürüme geçip Bitnami ile ortak bir versiyonda buluşana kadar Azure Container Service ya da Azure VM üzerinde Discourse’u geçici olarak barındırmaya karar verdik. Sürümler aynı noktada birleştiğinde tekrar bir taşıma işlemi ile Azure Single-Tier Application olarak barındırmayı hedefliyoruz.

İkinci Deneme: Azure Container Service

Azure üzerinde docker ayağa kaldırarak discourse imajını çalıştırmak istediğimizde yine bir sorun vardı çünkü discourse kendi scriptleri ile işi ilerletmemize izin veriyordu. Docker dışında çalıştırılması gereken scripler ile (ör: ./launcher rebuild app) direkt docker içinde çalışamadığımız için bu yöntem de discourse için çalışmayacaktı.

Başarılı Yöntem: Azure Ubuntu VM

Öncelikle taşıma işlemi için yol haritamızı kısaca belirledik.

1- Domain TTL süresinin kısaltılması (15dk olarak belirlenebilir, bu sayede taşıma işlemi tamamlandığında DNS sunucularının uzun bir süre daha discourse cloud sunucularının IP’lerini göstermesinin- Biz yeni dükkana taşınmışken navigasyonun müşterileri eski boş dükkana götürmesini istemeyiz:) — önüne geçeceğiz.)

2- Azure Cloud üzerinde 80 ve 443 portları açık olacak şekilde(Azure Firewall üzerinde) Ubuntu işletim sistemine sahip, ihtiyacınız olacak CPU/RAM kaynağına sahip sanal makinenin oluşturulması.

3- SSL için .crt ve .key dosyalarının ayrıca SMTP için servis sağlayıcının kullanıcı adı/şifre bilgilerinin ve notify mail adresinin temin edilmesi.

4- DNS A Kaydı kurulum aşamalarının stabil tamamlanabildiğinin test edilebilmesi için DNS A kaydı oluşturulmuş geçici bir domain temin edilmesi. Discourse kurulum esnasında çalışan bir domain istemekte, aksi halde kurulum başlamamaktadır. Geçici domain için https://freenom.com’u kullanabilirsiniz.

5- Mevcut discourse üzerinde çalışan pluginlerin, discourse admin panel üzerinden github adreslerinin alınması.

6- Yeni sunucuya Discourse yazılımının indirilip, kurulum, SSL, SMTP yapılandırmalarının tamamlanması.

7- Çalışan discourse üzerinden admin paneli üzerinden backup alınarak yeni ortama yüklenmesi ile yeni ortamın stabilitesinin test edilmesi.

8- Elimizde çalışan yeni ortam olduğundan emin olduğumuz anda mevcut discourse ortamımızda, kullanıcılara taşıma işleminin zaman aralığını önceden belirteceğimiz bir mesaj yazılması.

9- Çalışan discourse’un bakım moduna alınması, yeni taşıma öncesi son backup alınması ve yeni discourse üzerine restore edilmesi.

10- Restore işlemi tamamlandığında yeni discourse ortamı otomatik olarak maintenance modundan çıkmış olarak hizmete hazır hale gelmektedir.

Discourse Yükleme ve Yapılandırma

Yeni oluşturulan linux server üzerinde aşağıdaki komutlar ile discourse kurulum dosyaları klon edilir ve dosya sahiplik ayarları kuruluma uygun hale getirilir.

sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
chmod 700 containers

Gerekli Firewall izinleri olarak http, https, ssh portlarına izin verilir. Ubuntu için örnek komutlar aşağıda verilmiştir.

ufw status
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 22/tcp
ufw enable -y
ufw reload
ufw status

Sonraki bütün çalışma /var/discourse içerisinde yapılacaktır. Docker kurulum ve yapılandırması dahil gerekli kurulum ve bakım scriptleri bu klasör içerisinde hazır gelmekte ve direkt docker ile müdahale edilmemesi önerilmektedir.

/var/discourse/
├── LICENSE
├── README.md
├── bin
├── cids
├── containers # app.yml dosyası discourse kurulum ayarlarını içerir.
├── discourse-doctor # discourse-setup'a benzer ancak debug imkanı verir.
├── discourse-setup # docker da dahil discourse yükleme scripti
├── image
├── launcher # ./launcher ile tüm parametreleri görüntülenebilir app instance yönetim scripti.
├── samples # samples/standalone.yml örnek app.yml dosyası
├── scripts
├── shared # shared/standalone/ssl içerisine ssl .crt ve .key dosyaları atılmalıdır
├── templates # app.yml'a include edilecek SSL vb yapılandırmalar için template dosyaları
└── tests

Setup scripti aşağıdaki gibi çalıştırıldığında DNS A Kaydı oluşturulmuş domain, smtp yapılandırma ayarları, notify-email adresi, ssl .crt ve .key dosyaları hazır olmalı ve scriptin yönlendirmesi ile doğru şekilde app config(/var/discourse/container/app.yml) içerisine dahil edilmelidir.

SSL Yapılandırması

Öncelikle app.yml içerisinde uncomment edilmeli -> template/web.ssl.template.yml

SSL PATH: /var/discourse/shared/standalone/ssl yoluna .crt ve .key dosyaları atılmalı ve template/web.ssl.template.yml içerisinde ilgili alanda dosya isimleri belirtilmelidir.

443 portu üzerinden erişim sağlanamazsa hata ssl üzerinde ya da firewall üzerinde incelenmelidir.

SMTP Yapılandırması

app.yml dosyası içerisinde ya da ./discourse-setup scripti ile kurulum sırasında username ve password bilgileri verilmelidir.

Not: Eğer SendGrid ya da benzeri bir mail sağlayıcı ile entegre etmek istiyorsanız user:apikey pass:[apikey değeri] şeklinde belirtilmelidir.Bazı cloud sağlayıcıları 587 portunu engellemektedir bu durumla karşılaşılırsa SendGrid için 2525 denenebilir.

user: apikey

pass: “SG.GihDENEME8uIO1AAAaaa1.33….”

port: 587

./discourse-setup

Setup çalışmazsa sonrasında discourse-doctor aşağıdaki şekilde çalıştırılabilir ve yarım kalan kurulum debug edilebilir.

./discourse-doctor

Yukarıda belirtilen komutlar docker’ı yükleyecek discourse-base container imajı docker hub üzerinden çekecek ve verilen domain, smtp, ssl configleri ile bir build/deploy oluşturacaktır.

Not: Domain ismi erişilebilir olmalıdır yoksa discourse’a erişilemez geçici bir domain yönlendirmesi ya da hosts dosyası üzerinde bir düzenleme ile bu engel kurulum aşaması için aşılabilir.

Not2: Notify mail çalışır durumda olmalı yoksa ilk login anında aktivasyon maili gönderilemez ve discourse admin paneline login olunamaz.

Pluginler app.yml’a yukarıda ki örnekte ki şekilde eklendikten sonra ./launcher rebuild app komutu ile sisteme dahil edilir. Debug etmek istendiğinde docker exec -it /bin/bash ile ya da ./launcher enter app container shell açılarak ./launcher enter app ardından cd /var/www/discourse/plugins yolu altında başarılılı yüklenen pluginler görüntülenebilir.

Plugin yukarıda gösterildiği şekilde app.yml dosyasına eklenip ./launcher rebuild app komutu verildiğinde hata alınır ve docker ps -a ile containerın exited durumda olduğu görülürse, rebuild anındaki ekran akışında aşağıdaki resimde görüldüğü gibi hangi pluginden ne sebeple bir hata alındığı kontrol edilir ve debug edilir ya da plugin app.yml satırından kaldırılır.

Daha önce yüklenmiş bir plugin tekrar yüklenmeye çalışıldığında alınan hata örneği

Discourse containerın loglarının izlenebilmesi için ./launcher logs app komutu kullanılabilir.

Restore Backup Aşaması

Ardından yeni sunucu üzerinde forum kurulumu hazır şekilde yedeğin yüklenmesini bekler durumdayken, sonlandırılacak sunucuda sırasıyla aşağıda gösterildiği şekilde forumda read-only(bakım modu) aktif edilir, yedek oluşturulur ve yedek indirilir.

Discourse admin paneli backup/restore ekranı

Yeni sunucu üzerinde ilk web tarayıcı üzerinden oluşturulan admin kullanıcısı ile yönetici ekranına geçilerek mavi ile yazılan alana tıklanıp aşağıdaki sayfa açılarak geri yüklemeye izin verilir.

Discourse admin paneli genel ayarlar ekranı

Ardından tekrar yukarıda gösterilen yedekler sayfasına gidilerek eski sunucu üzerinden alınan yedek yeni sunucu üzerine yüklenir ve bir süre sonra liste üzerinde görünür olduğunda geri yükle seçeneği ile geri yüklenir.

Önemli Not:Bu işlem sonucunda yeni oluşturulan discourse kullanıcıları silinecek ve mevcut discourse kullanıcıları restore edileceği için yeni kurulum yapıldığında oluşturulan admin kullanıcısı yok olur ve eski discourse üzerindeki admin kullanıcı bilgileri ile giriş yapılabilir.

İşlemlerin tamamlanmasının ardından domain yeni sunucuya yönlendirilir. DNS TTL süresinden biraz daha sonra oturunca TTL süresi tekrar uzatılabilir.

Not: LoadBalancer kullanılacaksa LB üzerinde yapılandırmalar tamamlandıktan sonra domain LB üzerine A kaydı olarak yönlendirilmelidir.

Not2: LoadBalancer kullanılması durumunda kullanıcı IP lerinin tümü Discourse’a LoadBalancer IP’si şeklinde yansıyacak ve kullanıcı yönetimi, kullanıcı loglama ve engelleme gibi operasyonları engelleyecektir. Bu durumun yaşanmaması için yukarıda tüm örneği verilen app.yml dosyasının en altındaki replace komutu son satıra kadar olan kısmı ile eklenmeli ve kullanıcıların gerçek IP’lerinin Discourse üzerine yansıması sağlanmalıdır.

- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: "types {"
to: |
set_real_ip_from 172.173.174.175; # Buraya LB IP yazılmalı
real_ip_header X-Forwarded-For;
real_ip_recursive on;
types {

Not3: Taşıma öncesi kullanıcıların yükledikleri görseller Discourse CDN üzerinden gelmeye devam ediyorsa görsellerin URL pathlerini origin üzerinden gelecek şekilde ayarlamak gerecektir bunun için aşağıdaki kod çalıştırılabilir.

# ssh into server
cd /var/discourse
./launcher enter app
rake posts:rebake

Değerli yorumlarınızı ve varsa hatalar konusunda paylaşmak istediğiniz kısımları yorum olarak belirtebilirsiniz hepinize teşekkür eder kolaylıklar dilerim. :)

--

--