Membuat Web Rust di Alpine Linux dan Nginx

Daftar Isi

Halo Sobat, pada tulisan kali ini saya ingin mencoba sesuatu yang sedikit berbeda dari aplikasi web yang selama ini saya buat menggunakan PHP.

Kali ini kita akan mencoba menjalankan Rust di Alpine Linux dan membuat sebuah aplikasi web sederhana menggunakan Rust.

Aplikasi yang kita buat memang masih sederhana. Namun, daripada hanya menampilkan tulisan Hello World berupa teks polos, saya akan membuatnya sedikit lebih menarik dengan menghasilkan halaman HTML sederhana yang dapat langsung dibuka melalui browser.

Pada tutorial ini saya menggunakan server Alpine Linux yang sebelumnya sudah menjalankan Nginx, PHP, dan MySQL. Rust akan berjalan berdampingan dengan layanan tersebut tanpa perlu menggantikan PHP ataupun mengubah konfigurasi MySQL.

Konsepnya kira-kira seperti ini:

                        Internet
                           │
                           ▼
                    ┌─────────────┐
                    │    Nginx    │
                    │   Port 80   │
                    └──────┬──────┘
                           │
              ┌────────────┴────────────┐
              │                         │
              ▼                         ▼
       ┌─────────────┐          ┌─────────────┐
       │   PHP-FPM   │          │  Rust App   │
       │             │          │  Port 8080  │
       └─────────────┘          └─────────────┘

Dengan konfigurasi tersebut, website utama tetap menggunakan PHP seperti biasa. Sementara itu, URL tertentu seperti /rust akan diteruskan oleh Nginx ke aplikasi Rust.

Persiapan

Sebelum memulai, pastikan Sobat sudah dapat masuk ke server Alpine Linux melalui SSH.

Pada contoh ini kita menggunakan:

  • Alpine Linux
  • Nginx
  • PHP-FPM
  • Rust
  • Cargo
  • Port 8080 untuk aplikasi Rust

Saya menggunakan 127.0.0.1:8080 untuk aplikasi Rust. Artinya aplikasi Rust tidak perlu membuka port 8080 langsung ke internet karena akses dari luar akan dilakukan melalui Nginx.

Dengan cara ini, Nginx tetap menjadi pintu utama server.

Langkah 1 — Install Rust di Alpine Linux

Pertama, masuk ke server Alpine Linux melalui SSH.

Kemudian perbarui daftar repository:

apk update

Setelah itu install Rust, Cargo, dan beberapa tool yang dibutuhkan untuk proses kompilasi:

apk add curl build-base rust cargo

Setelah proses instalasi selesai, kita dapat memeriksa versi Rust:

rustc --version

Kemudian periksa Cargo:

cargo --version

Jika keduanya menampilkan nomor versi, berarti Rust sudah siap digunakan.

Catatan: rustc adalah compiler Rust, sedangkan cargo merupakan build system dan package manager yang biasa digunakan dalam pengembangan aplikasi Rust.

Untuk server produksi, compiler dan tool build sebenarnya tidak harus terus terpasang. Setelah aplikasi selesai dikompilasi, yang diperlukan untuk menjalankan aplikasi adalah file binary hasil kompilasi.

Langkah 2 — Membuat Project Rust

Selanjutnya kita buat project Rust baru.

Jalankan perintah berikut:

cargo new hello_world

Perintah tersebut akan membuat sebuah folder bernama hello_world.

Masuk ke folder tersebut:

cd hello_world

Jika kita melihat isi foldernya, kurang lebih strukturnya seperti ini:

hello_world/
├── Cargo.toml
└── src/
    └── main.rs

File utama program Rust berada di:

src/main.rs

Sedangkan Cargo.toml digunakan untuk menyimpan informasi dan konfigurasi project Rust.

Langkah 3 — Membuat Web Server Sederhana

Sekarang kita mulai membuat aplikasi web sederhana.

Buka file src/main.rs menggunakan Nano:

nano src/main.rs

Hapus isi sebelumnya dan ganti dengan kode berikut:

use std::io::{Read, Write};
use std::net::TcpListener;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();

    println!("Server Rust berjalan di http://127.0.0.1:8080");

    for stream in listener.incoming() {
        let mut stream = stream.unwrap();

        let mut buffer = [0; 1024];
        stream.read(&mut buffer).unwrap();

        let html = r#"<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">

    <title>Hello World - Rust</title>

    <style>
        * {
            box-sizing: border-box;
        }

        body {
            margin: 0;
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            font-family: Arial, sans-serif;
            background: linear-gradient(135deg, #f5f7fa, #dfe6ee);
            color: #222;
        }

        .container {
            width: min(90%, 700px);
            padding: 20px;
        }

        .card {
            background: #ffffff;
            border-radius: 18px;
            padding: 45px 35px;
            text-align: center;
            box-shadow: 0 15px 40px rgba(0, 0, 0, 0.12);
        }

        .icon {
            font-size: 58px;
            margin-bottom: 15px;
        }

        h1 {
            margin: 0 0 12px;
            font-size: 36px;
        }

        .subtitle {
            color: #666;
            font-size: 17px;
            line-height: 1.7;
        }

        .rust {
            display: inline-block;
            margin-top: 20px;
            padding: 10px 18px;
            border-radius: 30px;
            background: #f1f3f5;
            font-weight: bold;
        }

        .footer {
            margin-top: 25px;
            font-size: 13px;
            color: #888;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="card">

            <div class="icon">🦀</div>

            <h1>Hello World!</h1>

            <div class="subtitle">
                Halaman ini berhasil dijalankan
                menggunakan aplikasi Rust
                di Alpine Linux.
            </div>

            <div class="rust">
                Rust + Alpine Linux
            </div>

            <div class="footer">
                Web server sederhana tanpa framework
            </div>

        </div>
    </div>
</body>
</html>"#;

        let response = format!(
            "HTTP/1.1 200 OK\r\n\
             Content-Type: text/html; charset=UTF-8\r\n\
             Content-Length: {}\r\n\
             Connection: close\r\n\
             \r\n\
             {}",
            html.len(),
            html
        );

        stream.write_all(response.as_bytes()).unwrap();
        stream.flush().unwrap();
    }
}

Kemudian simpan file tersebut.

Jika menggunakan Nano:

Ctrl + O
Enter
Ctrl + X

Berbeda dengan contoh Hello World paling sederhana pada Rust, program di atas sudah berfungsi sebagai HTTP server sederhana.

Rust akan membuka port:

127.0.0.1:8080

Kemudian ketika ada browser atau Nginx yang mengakses server tersebut, Rust akan mengirimkan halaman HTML yang sudah kita buat.

Hasilnya bukan lagi sekadar tulisan:

Hello World dari Rust!

tetapi berupa halaman sederhana dengan kartu, ikon Rust, judul, dan informasi bahwa aplikasi berhasil berjalan.

Langkah 4 — Compile Program Rust

Sekarang kita compile program tersebut.

Gunakan perintah:

cargo build --release

Jika proses kompilasi berhasil, Cargo akan membuat binary di:

target/release/hello_world

Kita dapat melihat file tersebut dengan:

ls -lh target/release/hello_world

Untuk memastikan binary tersebut dapat dijalankan, kita dapat mencobanya langsung:

./target/release/hello_world

Jika berhasil, terminal akan menampilkan:

Server Rust berjalan di http://127.0.0.1:8080

Biarkan program tersebut berjalan sementara kita melakukan pengujian.

Langkah 5 — Menguji Rust dari Server

Karena aplikasi hanya menggunakan 127.0.0.1:8080, kita dapat mengujinya langsung dari server menggunakan curl.

Buka terminal lain atau hentikan sementara program jika diperlukan, kemudian jalankan:

curl http://127.0.0.1:8080

Jika berhasil, kita akan mendapatkan source HTML dari halaman yang dibuat oleh Rust.

Jika ingin melihat halaman tersebut dalam bentuk visual, kita membutuhkan Nginx sebagai reverse proxy.

Langkah 6 — Menjalankan Rust di Background

Setelah aplikasi berhasil diuji, kita dapat menjalankannya di background.

Gunakan:

nohup ./target/release/hello_world > app.log 2>&1 &

Perintah tersebut akan menjalankan aplikasi tanpa harus mempertahankan terminal SSH tetap terbuka.

Output aplikasi akan disimpan ke:

app.log

Untuk melihat prosesnya:

ps aux | grep hello_world

Kita juga dapat melihat log menggunakan:

cat app.log

atau:

tail -f app.log

Jika aplikasi berjalan dengan baik, sekarang Rust sudah aktif di:

127.0.0.1:8080

Langkah 7 — Menghubungkan Rust dengan Nginx

Sampai tahap ini aplikasi Rust sebenarnya sudah berjalan.

Namun, aplikasi tersebut hanya dapat diakses dari server karena kita menggunakan:

127.0.0.1:8080

Di sinilah Nginx kita gunakan sebagai reverse proxy.

Dengan konfigurasi ini, pengunjung tidak perlu mengetahui bahwa aplikasi Rust sebenarnya berjalan di port 8080.

Misalnya kita ingin menggunakan alamat:

http://domain.com/rust

maka Nginx akan menerima permintaan tersebut dan meneruskannya ke:

http://127.0.0.1:8080

Dengan demikian, aplikasi PHP yang sudah ada tidak perlu dipindahkan.

Langkah 8 — Tambahkan Konfigurasi Rust di Nginx

Buka konfigurasi Nginx.

Pada Alpine Linux, salah satu lokasi yang umum digunakan adalah:

/etc/nginx/http.d/default.conf

Misalnya:

nano /etc/nginx/http.d/default.conf

Kemudian kita dapat menggunakan konfigurasi seperti berikut:

server {
    listen 80;
    server_name localhost;

    root /home/ripanel/myweb/localhost;
    index index.php index.html index.htm;

    proxy_connect_timeout 12000;
    proxy_send_timeout 12000;
    send_timeout 12000;

    # Aplikasi Rust
    location /rust {
        proxy_pass http://127.0.0.1:8080;

        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_read_timeout 12000;
    }

    # Website utama
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # PHP-FPM
    location ~ \.php$ {
        fastcgi_read_timeout 12000;
        proxy_read_timeout 12000;

        include fastcgi_params;

        fastcgi_pass unix:/run/php-fpm.sock;
        fastcgi_index index.php;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # Blok file .ht*
    location ~ /\.ht {
        deny all;
    }
}

Bagian yang paling penting untuk Rust adalah:

location /rust {
    proxy_pass http://127.0.0.1:8080;

    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_read_timeout 12000;
}

Sedangkan konfigurasi PHP tetap menggunakan:

fastcgi_pass unix:/run/php-fpm.sock;

Jadi kita tidak mengganti PHP dengan Rust.

Keduanya berjalan berdampingan.

Langkah 9 — Periksa Konfigurasi Nginx

Jangan langsung melakukan reload setelah mengubah konfigurasi.

Sebaiknya kita periksa terlebih dahulu apakah konfigurasi Nginx memiliki kesalahan:

nginx -t

Jika konfigurasi benar, biasanya akan muncul pesan seperti:

syntax is ok
test is successful

Jika sudah berhasil, lakukan reload:

nginx -s reload

Dengan demikian Nginx akan menggunakan konfigurasi baru tanpa perlu menghentikan service secara keseluruhan.

Langkah 10 — Membuka Aplikasi Rust dari Browser

Sekarang coba buka alamat berikut pada browser:

http://domain.com/rust

Jika menggunakan server lokal:

http://localhost/rust

Jika semuanya berjalan dengan benar, Nginx akan menerima permintaan tersebut dan meneruskannya ke aplikasi Rust.

Browser kemudian akan menampilkan halaman yang kita buat sebelumnya.

Alur permintaannya menjadi seperti ini:

Browser
   │
   │ http://domain.com/rust
   ▼
 Nginx :80
   │
   │ proxy_pass
   ▼
Rust :8080
   │
   ▼
 HTML
   │
   ▼
Browser

Sementara jika pengunjung membuka halaman PHP biasa:

http://domain.com/

atau:

http://domain.com/index.php

permintaan tersebut tetap diproses oleh konfigurasi PHP-FPM seperti sebelumnya.

Jadi secara sederhana:

/rust/*  → Rust
/*.php   → PHP-FPM
/*       → Website utama

Rust dan PHP Bisa Berjalan Berdampingan

Menurut saya, bagian menarik dari percobaan ini bukan sekadar membuat halaman Hello World.

Yang lebih menarik adalah melihat bahwa kita tidak harus langsung mengganti seluruh aplikasi lama hanya karena ingin mencoba bahasa pemrograman atau teknologi baru.

Dalam satu server, kita dapat menjalankan beberapa aplikasi dengan tugas masing-masing.

Misalnya:

                    NGINX
                      │
          ┌───────────┴───────────┐
          │                       │
          ▼                       ▼
       PHP-FPM                  Rust
          │                       │
          ▼                       ▼
   Website utama             /rust

PHP tetap digunakan untuk website yang sudah ada, sedangkan Rust dapat digunakan untuk membuat aplikasi atau service baru.

Pendekatan seperti ini juga cukup menarik untuk eksperimen. Kita dapat mencoba Rust sedikit demi sedikit tanpa harus membongkar aplikasi PHP yang sudah berjalan.

Jika Sudah Selesai, Apakah Rust Compiler Harus Tetap Terpasang?

Tidak selalu.

Pada tutorial ini kita memasang:

rust
cargo
build-base

karena kita membutuhkan semuanya untuk melakukan proses kompilasi.

Setelah aplikasi selesai dibuat dan binary:

target/release/hello_world

sudah tersedia, compiler tidak lagi dibutuhkan untuk sekadar menjalankan aplikasi tersebut.

Jika ingin menghemat ruang pada server, tool untuk proses build dapat dipertimbangkan untuk dihapus.

Namun, saya biasanya menyarankan untuk tidak buru-buru menghapusnya jika server tersebut masih digunakan untuk eksperimen atau pengembangan. Dengan compiler dan Cargo tetap tersedia, kita dapat mengubah kode dan melakukan compile ulang dengan lebih mudah.

Penutup

Sampai di sini kita sudah berhasil membuat aplikasi web sederhana menggunakan Rust di Alpine Linux.

Walaupun program yang dibuat masih sangat sederhana, kita sudah mendapatkan beberapa hal penting:

  • Rust berhasil di-install di Alpine Linux.
  • Project Rust dibuat menggunakan Cargo.
  • Rust digunakan untuk membuat HTTP server sederhana.
  • Program dikompilasi menjadi binary.
  • Aplikasi Rust berjalan di port 8080.
  • Nginx digunakan sebagai reverse proxy.
  • PHP-FPM tetap dapat berjalan seperti sebelumnya.
  • Rust dan PHP dapat berjalan berdampingan dalam satu server.

Contoh ini juga menjadi dasar yang cukup baik jika nantinya ingin mencoba membuat aplikasi Rust yang lebih serius.

Untuk aplikasi nyata, tentu kita tidak perlu membuat HTTP server secara manual seperti contoh di atas. Kita dapat melanjutkannya dengan framework Rust seperti Axum, Actix Web, atau Rocket, kemudian menambahkan routing, database, API, authentication, dan kebutuhan aplikasi lainnya.

Namun untuk tahap awal, menurut saya membuat semuanya dari std terlebih dahulu cukup menarik karena kita dapat melihat secara langsung bagaimana sebuah aplikasi Rust menerima koneksi, membaca request, kemudian mengirimkan response HTTP ke browser.

Tinggalkan Balasan

Informasi kontak Anda tidak akan dipublikasikan. Kolom yang wajib diisi ditandai *. Notifikasi akan dikirim ke telegram untuk mempercepat tanggapan komentar