PHP dan PHP-FPM

PHP dan PHP-FPM

Bitnesia • Aug 26, 2026 105 •EN

Nginx dari Bab 12 dan Apache dari Bab 13 sudah terbukti sanggup menyajikan halaman example.local dan blog.example.local dengan baik, tetapi keduanya baru diuji dengan file HTML statis. Praktiknya, hampir semua aplikasi web yang benar-benar dipakai Client, mulai dari CMS seperti WordPress sampai framework modern seperti Laravel, membutuhkan konten yang dibentuk secara dinamis saat request masuk, bukan sekadar file yang dibaca apa adanya dari disk. Web server seperti Nginx dan Apache sebenarnya tidak tahu cara menjalankan kode PHP sama sekali, keduanya hanya pandai menyajikan file dan meneruskan request. Ada lapisan lain yang bertugas menerjemahkan file .php menjadi output HTML, dan itulah peran PHP beserta runtime-nya.

Bab ini membahas instalasi PHP dan ekstensi umum yang dibutuhkan aplikasi web, dilanjutkan dengan penjelasan dua model integrasi PHP ke web server yaitu mod_php dan PHP-FPM beserta alasan PHP-FPM menjadi pilihan standar saat ini. Setelah itu kita mempraktikkan langsung cara menghubungkan PHP-FPM ke Nginx lewat FastCGI dan ke Apache lewat mod_proxy_fcgi, memakai ulang virtual host example.local yang sudah dibangun di Bab 12 dan Bab 13. Bab ditutup dengan konfigurasi php.ini dasar, pengujian dengan script PHP sungguhan, dan pengenalan Composer sebagai dependency manager standar PHP yang dipakai hampir semua framework modern termasuk Laravel, sebagai bekal sebelum Bab 15 membahas reverse proxy dan load balancing untuk aplikasi backend yang lebih kompleks.

14.1 Instalasi PHP dan Ekstensi Umum untuk Kebutuhan Web

PHP adalah bahasa scripting server-side yang dirancang khusus untuk pengembangan web, dieksekusi di server sebelum hasilnya dikirim sebagai HTML biasa ke browser Visitor. Ubuntu Server menyediakan PHP langsung dari repository resmi, sehingga instalasinya tidak memerlukan repository pihak ketiga untuk kebutuhan standar.

14.1.1 Instalasi PHP-FPM dan PHP CLI dari Repository Ubuntu

Ada beberapa varian paket PHP di Ubuntu, tergantung cara PHP akan dijalankan. Untuk kebutuhan bab ini, kita memasang dua varian sekaligus, yaitu php-fpm untuk menjalankan PHP di balik web server, dan php-cli untuk menjalankan script PHP langsung dari terminal, yang juga berguna untuk keperluan pengujian dan troubleshooting.

Langkah Praktik

  1. Perbarui daftar paket, lalu pasang PHP-FPM dan PHP CLI.
    sudo apt update
    sudo apt install php-fpm php-cli
    Paket php-fpm dan php-cli sebenarnya adalah metapackage yang menarik versi PHP default Ubuntu, misalnya php8.4-fpm dan php8.4-cli. Versi persisnya bisa berbeda tergantung kapan repository Ubuntu terakhir disinkronkan, jadi jangan heran jika angkanya tidak sama persis dengan contoh di modul ini.
  2. Berbeda dari Nginx dan Apache yang langsung mendengarkan port begitu terpasang, PHP-FPM baru benar-benar berguna setelah dihubungkan ke web server di Bagian 14.3. Meskipun begitu, service-nya tetap otomatis aktif dan berjalan sejak instalasi selesai. Konfirmasi statusnya.
    systemctl status php8.4-fpm.service
  3. Periksa versi PHP yang benar-benar terpasang.
    php -v

Verifikasi dan Troubleshooting

  • Jika nama service php8.4-fpm.service tidak ditemukan, cek dulu versi PHP yang benar-benar terpasang lewat php -v, lalu sesuaikan angka versinya pada semua perintah systemctl di bab ini.
  • PHP-FPM mendengarkan lewat Unix socket, bukan port TCP, sehingga ss -tlnp tidak akan menampilkannya. Gunakan perintah berikut untuk memastikan socket-nya benar-benar dibuat.
    ls -l /run/php/
    File php8.4-fpm.sock seharusnya sudah ada di sana begitu service aktif.

14.1.2 Ekstensi PHP Umum untuk Kebutuhan Web

Instalasi PHP dasar hanya menyertakan fungsi inti bahasa tersebut. Kebutuhan nyata seperti koneksi ke database, pengolahan gambar, atau membaca file XML memerlukan extension tambahan yang dipasang terpisah. Hampir semua CMS dan framework PHP modern, termasuk WordPress dan Laravel, mensyaratkan kombinasi ekstensi tertentu agar bisa berjalan tanpa error.

Langkah Praktik

  1. Pasang kumpulan ekstensi yang paling sering dibutuhkan aplikasi web PHP.
    sudo apt install php-mysql php-pgsql php-curl php-mbstring php-xml php-zip php-gd php-intl
    Sama seperti php-fpm, paket-paket ini adalah metapackage yang menarik versi spesifik sesuai PHP yang terpasang. Paket php-mysql dan php-pgsql masing-masing menyediakan driver untuk MySQL/MariaDB dan PostgreSQL, dua database yang akan kita pasang di Bab 17 dan Bab 18. Paket php-curl dipakai aplikasi untuk memanggil API eksternal, php-mbstring menangani encoding string multi-byte seperti UTF-8, php-xml dan php-zip dibutuhkan banyak proses import/export data, sedangkan php-gd menangani pengolahan gambar seperti thumbnail.
  2. Restart PHP-FPM agar ekstensi baru benar-benar dimuat.
    sudo systemctl restart php8.4-fpm
  3. Pastikan ekstensi yang baru dipasang benar-benar terbaca oleh PHP.
    php -m | grep -Ei 'mysqli|pgsql|curl|mbstring|gd'

Verifikasi dan Troubleshooting

  • Di lapangan, error Call to undefined function pada aplikasi PHP yang baru dipindah ke server baru hampir selalu berarti ada ekstensi yang lupa dipasang, bukan bug di kode aplikasinya. Cocokkan pesan error dengan daftar ekstensi yang sudah aktif lewat php -m sebelum menuduh kode aplikasi bermasalah.
  • Menambah ekstensi baru di kemudian hari selalu perlu diikuti restart PHP-FPM, karena PHP memuat seluruh daftar ekstensinya hanya sekali saat proses pertama kali start, sama seperti kebiasaan restart module Apache yang sudah kita kenal di Bagian 13.3.1.

14.2 mod_php vs PHP-FPM: Perbedaan Model dan Kapan Masing-Masing Dipakai

PHP membutuhkan cara untuk terhubung ke web server sebelum bisa memproses request Visitor, dan ada dua model utama untuk itu, yaitu mod_php dan PHP-FPM. Memahami perbedaan arsitektur keduanya penting bagi Sysadmin, karena pilihan yang salah bisa berakhir pada masalah kompatibilitas yang membingungkan, terutama di server yang sudah memakai MPM event seperti hasil instalasi Apache di Bab 13.

14.2.1 mod_php: PHP Tertanam Langsung di Web Server

mod_php adalah module Apache, dipasang lewat paket seperti libapache2-mod-php, yang menanamkan interpreter PHP langsung ke dalam setiap proses worker Apache. Setiap kali Apache menerima request untuk file .php, proses worker itu sendiri yang menjalankan kode PHP-nya, tanpa perlu berkomunikasi ke proses lain. Model ini sederhana dan pernah menjadi standar de facto selama bertahun-tahun, tetapi punya kelemahan mendasar yaitu interpreter PHP tidak thread-safe, sehingga mod_php hanya bisa berjalan di atas MPM prefork yang memakai satu proses terpisah per koneksi, bukan MPM worker atau event yang memakai thread.

Konsekuensinya terasa langsung di server kita. Ubuntu Server memakai MPM event sebagai default sejak beberapa rilis terakhir, sesuai dengan yang sudah dibahas di Bagian 13.1. Cek kembali MPM yang aktif saat ini.

apache2ctl -M | grep mpm

Selama output-nya menunjukkan mpm_event_module, memasang mod_php berarti memaksa Apache berpindah balik ke MPM prefork yang jauh lebih boros memori untuk beban traffic tinggi, sebuah trade-off yang jarang sepadan hanya demi menjalankan PHP. Inilah alasan utama mod_php semakin ditinggalkan di instalasi baru, meskipun masih banyak dijumpai di server lawas yang sudah berjalan lama tanpa pernah dimigrasi.

14.2.2 PHP-FPM: Process Manager yang Berdiri Sendiri

PHP-FPM (FastCGI Process Manager) mengambil pendekatan yang sama sekali berbeda. PHP-FPM berjalan sebagai service-nya sendiri, terpisah sepenuhnya dari proses web server, dan berkomunikasi dengan Nginx atau Apache lewat protokol FastCGI, baik melalui Unix socket seperti /run/php/php8.4-fpm.sock yang sudah kita lihat di Bagian 14.1.1, maupun lewat port TCP. Web server cukup meneruskan request untuk file .php ke socket tersebut, menunggu hasilnya, lalu mengirimkan balik ke Visitor persis seperti mekanisme reverse proxy yang sudah kita praktikkan di Bagian 12.3.2.

Karena berdiri sendiri, PHP-FPM sama sekali tidak peduli MPM apa yang dipakai Apache, dan bisa dipasangkan ke Nginx yang bahkan tidak punya konsep module PHP sama sekali. PHP-FPM juga mengatur worker process-nya sendiri lewat konsep pool, kumpulan proses PHP yang bisa diatur jumlah minimum, maksimum, dan strategi scaling-nya secara independen dari konfigurasi web server, serta memungkinkan beberapa versi PHP berjalan berdampingan di satu server yang sama, masing-masing dengan pool dan socket sendiri. Hal ini adalah sesuatu yang mustahil bagi mod_php, karena interpreter-nya menyatu langsung dengan proses Apache.

14.2.3 Tabel Perbandingan dan Rekomendasi Pemakaian

Di lapangan, PHP-FPM sudah menjadi pilihan standar untuk instalasi baru, termasuk dokumentasi resmi WordPress yang merekomendasikan Nginx dengan PHP-FPM sebagai salah satu stack yang disarankan. mod_php tetap relevan sebagai pengetahuan historis dan untuk kasus khusus server lawas bermuatan aplikasi yang sudah sangat bergantung pada perilakunya, tetapi bukan pilihan default untuk server yang dibangun dari nol.

Aspekmod_phpPHP-FPM
Lokasi eksekusiTertanam di dalam proses worker ApacheProses/service terpisah, dihubungi lewat FastCGI
Kompatibilitas MPM/web serverHanya MPM prefork, khusus ApacheSemua MPM Apache, juga Nginx dan web server lain
Multi-versi PHPSulit, satu interpreter per proses ApacheMudah, tiap versi punya pool dan socket sendiri
Isolasi resourceMenyatu dengan resource ApacheBisa diatur independen lewat konfigurasi pool
Status di lapangan saat iniLegacy, dipertahankan untuk kompatibilitas lamaStandar de facto untuk instalasi baru

Bagian selanjutnya mempraktikkan langsung cara menghubungkan PHP-FPM yang sudah terpasang, baik ke Nginx maupun ke Apache.

14.3 Menghubungkan PHP-FPM ke Nginx (FastCGI) dan ke Apache (proxy_fcgi)

PHP-FPM yang sudah aktif sejak Bagian 14.1 belum terhubung ke web server mana pun, sehingga request ke file .php masih belum bisa diproses. Bagian ini menghubungkan PHP-FPM tersebut ke Nginx lewat konfigurasi FastCGI bawaan, lalu ke Apache lewat module mod_proxy_fcgi, memakai ulang document root dan virtual host example.local yang sama persis dari Bab 12 dan Bab 13.

14.3.1 Menghubungkan PHP-FPM ke Nginx

Nginx sedang aktif melayani example.local sejak akhir Bab 13, sehingga bagian ini bisa langsung dipraktikkan tanpa mengubah service apa pun terlebih dahulu.

Langkah Praktik

  1. Buat file pengujian sederhana di document root example.local yang sudah ada.
    echo "<?php phpinfo(); ?>" | sudo tee /var/www/example.local/html/info.php
    sudo chown www-data:www-data /var/www/example.local/html/info.php
  2. Edit server block example.local.
    sudo nano /etc/nginx/sites-available/example.local
  3. Tambahkan index.php ke directive index yang sudah ada, lalu tambahkan blok location baru berikut di dalam blok server.
    index index.html index.php;
    
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
    }
    Paket nginx dari repository Ubuntu sudah menyertakan file /etc/nginx/snippets/fastcgi-php.conf secara default. File ini berisi parameter FastCGI standar, termasuk SCRIPT_FILENAME yang memberi tahu PHP-FPM file .php mana persisnya yang harus dijalankan, sehingga kita tidak perlu menulis ulang parameter-parameter tersebut secara manual di setiap server block.
  4. Uji sintaks, lalu terapkan perubahan.
    sudo nginx -t
    sudo systemctl reload nginx
  5. Uji dari komputer lain di jaringan yang sama.
    curl http://www.example.local/info.php

Respons yang muncul berupa halaman HTML panjang berisi detail konfigurasi PHP, tanda Nginx berhasil meneruskan request ke PHP-FPM dan menerima balik hasilnya. Perhatikan bahwa mengakses http://www.example.local/ tanpa embel-embel info.php tetap menampilkan index.html lama dari Bab 12, bukan otomatis mencari index.php, karena Nginx membaca directive index berurutan dari kiri ke kanan dan index.html masih lebih dulu ditemukan di document root.

Verifikasi dan Troubleshooting

  • Munculnya error 502 Bad Gateway di sini punya arti berbeda dari 502 pada reverse proxy biasa di Bagian 12.3.2. Penyebabnya hampir selalu path socket yang salah ketik atau PHP-FPM yang belum aktif, bukan backend HTTP yang mati. Pastikan dengan perintah berikut:
    systemctl status php8.4-fpm.service
    ls -l /run/php/php8.4-fpm.sock
  • Jika error File not found. justru muncul di dalam body response dan bukan sebagai halaman error Nginx biasa, hal tersebut umumnya berarti fastcgi_pass sudah benar tetapi PHP-FPM tidak menemukan file pada path yang diteruskan. Pastikan root di server block sama persis dengan document root tempat file PHP benar-benar disimpan.
  • Halaman phpinfo() menampilkan banyak detail konfigurasi server, termasuk path internal dan versi software. Hapus atau nonaktifkan file info.php ini di server production setelah selesai diuji, karena informasi tersebut sangat membantu Attacker memetakan celah yang bisa dieksploitasi.

14.3.2 Menghubungkan PHP-FPM ke Apache (proxy_fcgi)

Apache sedang tidak aktif sejak dimatikan di akhir Bab 13, sedangkan Nginx masih memakai port 80. Sama seperti pola di Bab 13, hentikan dulu Nginx sebelum mengaktifkan Apache untuk menghindari konflik port, lalu manfaatkan kembali virtual host example.local.conf yang sudah dibuat di Bagian 13.2.1.

Langkah Praktik

  1. Hentikan Nginx, lalu aktifkan kembali Apache.
    sudo systemctl stop nginx
    sudo systemctl start apache2
  2. Aktifkan module proxy_fcgi dan setenvif, dua module yang dibutuhkan Apache untuk berbicara dengan PHP-FPM lewat FastCGI.
    sudo a2enmod proxy_fcgi setenvif
  3. Paket php8.4-fpm di Ubuntu otomatis menyiapkan file konfigurasi integrasi untuk Apache begitu mendeteksi apache2 sudah terpasang. Periksa keberadaannya.
    ls /etc/apache2/conf-available/ | grep php
    File php8.4-fpm.conf seharusnya sudah ada di sana, isinya kurang lebih seperti berikut.
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost/"
    </FilesMatch>
    Directive SetHandler ini yang menjadi inti penghubung. Setiap request untuk file berakhiran .php diteruskan lewat mod_proxy_fcgi ke socket PHP-FPM yang sama persis dengan yang dipakai Nginx di Bagian 14.3.1, tanda kedua web server ini benar-benar berbagi satu mesin PHP yang sama di belakangnya.
  4. Aktifkan konfigurasi tersebut.
    sudo a2enconf php8.4-fpm
  5. Restart Apache, karena mengaktifkan module baru mewajibkan restart penuh seperti yang sudah kita bahas di Bagian 13.3.1.
    sudo apache2ctl configtest
    sudo systemctl restart apache2
  6. Uji dari komputer lain di jaringan yang sama.
    curl http://www.example.local/info.php

Halaman phpinfo() yang muncul seharusnya identik dengan yang tadi disajikan Nginx, sebab keduanya benar-benar meneruskan request ke proses PHP-FPM yang sama, hanya jalur di depannya saja yang berbeda.

Verifikasi dan Troubleshooting

  • Jika Apache masih mengunduh file .php mentah-mentah alih-alih menjalankannya, kemungkinan besar a2enconf php8.4-fpm belum dijalankan atau restart belum dilakukan setelahnya. Pastikan dengan perintah berikut:
    apache2ctl -M | grep proxy_fcgi
  • Jika di server yang sama pernah terpasang libapache2-mod-php dari percobaan lain, module tersebut bisa bentrok dengan proxy_fcgi karena keduanya sama-sama mengklaim menangani file .php. Nonaktifkan lebih dulu dengan sudo a2dismod php8.4 sebelum mengaktifkan proxy_fcgi.
  • Kita bisa membuktikan kedua web server benar-benar berbagi PHP-FPM yang sama dengan membuat satu script kecil yang menampilkan SAPI yang sedang aktif.
    echo '<?php echo php_sapi_name(); ?>' | sudo tee /var/www/example.local/html/sapi.php
    curl http://www.example.local/sapi.php
    Outputnya tetap fpm-fcgi baik saat diakses lewat Nginx maupun Apache, bukan apache2handler yang justru muncul kalau memakai mod_php. Hal ini menjadi bukti nyata bahwa PHP-FPM sama sekali tidak terikat pada satu web server tertentu.

Kembalikan server ke kondisi baseline setelah pengujian ini selesai, mengikuti pola yang sama seperti penutup Bab 13, supaya Nginx tetap menjadi web server utama untuk bab-bab berikutnya.

sudo systemctl stop apache2
sudo systemctl disable apache2
sudo systemctl start nginx
curl http://www.example.local/info.php

PHP-FPM sendiri tidak perlu di-restart atau diubah apa pun saat berpindah dari Apache kembali ke Nginx, karena service tersebut memang berjalan independen dari web server mana pun yang sedang aktif, persis inti dari perbedaan arsitektur yang sudah dibahas di Bagian 14.2.2.

14.4 Konfigurasi php.ini Dasar dan Pengujian dengan Script PHP

PHP menyimpan sebagian besar pengaturan perilakunya di file php.ini, mulai dari batas memori sampai apakah pesan error boleh ditampilkan ke Visitor. Bagian ini mempraktikkan perubahan beberapa directive yang paling sering disesuaikan Sysadmin di lapangan, sekaligus menutup bab dengan pengujian akhir memakai script PHP yang lebih mencerminkan penggunaan nyata dibanding sekadar phpinfo().

14.4.1 Directive php.ini yang Paling Sering Disesuaikan

Ubuntu memisahkan file php.ini berdasarkan SAPI yang memakainya, bukan menyediakan satu file tunggal untuk semua konteks. Sejak instalasi di Bagian 14.1, hanya ada dua direktori yang relevan untuk kita, yaitu /etc/php/8.4/fpm/php.ini yang dipakai PHP-FPM saat melayani web, dan /etc/php/8.4/cli/php.ini yang dipakai saat PHP dijalankan lewat terminal. Mengubah salah satunya sama sekali tidak memengaruhi yang lain, sebuah sumber kebingungan umum saat sebuah pengaturan "sudah diubah" tetapi perilakunya tidak berubah di browser.

Langkah Praktik

  1. Edit php.ini milik PHP-FPM, karena inilah yang benar-benar memengaruhi aplikasi web kita.
    sudo nano /etc/php/8.4/fpm/php.ini
  2. Cari dan sesuaikan directive berikut sesuai kebutuhan.
    memory_limit = 256M
    upload_max_filesize = 20M
    post_max_size = 20M
    display_errors = Off
    Pengaturan memory_limit membatasi memori maksimum yang boleh dipakai satu script PHP, mencegah satu request bermasalah menghabiskan resource server. Parameter upload_max_filesize dan post_max_size perlu dinaikkan bersamaan, karena post_max_size yang lebih kecil dari upload_max_filesize akan tetap menolak upload besar meskipun batas file individunya sudah dinaikkan. Pengaturan display_errors sebaiknya bernilai Off di server production, supaya pesan error PHP yang sering memuat path file dan versi software tidak langsung terlihat Visitor atau Attacker yang sedang mencari celah.
  3. Restart PHP-FPM agar perubahan terbaca.
    sudo systemctl restart php8.4-fpm
  4. Verifikasi nilai yang benar-benar aktif lewat halaman phpinfo() yang sudah dibuat di Bagian 14.3.1.
    curl -s http://www.example.local/info.php | grep -i memory_limit

Verifikasi dan Troubleshooting

  • Apabila nilai yang tampil di phpinfo() masih nilai lama, kemungkinan besar file yang diedit salah, misalnya tidak sengaja mengedit php.ini di direktori cli alih-alih fpm, atau restart PHP-FPM belum dijalankan setelah perubahan.
  • Setelah display_errors dimatikan, error fatal pada script PHP hanya akan menampilkan halaman putih kosong tanpa pesan apa pun ke browser, dikenal luas sebagai White Screen of Death di kalangan Developer PHP. Jangan panik melihat halaman kosong ini, telusuri dulu error log PHP-FPM sebelum menyimpulkan ada yang rusak.
    sudo tail -n 20 /var/log/php8.4-fpm.log

14.4.2 Pengujian Akhir dengan Script PHP

Sebagai penutup, kita membuat satu script PHP kecil yang benar-benar memproses logika sederhana, bukan sekadar menampilkan informasi konfigurasi statis seperti phpinfo(), sekaligus memverifikasi bahwa semua lapisan yang sudah dibangun sepanjang bab ini benar-benar bekerja bersama.

Langkah Praktik

  1. Buat file status.php di document root example.local.
    sudo nano /var/www/example.local/html/status.php
  2. Isi dengan kode berikut.
    <?php
    echo "<h1>PHP aktif di server ini</h1>";
    echo "<p>Waktu server saat ini: " . date('Y-m-d H:i:s') . "</p>";
    echo "<p>PHP SAPI yang menjalankan script ini: " . php_sapi_name() . "</p>";
    echo "<p>Ekstensi mysqli terpasang: " . (extension_loaded('mysqli') ? 'Ya' : 'Tidak') . "</p>";
  3. Sebelum diakses lewat browser, periksa dulu sintaksnya langsung dari terminal lewat PHP CLI yang sudah dipasang di Bagian 14.1.1. Langkah ini merupakan kebiasaan yang baik untuk menangkap typo lebih awal sebelum sempat memengaruhi Visitor.
    php -l /var/www/example.local/html/status.php
    Output yang sehat menunjukkan No syntax errors detected.
  4. Samakan kepemilikan filenya, lalu uji dari komputer lain di jaringan yang sama.
    sudo chown www-data:www-data /var/www/example.local/html/status.php
    curl http://www.example.local/status.php

Verifikasi dan Troubleshooting

  • Baris date() pada output seharusnya menunjukkan waktu server saat ini. Jika jamnya meleset jauh dari waktu sebenarnya, ini bukan masalah PHP, melainkan tanda konfigurasi timezone atau sinkronisasi waktu chrony dari Bab 11 yang perlu ditinjau ulang, sekaligus catatan bahwa date.timezone di php.ini juga perlu diset eksplisit agar PHP tidak bergantung pada tebakan zona waktu sistem.
  • Baris php_sapi_name() adalah cara paling cepat memverifikasi PHP-FPM benar-benar yang menangani request, bukan mekanisme lain. Nilainya harus tetap fpm-fcgi, konsisten dengan pengujian di Bagian 14.3.2.

14.5 Composer: Dependency Manager untuk PHP

PHP sendiri hanya menyediakan bahasa dan ekstensinya, sedangkan aplikasi nyata seperti Laravel hampir selalu bergantung pada puluhan hingga ratusan library pihak ketiga yang saling berhubungan. Mengunduh dan menyusun manual setiap library beserta versi dan dependency-nya masing-masing jelas tidak praktis, dan di sinilah Composer berperan sebagai dependency manager standar PHP, mirip peran APT di level sistem operasi yang sudah dibahas di Bab 6, hanya saja bekerja di level aplikasi dan per-project alih-alih per-server.

14.5.1 Instalasi Composer dari Installer Resmi

Ubuntu Server sebenarnya menyediakan paket composer lewat apt, tetapi versinya cenderung tertinggal beberapa rilis dari versi resmi terbaru karena mengikuti jadwal freeze repository Ubuntu, bukan jadwal rilis Composer sendiri. Dokumentasi Laravel dan sebagian besar framework modern mengasumsikan Composer versi terbaru, sehingga instalasi lewat installer script resmi dari getcomposer.org lebih dianjurkan dibanding paket apt untuk kebutuhan pengembangan aktif.

Langkah Praktik

  1. Unduh installer, lalu verifikasi checksum-nya lewat signature resmi sebelum dieksekusi. Langkah verifikasi ini penting karena installer pada dasarnya adalah script PHP yang dijalankan dengan hak akses Sysadmin.
    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    php -r "if (hash_file('sha384', 'composer-setup.php') === file_get_contents('https://composer.github.io/installer.sig')) { echo 'Installer terverifikasi'.PHP_EOL; } else { echo 'Installer korup, hapus dan ulangi'.PHP_EOL; unlink('composer-setup.php'); }"
    Pesan Installer terverifikasi harus muncul sebelum melanjutkan ke langkah berikutnya. Jika yang muncul justru pesan korup, ulangi proses unduh dari awal, jangan lanjutkan dengan file yang sudah terlanjur dihapus skrip di atas.
  2. Jalankan installer untuk menghasilkan composer.phar, lalu hapus file installer-nya karena sudah tidak diperlukan lagi.
    php composer-setup.php
    php -r "unlink('composer-setup.php');"
  3. Pindahkan composer.phar ke /usr/local/bin supaya bisa dipanggil dari direktori mana pun sebagai perintah global composer, mengikuti konvensi binary pihak ketiga yang sama seperti yang sudah kita praktikkan sebelumnya di server ini.
    sudo mv composer.phar /usr/local/bin/composer
    composer --version

Verifikasi dan Troubleshooting

  • Jika perintah composer menghasilkan command not found setelah dipindahkan, pastikan /usr/local/bin memang termasuk dalam PATH user yang sedang dipakai lewat echo $PATH.
  • Composer dapat memutakhirkan dirinya sendiri kapan saja tanpa perlu mengulang proses installer, cukup lewat sudo composer self-update.
  • Paket apt install composer tetap menjadi pilihan sah untuk server yang mengutamakan konsistensi versi lewat unattended-upgrades dari Bab 6 dan tidak terlalu bergantung pada fitur Composer paling baru.

14.5.2 Menambah Dependency dan Autoloading Dasar

Bagian ini mempraktikkan alur kerja Composer yang paling umum dijumpai Sysadmin saat menyiapkan atau men-deploy aplikasi PHP, yaitu menambah dependency dan memanfaatkan autoloading kelasnya tanpa perlu include atau require manual satu per satu.

Langkah Praktik

  1. Buat direktori percobaan terpisah dari document root web server, supaya tidak tercampur dengan virtual host example.local yang sudah dibangun di Bab 12 dan Bab 13.
    mkdir ~/demo-composer && cd ~/demo-composer
  2. Tambahkan satu library populer sebagai contoh, yaitu monolog/monolog untuk kebutuhan logging.
    composer require monolog/monolog
    Perintah ini otomatis membuat tiga hal sekaligus: composer.json yang mencatat dependency apa saja yang dibutuhkan project, composer.lock yang mengunci versi persis setiap dependency beserta turunannya agar instalasi ulang selalu menghasilkan versi yang identik, dan direktori vendor/ tempat kode library beserta autoloader-nya benar-benar disimpan.
  3. Buat script kecil yang memanfaatkan autoloading dari Composer, tanpa satu pun baris require manual ke file library.
    nano test.php
    Isi dengan kode berikut.
    <?php
    require 'vendor/autoload.php';
    
    use Monolog\Logger;
    use Monolog\Handler\StreamHandler;
    
    $log = new Logger('demo');
    $log->pushHandler(new StreamHandler('php://stdout'));
    $log->info('Composer berhasil memuat dependency lewat autoloading.');
  4. Jalankan lewat PHP CLI.
    php test.php

Verifikasi dan Troubleshooting

  • Output yang sehat menampilkan satu baris log berformat timestamp, nama channel demo, level INFO, dan pesan yang sudah ditulis, tanda class Monolog\Logger berhasil dimuat otomatis oleh vendor/autoload.php meskipun tidak pernah di-require manual.
  • Error Failed opening required 'vendor/autoload.php' berarti composer require atau composer install belum pernah dijalankan di direktori tersebut, sehingga folder vendor/ memang belum ada.
  • Saat memindahkan aplikasi PHP berbasis Composer ke server lain atau melakukan deployment, jalankan composer install, bukan composer update. Perintah install membaca composer.lock apa adanya dan menghasilkan environment yang identik, sedangkan update justru mencari versi terbaru yang masih memenuhi batasan di composer.json dan bisa diam-diam menaikkan versi dependency di server production.
  • Direktori vendor/ lazimnya tidak disertakan ke dalam repository Git karena ukurannya besar dan bisa dibuat ulang kapan saja lewat composer install. Yang wajib disertakan justru composer.json dan composer.lock, karena keduanya adalah sumber kebenaran dependency project.

Sampai di sini, PHP-FPM sudah terpasang lengkap dengan ekstensi umum, terhubung ke Nginx maupun Apache, siap menjalankan aplikasi PHP sungguhan dengan konfigurasi dasar yang wajar untuk kebutuhan web, dan dilengkapi Composer untuk mengelola dependency aplikasi modern seperti Laravel. Bab 15 melanjutkan topik reverse proxy yang sudah disinggung sejak Bab 12, kali ini untuk aplikasi backend yang lebih beragam dan load balancing antar beberapa backend sekaligus, sebelum Bab 16 menambahkan lapisan HTTPS lewat Let's Encrypt ke seluruh virtual host yang sudah kita bangun.