nginx - alias panik
Tiga hari belakangan ini saya menuai sedikit kepanikan (panik - supaya terkesan heboh) tentang bagaimana menerapkan fungsi alias di nginx. Beberapa dokumen panduan konfigurasi dari nginx dan sejumlah artikel forum maupun blog sudah saya baca. Simpulannya, tidak ada yang keliru dengan konfigurasi saya. Saya bisa menjamin bahwa konfigurasi saya sesuai dengan standarisasi nginx. Toh jika ada kesalahan, saya dapat dengan mudah mengaktifkan fitur log error dan tinggal menganalisanya. Paling2 ketemunya ternyata lokasi direktori atau file yang diakses tidak tepat.
Kasus saya bermula saat saya mencoba menambahkan lokasi sebuah aplikasi berbasis web yang menggunakan PHP. Karena nginx tidak memiliki mesin pengkompilasi dan pengeksekusi skrip CGI seperti PHP, maka nginx memanfaatkan mesin kompilasi internal milik PHP yang dapat dijalankan secara terpisah dari nginx di dalam sistem operasi, yaitu php-cgi. Jadi dengan menggunakan skrip inisialisasi tertentu kita dapat membuat sebuah soket pengeksekusi skrip php dan kemudian kita dapat mengkonfigurasi nginx untuk mengumpankan skrip tersebut ke soket tersebut. Hasilnya ditangkap lagi oleh nginx dan dikirimkan ke pengguna yang mengakses skrip tersebut. Apache HTTPD sudah menyediakan fitur ini secara internal melalui modul php-nya, jadi tidak perlu lagi apache menjalankan php-cgi di belakangnya. Sedangkan lighttpd memiliki sebuah eksekutor php-cgi internal (spawn-fcgi), jadi kita tidak perlu menjalankan php-cgi secara terpisah. Sebuah catatan, nginx sebenarnya memanfaatkan program spawn-fcgi milik lighttpd yang memang dikembangkan secara terpisah dari lighttpd, meskipun nantinya akan dibundel menjadi satu dalam distribusi kode lighttpd.
Sistem yang sederhana kan? Meski begitu, tetap saja saya tidak dapat mengakses skrip yang saya inginkan. Selalu saja skrip php di dalam direktori alias dianggap tidak terumpankan ke soket php-cgi. Selalu saja muncul pesan: No input specified. Lha ntuuh file-nya om nginx!
Sampai heran saya. Apalagi di log error nginx, tidak muncul satu baris kesalahan pun. Lalu saya harus bertanya ke siapa? Rumput yang bergoyang? Atau semut2 di dinding? Apakah pengumpanan skrip cgi saya keliru? Tidak juga. Direktori root dari nginx juga mengandung aplikasi dengan skrip php dan dapat berjalan lancar.Apalagi ya?
Kemudian saya teringat akan beberapa konfigurasi program yang sangat memperhatikan urutan baris-baris konfigurasi. Apa salahnya dicoba, toh semua cara sudah saya coba dan gagal.
Jadi saya mencoba mengubah urutan konfigurasi saya dari ini:
location / {
root /lokasi/app/satu;
index index.php index.html index.htm;
}
location ~ \.php$ {
root /lokasi/app/satu;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass unix:/tmp/php-fastcgi.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
fastcgi_intercept_errors on;
}
location /app2 {
alias /lokasi/app/dua;
index index.html index.php;
}
location ~ ^/app2.+\.php$ {
alias /lokasi/app/dua/$1;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /lokasi/app$fastcgi_script_name;
fastcgi_pass unix:/tmp/php-fastcgi.sock;
fastcgi_param HTTPS on;
fastcgi_intercept_errors on;
}
Menjadi seperti ini:
location /app2 {
alias /lokasi/app/dua;
index index.html index.php;
}
location ~ ^/app2.+\.php$ {
alias /lokasi/app/dua/$1;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /lokasi/app$fastcgi_script_name;
fastcgi_pass unix:/tmp/php-fastcgi.sock;
fastcgi_param HTTPS on;
fastcgi_intercept_errors on;
}
location / {
root /lokasi/yang/utama;
index index.php index.html index.htm;
}
location ~ \.php$ {
root /lokasi/yang/utama;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass unix:/tmp/php-fastcgi.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
fastcgi_intercept_errors on;
}
Dan berhasil! Oalaah yo, yo...
Ternyata begitu toh. Jadi nginx berasumsi bahwa setelah ada pengumpanan skrip php ke php-cgi yang pertama, maka pengumpanan berikutnya dari direktori selain root atau direktori alias akan dianggap tidak ada atau tidak benar. Jika dibalik maka nginx akan mendaftarkan terlebih dahulu direktori alias tersebut baru direktori utama atau root /. Apa tidak jadi masalah nantinya? Nah di sinilah peran dari definisi /app2 yang artinya direktori app2 itu berada setelah direktori root yang didefinisikan terakhir. Jadi nginx nggak perlu bingung nyari root di server tetangga.
Akhirnya karena konfigurasi sudah berhasil, saya kemudian menaruh konfigurasi-konfigurasi tambahan untuk aplikasi2 saya ke file terpisah dan tinggal mengikutsertakan file tersebut ke konfigurasi nginx.conf dengan urutan yang sama seperti konfigurasi sebelumnya.
server {
listen 0.0.0.0:443;
ssl on;
server_name nama.domain.nya;
ssl_certificate /lokasi/sertifikat/domain.crt;
ssl_certificate_key /lokasi/sertifikat/domain.key;
include app2.conf;
include utama.conf;
}
Nah, buat teman2 yang menggunakan nginx dan mengalami permasalahan seperti saya. Monggo dicoba resep saya. Mudah-mudahan benar-benar jadi solusinya. Catatan: konfigurasi ini saya gunakan di server nginx yang menjalankan layanan https (SSL), tetapi konfigurasi tersebut berlaku umum http maupun https.
Selamat mencoba.