Clojure Web Uygulamasını Ubuntu 14.04 Üzerine Dağıtma Rehberi
Giriş
Modern web uygulaması geliştirme dünyasında, performans, eşzamanlılık ve güvenilirlik giderek daha kritik hale gelmektedir. Bu bağlamda, JVM üzerinde çalışan, fonksiyonel bir dil olan Clojure, geliştiricilere benzersiz avantajlar sunar. Clojure’ın sağlam ekosistemi, Java kütüphaneleriyle sorunsuz entegrasyonu ve eşzamanlılık için tasarlanmış yapısı, onu yüksek performanslı ve ölçeklenebilir web uygulamaları geliştirmek için ideal bir seçenek haline getirir. Öte yandan, Ubuntu, özellikle 14.04 LTS (Uzun Süreli Destek) sürümü, sunucu ortamlarında yıllarca istikrarlı ve güvenilir bir platform olarak kendini kanıtlamıştır. Bu makale, bir Clojure web uygulamasını Ubuntu 14.04 sunucusu üzerine başarılı bir şekilde dağıtmak için adım adım kapsamlı bir rehber sunmaktadır. Her ne kadar Ubuntu’nun daha yeni sürümleri mevcut olsa da, birçok kurumsal ortamda veya belirli projelerde 14.04’ün hala kullanıldığı göz önüne alındığında, bu rehberin pratik değeri devam etmektedir. Amacımız, geliştirme ortamından canlı sunucuya geçiş sürecini mümkün olduğunca sorunsuz hale getirmektir.
Ön Gereksinimler ve Ortam Kurulumu
Clojure web uygulamanızı dağıtmaya başlamadan önce, Ubuntu 14.04 sunucunuzda bazı temel araçların ve bileşenlerin kurulu olması gerekmektedir. Bu bölümde, gerekli tüm ön gereksinimleri ve bunların nasıl kurulacağını ele alacağız.
Ubuntu 14.04 Sunucusu
Öncelikle, SSH erişimi olan bir Ubuntu 14.04 sunucusuna ihtiyacınız var. Sunucunuzun temel kurulumunun tamamlandığını ve root veya sudo yetkilerine sahip bir kullanıcıyla erişebildiğinizi varsayıyoruz. Sunucuya SSH ile bağlanarak başlayın:
ssh kullanici_adi@sunucu_ip_adresi
Tüm paket listelerini güncelleyerek başlayın:
sudo apt-get update
sudo apt-get upgrade -y
Java Geliştirme Kiti (JDK)
Clojure, JVM üzerinde çalıştığı için bir Java Geliştirme Kiti’ne (JDK) ihtiyaç duyar. OpenJDK, Ubuntu üzerinde en yaygın ve önerilen seçenektir.
sudo apt-get install openjdk-7-jdk -y
Kurulumdan sonra Java sürümünü kontrol ederek doğruluğunu teyit edebilirsiniz:
java -version
javac -version
Leiningen
Leiningen, Clojure projeleri için bir derleme otomasyonu ve bağımlılık yönetim aracıdır. Uygulamanızı paketlemek ve çalıştırmak için Leiningen’e ihtiyacımız olacak.
Leiningen’i indirip çalıştırılabilir hale getirmek için aşağıdaki adımları izleyin:
wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
sudo mv lein /usr/local/bin/
sudo chmod +x /usr/local/bin/lein
İlk kez çalıştırdığınızda, Leiningen kendisini kuracaktır. Bu biraz zaman alabilir:
lein
Sürümü kontrol ederek kurulumu doğrulayın:
lein version
Git
Uygulamanızın kaynak kodunu sunucuya çekmek için Git’e ihtiyacınız olacak.
sudo apt-get install git -y
Nginx
Nginx, web uygulamanız için bir ters proxy ve statik dosya sunucusu olarak görev yapacaktır. Gelen HTTP isteklerini Clojure uygulamanıza yönlendirecek ve performansı artıracaktır.
sudo apt-get install nginx -y
Nginx’in çalışıp çalışmadığını kontrol edin:
sudo service nginx status
PostgreSQL veya MySQL (İsteğe Bağlı)
Uygulamanız bir veritabanı kullanıyorsa, ilgili veritabanı sunucusunu kurmanız gerekecektir. Bu örnekte PostgreSQL’i ele alalım:
sudo apt-get install postgresql postgresql-contrib -y
PostgreSQL kurulumundan sonra, varsayılan postgres kullanıcısı için bir parola belirlemek iyi bir uygulamadır:
sudo -u postgres psql
ALTER USER postgres WITH PASSWORD 'sifreniz';
\q
Ardından, uygulamanız için yeni bir veritabanı ve kullanıcı oluşturabilirsiniz:
sudo -u postgres psql
CREATE DATABASE myapp_db;
CREATE USER myapp_user WITH PASSWORD 'myapp_sifresi';
GRANT ALL PRIVILEGES ON DATABASE myapp_db TO myapp_user;
\q
Clojure Web Uygulaması Hazırlığı
Dağıtıma başlamadan önce, Clojure web uygulamanızın dağıtıma hazır olduğundan emin olmalısınız. Bu bölüm, bir Clojure uygulamasının dağıtım için nasıl hazırlanacağını anlatır.
Örnek Clojure Uygulaması
Basit bir Clojure web uygulaması, genellikle Ring ve Compojure (veya Reitit gibi başka bir yönlendirici) kullanır. Örnek olarak, my-clojure-app adında bir uygulama oluşturalım:
lein new compojure my-clojure-app
cd my-clojure-app
src/my_clojure_app/handler.clj dosyanızda basit bir rota tanımlayabilirsiniz:
(ns my-clojure-app.handler
(:require [compojure.core :refer :all]
[compojure.route :as route]
[ring.middleware.defaults :refer [wrap-defaults site-defaults]]))
(defroutes app-routes
(GET "/" [] "Merhaba Clojure Uygulaması!")
(route/not-found "Sayfa Bulunamadı"))
(def app
(wrap-defaults app-routes site-defaults))
project.clj dosyanızda, uygulamanızın ana sınıfını ve bağımlılıklarını belirtmeniz gerekir. Varsayılan olarak Leiningen, my-clojure-app.handler/app fonksiyonunu Ring uygulaması olarak kullanır. Uygulamanızın belirli bir portta çalışmasını sağlamak için project.clj dosyanıza profiles bölümü ekleyebilirsiniz:
(defproject my-clojure-app "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:min-lein-version "2.0.0"
:dependencies [[org.clojure/clojure "1.8.0"]
[compojure "1.5.1"]
[ring/ring-defaults "0.2.0"]
[ring/ring-jetty-adapter "1.5.0"]] ; Jetty web sunucusunu ekleyin
:plugins [[lein-ring "0.9.7"]]
:ring {:handler my-clojure-app.handler/app
:init my-clojure-app.handler/init
:destroy my-clojure-app.handler/destroy}
:profiles
{:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
[ring/ring-mock "0.3.0"]]}
:uberjar {:aot :all
:main my-clojure-app.server ; Eğer uberjar ile çalıştırmak istiyorsanız
:omit-source true}})
Eğer uberjar kullanarak doğrudan bir JAR dosyası çalıştırmak istiyorsanız, uygulamanızı bir Jetty sunucusu üzerinde başlatacak bir my-clojure-app.server namespace’i oluşturmanız gerekir:
;; src/my_clojure_app/server.clj
(ns my-clojure-app.server
(:require [ring.adapter.jetty :refer [run-jetty]]
[my-clojure-app.handler :refer [app]])
(:gen-class))
(defn -main
[& args]
(let [port (Integer/parseInt (or (System/getenv "PORT") "3000"))]
(println (str "Sunucu " port " portunda başlatılıyor."))
(run-jetty app {:port port :join? false})))
Bu, uygulamanızı java -jar komutuyla çalıştırırken varsayılan olarak 3000 portunu kullanmasını sağlar. Portu bir ortam değişkeni (PORT) aracılığıyla yapılandırabilirsiniz.
Uygulamanın Yerel Ortamda Test Edilmesi
Dağıtımdan önce uygulamanızın yerel olarak doğru çalıştığından emin olun:
lein ring server
Tarayıcınızda http://localhost:3000 adresine giderek “Merhaba Clojure Uygulaması!” mesajını görmelisiniz.
Uygulamanın JAR Olarak Paketlenmesi
Canlı sunucuda çalıştırılmak üzere, Clojure uygulamanızı tek bir çalıştırılabilir JAR dosyası (uberjar) olarak paketlemek en yaygın yöntemdir. Bu JAR dosyası, tüm bağımlılıkları içerir ve harici bir Leiningen kurulumuna ihtiyaç duymaz.
lein uberjar
Bu komut, target/uberjar dizini altında my-clojure-app-0.1.0-SNAPSHOT-standalone.jar gibi bir dosya oluşturacaktır.
Ortam Değişkenleri Yönetimi
Veritabanı bağlantı bilgileri, API anahtarları gibi hassas veya ortama özel ayarların doğrudan kodda tutulmaması önemlidir. Bunun yerine, ortam değişkenleri veya yapılandırma dosyaları kullanmalısınız. Uygulamanızda bu değerleri System/getenv ile okuyabilirsiniz.
(System/getenv "DATABASE_URL")
Sunucuya Dağıtım Adımları
Uygulamanız hazır olduğuna göre, şimdi onu Ubuntu 14.04 sunucunuza dağıtabiliriz.
Kullanıcı Oluşturma ve Yetkilendirme
Güvenlik amacıyla, uygulamanızı root kullanıcısı yerine ayrı, yetkileri kısıtlanmış bir kullanıcı altında çalıştırmak her zaman iyi bir uygulamadır. deployer adında bir kullanıcı oluşturalım:
sudo adduser deployer
Bu kullanıcıya sudo yetkisi vermek isteyebilirsiniz, ancak uygulamanın kendisi sudo ile çalışmamalıdır.
Uygulama Dosyalarını Sunucuya Aktarma
Oluşturduğunuz uberjar dosyasını sunucuya aktarmanın birkaç yolu vardır. En yaygın olanı scp veya Git kullanmaktır.
SCP ile: Yerel makinenizden sunucuya kopyalayın:
scp target/uberjar/my-clojure-app-0.1.0-SNAPSHOT-standalone.jar deployer@sunucu_ip_adresi:/home/deployer/my-clojure-app.jar
Git ile: Eğer uygulamanız bir Git deposundaysa, sunucuda depoyu klonlayabilir ve orada uberjar oluşturabilirsiniz:
sudo mkdir -p /opt/my-clojure-app
sudo chown deployer:deployer /opt/my-clojure-app
su - deployer
cd /opt/my-clojure-app
git clone https://github.com/kullaniciadi/my-clojure-app.git .
lein uberjar
Uygulamanızı /opt/my-clojure-app gibi standart bir dizine yerleştirmek iyi bir uygulamadır.
Veritabanı Kurulumu ve Yapılandırması
Eğer uygulamanız bir veritabanı kullanıyorsa, sunucuda veritabanı şemasını oluşturmanız ve başlangıç verilerini yüklemeniz gerekebilir. PostgreSQL için:
sudo -u postgres psql -d myapp_db -f /opt/my-clojure-app/db/schema.sql
Uygulamanızın veritabanı bağlantı bilgilerini ortam değişkenleri aracılığıyla veya bir yapılandırma dosyası aracılığıyla sağlamayı unutmayın.
Uygulamanın Servis Olarak Çalıştırılması (Upstart)
Ubuntu 14.04, sistem servislerini yönetmek için Upstart kullanır. Uygulamanızın sunucu yeniden başlatıldığında otomatik olarak başlaması ve arka planda sürekli çalışması için bir Upstart yapılandırma dosyası oluşturacağız.
/etc/init/my-clojure-app.conf adında bir dosya oluşturun ve içine aşağıdaki içeriği ekleyin:
description "Clojure Web Uygulaması"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5 ; 5 saniyede 10 kez yeniden başlatılırsa durur
setuid deployer
setgid deployer
env PORT=3000
env DATABASE_URL="jdbc:postgresql://localhost:5432/myapp_db?user=myapp_user&password=myapp_sifresi"
exec java -jar /opt/my-clojure-app/target/uberjar/my-clojure-app-0.1.0-SNAPSHOT-standalone.jar
Açıklamalar:
description: Servisin kısa açıklaması.start onvestop on: Servisin hangi runlevel’larda başlayıp duracağını belirtir.respawn: Servis beklenmedik bir şekilde durursa otomatik olarak yeniden başlatılır.setuidvesetgid: Servisi çalıştıracak kullanıcı ve grup. Bu, uygulamanındeployerkullanıcısının yetkileriyle çalışmasını sağlar.env: Ortam değişkenlerini ayarlar. Uygulamanızın ihtiyaç duyduğu tüm ortam değişkenlerini buraya eklemelisiniz.exec: Çalıştırılacak komut. Bu, oluşturduğumuz uberjar dosyasını başlatır.
Yapılandırma dosyasını kaydettikten sonra, servisi başlatın:
sudo service my-clojure-app start
Servisin durumunu kontrol edin:
sudo service my-clojure-app status
Logları kontrol etmek için:
sudo tail -f /var/log/upstart/my-clojure-app.log
Eğer bir değişiklik yaparsanız, servisi yeniden başlatmanız gerekir:
sudo service my-clojure-app restart
Nginx ile Ters Proxy Kurulumu
Uygulamamız artık arka planda çalışıyor, ancak doğrudan 3000 portundan erişilebilir durumda. Nginx’i kullanarak bu erişimi daha güvenli ve yönetilebilir hale getireceğiz. Nginx, gelen HTTP/HTTPS isteklerini Clojure uygulamamıza yönlendirecek ve statik dosyaları (CSS, JS, resimler) doğrudan sunarak performansı artıracaktır.
Nginx Yapılandırma Dosyası Oluşturma
Uygulamanız için yeni bir Nginx sunucu bloğu yapılandırma dosyası oluşturun:
sudo nano /etc/nginx/sites-available/my-clojure-app
İçeriği aşağıdaki gibi doldurun (alan adınızı ve sunucu IP’nizi güncellemeyi unutmayın):
server {
listen 80;
server_name www.alanadiniz.com alanadiniz.com; # Alan adınızı buraya yazın
# Clojure uygulamasına yönlendirme
location / {
proxy_pass http://localhost:3000; # Uygulamanızın çalıştığı port
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $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 $scheme;
proxy_cache_bypass $http_upgrade;
}
# Statik dosyaları doğrudan sunma (isteğe bağlı)
# Eğer uygulamanız statik dosyalar içeriyorsa ve Nginx'in bunları sunmasını istiyorsanız
# bu bölümü kullanabilirsiniz. Örneğin: /opt/my-clojure-app/public
# location ~* ^/(img|js|css|fonts|robots.txt|favicon.ico) {
# root /opt/my-clojure-app/public; # Statik dosyalarınızın yolu
# expires 30d;
# add_header Cache-Control "public, no-transform";
# }
error_log /var/log/nginx/my-clojure-app_error.log;
access_log /var/log/nginx/my-clojure-app_access.log;
}
Yapılandırmayı Etkinleştirme
Oluşturduğunuz yapılandırma dosyasını sites-enabled dizinine bağlayarak etkinleştirin:
sudo ln -s /etc/nginx/sites-available/my-clojure-app /etc/nginx/sites-enabled/
Varsayılan Nginx yapılandırmasını devre dışı bırakmak isteyebilirsiniz:
sudo rm /etc/nginx/sites-enabled/default
Nginx yapılandırmasının sözdizimini kontrol edin:
sudo nginx -t
Her şey yolundaysa, Nginx’i yeniden başlatın:
sudo service nginx restart
Artık tarayıcınızdan http://alanadiniz.com adresine gittiğinizde Clojure uygulamanızın yanıtını görmelisiniz.
SSL/TLS Yapılandırması (Önerilir)
Canlı bir uygulama için HTTPS kullanmak kritik öneme sahiptir. Let’s Encrypt, ücretsiz SSL sertifikaları sağlar ve Certbot aracıyla kolayca kurulabilir. Ubuntu 14.04 için Certbot kurulumu biraz farklı olabilir.
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx -y
Ardından, sertifikayı almak ve Nginx’i yapılandırmak için Certbot’u çalıştırın:
sudo certbot --nginx -d alanadiniz.com -d www.alanadiniz.com
Certbot, Nginx yapılandırmanızı otomatik olarak güncelleyecek ve HTTPS’yi etkinleştirecektir.
Güvenlik ve Optimizasyon İpuçları
Uygulamanızı canlıya aldıktan sonra, güvenlik ve performansını artırmak için bazı ek adımlar atmanız önemlidir.
Güvenlik Duvarı (UFW)
Ubuntu’da UFW (Uncomplicated Firewall) kullanarak sunucunuza gelen trafiği kontrol edebilirsiniz. Yalnızca gerekli portları açın.
sudo ufw enable
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw status
Eğer veritabanına dışarıdan erişim gerekiyorsa (genellikle önerilmez), ilgili portu da açmanız gerekir (örneğin PostgreSQL için 5432).
SSH Güvenliği
- Anahtar Tabanlı Kimlik Doğrulama: Parola ile giriş yerine SSH anahtarları kullanın.
- Root Erişimi Kapatma:
sshd_configdosyasındaPermitRootLogin noolarak ayarlayın. - Varsayılan SSH Portunu Değiştirme:
Port 22yerine farklı bir port kullanın.
sudo nano /etc/ssh/sshd_config
sudo service ssh restart
Log Yönetimi
Uygulamanızın ve Nginx’in log dosyaları zamanla büyüyebilir. logrotate kullanarak bu logları otomatik olarak sıkıştırıp arşivleyebilirsiniz.
Nginx ve Upstart zaten logrotate tarafından yönetilir, ancak Clojure uygulamanızın kendi logları varsa, bunlar için özel bir yapılandırma eklemeniz gerekebilir.
Performans İzleme
JVM tabanlı uygulamalar için JMX metriklerini izlemek, performansı anlamak için faydalıdır. Prometheus ve Grafana gibi araçlar, bu metrikleri görselleştirmek için kullanılabilir.
JVM bellek ayarlarını optimize etmek de önemlidir. Upstart yapılandırmanızdaki exec satırına JVM argümanları ekleyebilirsiniz:
exec java -Xmx512m -Xms256m -jar /opt/my-clojure-app/target/uberjar/my-clojure-app-0.1.0-SNAPSHOT-standalone.jar
-Xmx maksimum heap boyutunu, -Xms başlangıç heap boyutunu ayarlar.
Yedekleme Stratejileri
Veritabanınızın ve uygulama dosyalarınızın düzenli yedeklerini almayı unutmayın. pg_dump (PostgreSQL için) gibi araçlar veritabanı yedeklemeleri için kullanılabilir.
Otomatik Dağıtım (CI/CD)
Uygulamanız büyüdükçe, manuel dağıtım süreçleri hantal hale gelebilir. Jenkins, GitLab CI, CircleCI gibi CI/CD araçları kullanarak test, derleme ve dağıtım süreçlerini otomatikleştirebilirsiniz.
Sıkça Sorulan Sorular ve Sorun Giderme
Uygulama Başlamıyor veya Hata Veriyor
- Upstart Loglarını Kontrol Edin:
/var/log/upstart/my-clojure-app.logdosyasında hata mesajlarını arayın. - Ortam Değişkenlerini Doğrulayın: Uygulamanızın ihtiyaç duyduğu tüm ortam değişkenlerinin (PORT, DATABASE_URL vb.) Upstart yapılandırma dosyasında doğru ayarlandığından emin olun.
- JVM Bellek Sorunları: Uygulamanız yeterli belleğe sahip olmayabilir. Upstart yapılandırmanızdaki
java -jarkomutuna-Xmxve-Xmsparametrelerini ekleyerek JVM bellek ayarlarını artırmayı deneyin. - Dosya Yolları:
execkomutundaki JAR dosyasının yolunun doğru olduğundan emin olun.
Nginx 502 Bad Gateway Hatası
Bu hata genellikle Nginx’in Clojure uygulamanızla bağlantı kuramadığı anlamına gelir.
- Clojure Uygulamasının Çalıştığından Emin Olun:
sudo service my-clojure-app statuskomutuyla uygulamanızın çalıştığını kontrol edin. - Port Doğruluğu: Nginx yapılandırmasındaki
proxy_passadresinin (http://localhost:3000) uygulamanızın dinlediği portla eşleştiğinden emin olun. - Nginx Hata Logları:
/var/log/nginx/error.logdosyasını kontrol edin.
Veritabanı Bağlantı Sorunları
- Bağlantı Dizisi (Connection String): Uygulamanızın kullandığı veritabanı bağlantı dizisinin (örneğin
DATABASE_URLortam değişkeni) doğru olduğundan emin olun. Kullanıcı adı, parola, veritabanı adı ve host bilgilerini kontrol edin. - Veritabanı Servisi: Veritabanı sunucusunun (PostgreSQL) çalıştığından emin olun:
sudo service postgresql status. - Güvenlik Duvarı: Eğer veritabanı farklı bir sunucudaysa, veritabanı sunucusunun güvenlik duvarının Clojure uygulamanızın sunucusundan gelen bağlantılara izin verdiğinden emin olun.
Uygulama Performansı Düşük
- JVM Ayarları: Özellikle
-Xmxve-Xmsparametreleri olmak üzere JVM bellek ayarlarını optimize edin. - Veritabanı İndeksleri: Veritabanı sorgularınızın yavaş çalışıp çalışmadığını kontrol edin. Gerekli tablolara indeksler ekleyin.
- Nginx Caching: Statik dosyalar için Nginx önbelleklemesini etkinleştirin.
- Kod Optimizasyonu: Clojure kodunuzdaki performans darboğazlarını profilleyici araçlarla tespit edin ve optimize edin.
Sonuç
Bu kapsamlı rehber, bir Clojure web uygulamasını Ubuntu 14.04 sunucusu üzerine dağıtmanın tüm temel adımlarını detaylandırmıştır. Ön gereksinimlerin kurulumundan, Clojure uygulamasının paketlenmesine, Upstart ile servis olarak çalıştırılmasına ve Nginx ile ters proxy yapılandırmasına kadar her aşamayı ele aldık. Ayrıca, güvenlik, optimizasyon ve sorun giderme konularına da değinerek uygulamanızın canlı ortamda sağlam ve performanslı çalışmasını sağlayacak ek ipuçları sunduk. Unutulmamalıdır ki, her uygulamanın kendine özgü gereksinimleri olabilir ve bu rehber genel bir çerçeve sunmaktadır. Dağıtım sürecini kendi uygulamanızın özel ihtiyaçlarına göre uyarlamak, başarılı bir canlıya geçiş için kritik öneme sahiptir. Bu adımları dikkatlice takip ederek, Clojure uygulamanızı Ubuntu 14.04 üzerinde güvenle ve etkin bir şekilde çalıştırabilirsiniz.