ElysiaJS adalah framework web berbasis TypeScript yang dibangun khusus di atas Bun, menawarkan performa tinggi dan type safety dari ujung ke ujung tanpa banyak boilerplate. Menulis kode di Elysia terasa ringan, tapi memindahkannya ke server produksi adalah cerita berbeda. Proses build yang asal jalan, port yang terbuka tanpa proteksi, atau environment variable yang bocor ke repository publik bisa berubah jadi insiden serius begitu aplikasi diakses banyak visitor. Artikel ini membahas jalur deployment Elysia secara menyeluruh, dari persiapan server, opsi containerization, VPS, hingga platform PaaS, sampai lapisan keamanan dan monitoring yang wajib ada sebelum aplikasi benar-benar live.
1. Prasyarat Sebelum Deployment
Sebelum menyentuh server produksi, ada beberapa hal yang perlu kita pastikan siap lebih dulu. Melewatkan tahap ini sering jadi sumber masalah yang baru terasa saat traffic mulai masuk.
1.1 Runtime dan Repository
Server produksi perlu Bun terpasang jika kita menjalankan aplikasi langsung dari source code, atau setidaknya binary hasil compile jika memilih jalur yang dibahas di bagian 1.3. Pastikan juga kode sudah berada di dalam repository Git yang rapi, dengan .gitignore yang mengecualikan folder node_modules dan file .env. Developer yang lupa mengecualikan .env dari repository berisiko membocorkan credential database atau API key ke publik, terutama jika repository tersebut ternyata bersifat publik atau di-push ke fork orang lain.
1.2 Konfigurasi Environment Variables
Bun membaca file .env secara otomatis tanpa perlu package tambahan seperti dotenv. Variabel di dalamnya langsung tersedia lewat process.env begitu proses dijalankan. Untuk produksi, set NODE_ENV=production agar Elysia dan dependency lain yang membaca variabel ini bisa menonaktifkan log verbose atau fitur debugging yang tidak perlu berjalan di lingkungan live.
# .env.production
NODE_ENV=production
PORT=3000
DATABASE_URL=postgres://user:pass@localhost:5432/dbJangan pernah menaruh file .env berisi credential asli di dalam image Docker atau commit ke Git. Sebagian besar platform PaaS seperti Fly.io dan Render menyediakan mekanisme secret terpisah untuk menyimpan variabel sensitif ini di luar kode.
1.3 Optimasi Build dengan Compile Binary
Alih-alih menjalankan source code TypeScript langsung di produksi, dokumentasi resmi Elysia merekomendasikan meng-compile aplikasi jadi satu binary executable lewat fitur bawaan Bun. Cara ini bisa menekan konsumsi memori 2-3 kali lebih rendah dibanding menjalankan dari lingkungan development.
bun build \
--compile \
--minify-whitespace \
--minify-syntax \
--target bun \
--outfile server \
src/index.tsHasilnya adalah file server yang bisa langsung dijalankan (./server) tanpa membutuhkan Bun terpasang di server tujuan. Kalau target deployment berbeda arsitektur dari mesin development, misalnya kita compile di macOS ARM tapi server produksi memakai Linux x64, tentukan target eksplisit lewat flag seperti --target bun-linux-x64-musl. Satu catatan penting: jika aplikasi memakai OpenTelemetry untuk tracing, hindari flag --minify penuh karena bisa memangkas nama fungsi jadi satu karakter dan membuat trace sulit dibaca. Pakai kombinasi --minify-whitespace dan --minify-syntax saja seperti contoh di atas.
2. Deploy dengan Docker
Docker jadi pilihan populer karena konsisten: aplikasi yang jalan di container lokal punya perilaku yang sama persis saat dipindah ke VPS atau cloud manapun. Elysia dan Bun sudah menyediakan pola multi-stage build yang ringkas untuk kebutuhan ini.
FROM oven/bun AS build
WORKDIR /app
COPY package.json bun.lock .
RUN bun install
COPY ./src ./src
ENV NODE_ENV=production
RUN bun build \
--compile \
--minify-whitespace \
--minify-syntax \
--outfile server \
src/index.ts
FROM gcr.io/distroless/base
WORKDIR /app
COPY --from=build /app/server server
ENV NODE_ENV=production
CMD ["./server"]
EXPOSE 3000Stage pertama memakai image resmi oven/bun untuk install dependency dan compile binary. Stage kedua memakai distroless base image dari Google yang tidak menyertakan shell, package manager, atau tool lain di dalamnya. Kalau seorang attacker berhasil mengeksploitasi aplikasi, tidak ada shell yang bisa dipakai untuk eksplorasi lebih jauh di dalam container karena memang tidak tersedia.
- Build image dari Dockerfile di atas:
docker build -t elysia-app . - Jalankan container dan map port 3000 ke port host:
docker run -d -p 3000:3000 --name elysia-app elysia-app - Cek log untuk memastikan aplikasi berjalan normal:
docker logs -f elysia-app
Untuk proyek yang memakai OpenTelemetry, keluarkan library yang di-instrument dari proses bundling lewat flag --external (misalnya --external pg untuk driver PostgreSQL) agar mekanisme monkey-patching-nya tetap berfungsi, lalu install dependency produksi saja di image final dengan bun install --production.
3. Deploy ke VPS
Kalau kita mengelola VPS sendiri tanpa Docker, aplikasi tetap butuh process manager agar otomatis restart saat crash atau server reboot. Dua opsi paling umum di ekosistem Linux adalah PM2 dan systemd.
3.1 Instalasi Bun di VPS
- Login ke VPS lewat SSH, lalu install Bun dengan installer resmi:
curl -fsSL https://bun.com/install | bash - Pastikan package
unzipsudah terpasang di Ubuntu/Debian, karena installer Bun membutuhkannya:sudo apt install unzip - Verifikasi instalasi:
bun --version - Clone repository aplikasi dan install dependency:
git clone https://github.com/username/repo.git cd repo bun install --production
3.2 Menjalankan dengan PM2
PM2 punya dukungan native untuk Bun lewat flag --interpreter. Sysadmin yang sudah familiar dengan PM2 dari proyek Node.js bisa langsung memakai pola yang sama.
pm2 start index.js --interpreter bunUntuk konfigurasi yang lebih terstruktur, definisikan aplikasi lewat file ecosystem.config.js:
module.exports = {
apps: [{
name: "elysia-app",
script: "./src/index.ts",
interpreter: "bun"
}]
}Untuk menjalankan aplikasi di banyak core sekaligus (cluster mode), Bun versi 1.1.25 ke atas mendukung mode ini lewat:
bunx --bun pm2 start app.ts -i maxPM2 menyimpan runtime yang dipakai saat daemon-nya pertama kali start. Kalau sebelumnya PM2 sudah berjalan dengan interpreter Node.js, jalankan pm2 kill dulu sebelum start ulang dengan interpreter Bun, supaya daemon tidak bingung memakai runtime lama.
3.3 Menjalankan dengan Systemd
Alternatif tanpa dependency tambahan adalah memanfaatkan systemd, service manager bawaan hampir semua distribusi Linux modern termasuk Ubuntu Server. Buat unit file baru:
- Buat file
/etc/systemd/system/elysia-app.servicedengan isi berikut:[Unit] Description=Elysia Production Server After=network.target [Service] Type=simple User=www-data WorkingDirectory=/var/www/elysia-app ExecStart=/var/www/elysia-app/server Restart=on-failure Environment=NODE_ENV=production [Install] WantedBy=multi-user.targetExecStartdi atas mengarah ke binary hasil compile dari bagian 1.3. Kalau memilih menjalankan langsung dari source, ganti baris tersebut menjadiExecStart=/usr/local/bin/bun run /var/www/elysia-app/src/index.ts. - Muat ulang konfigurasi systemd:
sudo systemctl daemon-reload - Aktifkan service agar otomatis start saat boot, lalu jalankan:
sudo systemctl enable --now elysia-app - Cek status dan log:
sudo systemctl status elysia-app journalctl -u elysia-app -f
PM2 lebih cocok kalau tim developer sudah nyaman dengan ekosistem Node.js dan butuh fitur monitoring bawaan yang siap pakai. Systemd lebih ringan karena tidak menambah dependency baru di server, dan jadi pilihan yang lebih natural bagi sysadmin yang sudah mengelola service Linux lain dengan cara yang sama.
4. Deploy di Fly.io dan Render
Untuk tim yang tidak ingin mengurus server secara manual, platform PaaS menawarkan jalur deployment yang lebih singkat lewat integrasi Git langsung.
4.1 Fly.io
Fly.io mendukung deployment berbasis Dockerfile secara langsung. Kalau Dockerfile dari bagian 2 sudah ada di root project, Fly akan mendeteksinya otomatis dan memakainya sebagai basis image.
- Install CLI
flylalu login ke akun Fly.io. - Jalankan dari root project untuk membuat konfigurasi awal:
Perintah ini akan membuat filefly launchfly.tomlsebagai konfigurasi aplikasi, dan otomatis memakai Dockerfile yang sudah ada tanpa mencoba scanner framework lain. - Deploy aplikasi:
fly deploy
4.2 Render
Render saat ini belum menyediakan environment native khusus Bun seperti yang tersedia untuk Node.js atau Python. Jalur paling aman adalah memilih environment Docker saat membuat Web Service baru, lalu memakai Dockerfile yang sama seperti pada bagian 2.
Baik Fly.io, Render, maupun Railway umumnya mengatur port lewat environment variable PORT yang nilainya ditentukan platform, bukan port statis yang kita pilih sendiri. Pastikan kode listen Elysia membaca variabel ini:
import { Elysia } from "elysia"
new Elysia()
.get("/", () => "OK")
.listen(process.env.PORT ?? 3000)Elysia secara default mem-bind hostname ke 0.0.0.0, sehingga kompatibel dengan cara platform-platform ini meneruskan traffic ke container aplikasi.
5. Reverse Proxy dan SSL
Menjalankan Elysia langsung di port 80/443 sebagai root user bukan praktik yang aman. Pola yang lebih umum adalah menjalankan Elysia di port internal (misalnya 3000), lalu meletakkan reverse proxy di depannya untuk menangani domain dan SSL.
5.1 Konfigurasi Nginx
Nginx jadi pilihan paling umum untuk reverse proxy di Linux. Buat konfigurasi server block yang mengarahkan domain ke port aplikasi Elysia:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}Header Upgrade dan Connection di atas penting kalau aplikasi Elysia juga menangani koneksi WebSocket, bukan hanya HTTP biasa. Setelah file konfigurasi ini disimpan di /etc/nginx/sites-available/ dan di-symlink ke sites-enabled, reload Nginx dengan sudo systemctl reload nginx. Sebagai alternatif yang lebih sederhana, Caddy bisa mengurus reverse proxy sekaligus provisioning SSL otomatis hanya lewat beberapa baris Caddyfile, cocok untuk sysadmin yang ingin setup lebih cepat tanpa mengelola Certbot secara manual.
5.2 Pemasangan SSL dengan Certbot
Let's Encrypt menyediakan sertifikat SSL gratis lewat client resmi Certbot.
- Install Certbot lewat snap (disarankan dokumentasi resmi dibanding package repository OS):
sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/local/bin/certbot - Jalankan Certbot dengan plugin Nginx untuk mendapatkan sekaligus memasang sertifikat secara otomatis:
sudo certbot --nginx - Verifikasi mekanisme perpanjangan otomatis berjalan normal:
sudo certbot renew --dry-run
Sertifikat Let's Encrypt berlaku 90 hari, dan Certbot biasanya sudah mengatur cron job atau systemd timer untuk perpanjangan otomatis begitu instalasi selesai.
6. Keamanan dan Monitoring Production
Server yang sudah live jadi target yang terus-menerus dicoba oleh attacker otomatis lewat bot scanning. Beberapa lapisan proteksi dasar wajib ada sebelum domain diumumkan ke publik.
6.1 Membatasi CORS
Plugin resmi @elysia/cors mengatur header CORS (Cross-Origin Resource Sharing) agar hanya origin tertentu yang boleh mengakses API dari browser.
bun add @elysia/corsimport { Elysia } from "elysia"
import { cors } from "@elysia/cors"
new Elysia()
.use(cors({
origin: ["https://app.example.com"],
methods: ["GET", "POST", "PUT", "DELETE"],
credentials: true
}))
.listen(3000)Secara default plugin ini menerima origin apapun (origin: true), yang cukup aman untuk API publik tanpa cookie session, tapi berisiko kalau endpoint kita menyertakan credential di setiap request. Untuk API yang dipakai user/client lewat browser dengan session cookie, batasi origin secara eksplisit seperti contoh di atas.
6.2 Rate Limiting dan Header Keamanan
Elysia belum menyediakan plugin resmi untuk rate limiting dari tim intinya. Package komunitas seperti elysia-rate-limit banyak dipakai untuk kebutuhan ini, tapi karena statusnya third-party, sebaiknya kita cek ulang rilis terbaru dan tingkat pemeliharaannya di repository sebelum dipasang di produksi. Sebagai lapisan pertahanan tambahan yang lebih teruji, rate limiting juga bisa diterapkan di level Nginx lewat directive limit_req_zone, atau di level platform kalau memakai PaaS yang menyediakan fitur ini secara bawaan.
Untuk header keamanan seperti X-Content-Type-Options atau Strict-Transport-Security, Elysia belum punya plugin resmi setara helmet di ekosistem Express. Cara paling aman untuk saat ini adalah menambahkan header tersebut manual lewat onAfterHandle, atau mengaturnya di konfigurasi Nginx yang sudah kita pasang di bagian 5.1.
6.3 Monitoring dan Logging
Plugin @elysia/opentelemetry memungkinkan kita melacak request secara detail, termasuk durasi tiap handler dan query database yang dipanggil di dalamnya. Seperti disinggung di bagian 1.3, hindari flag --minify penuh saat compile binary kalau memakai plugin ini, karena nama fungsi yang terpotong bikin hasil trace sulit dibaca ulang. Untuk visualisasi data trace dan metric jangka panjang, data ini umumnya diarahkan ke tool observability seperti Grafana atau layanan APM pihak ketiga, tergantung stack monitoring yang sudah dipakai tim infrastruktur.
7. Kesimpulan
Deployment Elysia ke production bukan sekadar menjalankan bun run di server dan berharap semuanya lancar. Tiap opsi punya trade-off sendiri: Docker unggul dari sisi konsistensi environment, VPS dengan PM2 atau systemd memberi kontrol penuh atas resource server, sementara Fly.io dan Render memangkas banyak pekerjaan operasional dengan mengorbankan sedikit fleksibilitas konfigurasi. Lapisan reverse proxy, SSL, CORS, dan rate limiting bukan langkah opsional, karena tanpa itu aplikasi yang sudah live jadi target empuk bagi percobaan akses yang tidak diinginkan.
Langkah lanjutan yang layak dipertimbangkan adalah mengotomatisasi seluruh proses ini lewat pipeline CI/CD, misalnya dengan GitHub Actions yang menjalankan build binary atau image Docker setiap ada push ke branch utama, lalu men-deploy otomatis ke VPS lewat SSH atau memanggil fly deploy langsung dari workflow. Proses deployment jadi konsisten dan tidak lagi bergantung pada langkah manual yang rawan human error.




