Yakın zamanda web sayfamı oluşturduğum hakkında bir yazı paylaşmıştım. Yine Astro ile blog sayfamı yayınlamadan önce vps sunucu kullandığım için bunu mevcut sunucuma deploy etmem gerekti. Vercel, Netlify vd. gibi bir çok alana deploy yapabilme olanağınız var ama Nodejs için işin server tarafı direkt olarak size kalıyor tabi.


Sunucu üzerinde bir nodejs ayaklandıracağız ve mevcut sunumuzdaki php server'ımız üzerinden reverse proxy açarak oluşturduğumuz astro projemize doğrudan yönlendirme işlemi yapacağız. Beraberinde bir linux service hazırlayacağız ve bu servis üzerinden sunucu restart veya uygulama hatası durumlarında tekrar tekrar arka planda ayakta kalmasını sağlayacağız.


Öncelikle NodeJs sunucunuzda kullandığınız sunucuya göre en az versiyon 18 ve üzeri olmak üzere yüklememiz gerekiyor.


Başlarken

Sunucu üzerindeki astro nodejs uygulamamızı çalıştırmak için express.js kullanacağız. Öncelikle proje kök dizininde run-server.mjs adında bir dosya oluşturalım ve içeriğini aşağıdaki şekilde düzenleyelim.

import express from 'express';
import { handler as ssrHandler } from './dist/server/entry.mjs';

const app = express();

app.use(express.static('dist/client/'));

app.use((req, res, next) => {
  return ssrHandler(req, res, next);
});

app.listen(8100, () => {
  console.log('Server Listening on localhost port 8100')
});


Burada yaptığımız işlem Astro Docs içerisinde olan bir express.js server örneğidir. Ben sunucumda direkt olarak kullanmaya çalıktığımda HTTPS protokolü kullandığım için SSL handshake error alıyorum. Haliyle burada Express.js bize HTTPS server olarak lazım. Bunun için kodumuzu aşağıdaki şekilde düzenliyoruz.


Express ile HTTPS Server Örneği

import express from 'express';
import { handler as ssrHandler } from './dist/server/entry.mjs';
import fs from 'fs'
import https from 'https'

const app = express();

app.use(express.static('dist/client/'));

app.use((req, res, next) => {
  return ssrHandler(req, res, next);
});

const privateKey = fs.readFileSync('/usr/local/.../gokhankorul.dev.key', 'utf8'); // Özel anahtar dosyasının yolu
const certificate = fs.readFileSync('/usr/local/.../gokhankorul.dev.cert.combined', 'utf8'); // Sertifika dosyasının yolu

const credentials = { key: privateKey, cert: certificate };

const server = https.createServer(credentials, app);

server.listen(8100, () => {
  console.log('Server listening on localhost port 8100')
});


Sertifikanıza ait dosyalarınızın yollarını sunucunuz üzerindekiler ile güncelleyin. Şimdi node run-server.mjs dediğimizde sunucumuz ayaklanmalı.

~ $ node ./run-server.mjs


Building for Production

astro build komutu ile projemizi localimizde build ediyoruz.


~ $ astro build
...
24:29:35 [vite] ✓ built in 16.44s
24:29:38 finalizing server assets 
24:29:38 [build] Rearranging server assets...
24:29:38 [build] Server built in 23.80s
24:29:38 [build] Complete!


Building işlemi tamamlandıktan sonra /dist, /src ve kök dizindeki tüm dosyalar ile birlikte projenizi sunucumuza aktarıyoruz. /home/{user}/ altında bir klasör oluşturup bunun altına atabiliriz.


Proje dosyasını sunucumuza attıktan sonra modülleri tekrar burada da yüklememiz gerekiyor.

~ $ npm install
# yada
~ $ yarn install


Serving İşlemi

Sunucumuza root erişimi sağlıyoruz.

~ $ sudo su

Şimdi projemiz çalıştırılmaya hazır haldeyken sunucumuz üzerinde bir service hazırlayacağız. Aşağıdaki şekilde service dosyamızı oluşturalım.

~ touch /etc/systemd/system/astro-ssr.service


Şimdi service dosyamızı açalım.

~ nano /etc/systemd/system/astro-ssr.service


Aşağıdaki alanları kendimize göre düzenleyelim. Burada en önemli olan olay WorkingDirectory kısmı. Uygulama için açtığımız klasör kök dizinini tam yoluyla aşağıdaki gibi girin.

[Unit]
Description=Gokhan Korul Personal Blog
After=network.target

[Service]
ExecStart=node ./run-server.mjs

WorkingDirectory=/home/gokhan/astro_web_app
Restart=on-failure
User=root
Group=root
Environment=NODE_PORT=8100

[Install]
WantedBy=multi-user.target


CTRL+X ve Y, Enter diyerek dosyamızı kaydedip kapatalım. Şimdi oluşturduğumuz service mizi sunucu başlangıcına ekleyeceğiz ki her defasında tekrar tekrar el ile başlatmak zorunda kalmayalım. Aşağıdaki komutu kullanarak service'i system başlangıcına ekleyelim.

~ systemctl enable astro-ssr


Şimdi artık astro-ssr service'i başlatabiliriz.


~ systemctl start astro-ssr

Artık servisimizi başlattık ve durum kontrolü yapabiliriz.


[root@root ~]# systemctl status astro-ssr
● astro-ssr.service - Gokhan Korul Personal Blog
   Loaded: loaded (/etc/systemd/system/astro-ssr.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2024-01-19 22:35:16 UTC; 1 day 18h ago
 Main PID: 364248 (node)
    Tasks: 11 (limit: 47740)
   Memory: 127.4M
   CGroup: /system.slice/astro-ssr.service
           └─364248 /usr/local/bin/node ./run-server.mjs


PHP Sunucusu Konfigürasyonu

Bundan sonraki adımda sunucu üzerinde php sunucu kullanıyorsanız örn: apache, lighttpd vb. ilgili sunucu uygulamasının konfigürasyonu içerisinden proxy olarak uygulamamıza yani https://127.0.0.1:8100 portuna yönlendirmemiz gerekiyor.