Web Server dengan Apache

Web Server dengan Apache

Bitnesia • Aug 26, 2026 84 •EN

Nginx yang kita pasang di Bab 12 sudah melayani domain example.local dan blog.example.local dengan baik, tetapi di lapangan Sysadmin jarang memiliki kemewahan memilih satu web server saja untuk seluruh infrastruktur. Banyak aplikasi lawas, terutama CMS seperti WordPress atau framework PHP yang dibangun sekitar satu dekade lalu, dirancang dengan asumsi berjalan di atas Apache. Struktur file .htaccess yang menjadi andalan aplikasi-aplikasi ini adalah fitur khas Apache yang tidak memiliki padanan langsung di Nginx. Cepat atau lambat, kita akan menemui server production yang mewajibkan Apache tetap terpasang, entah karena warisan infrastruktur lama atau karena vendor aplikasi memang mensyaratkannya.

Bab ini mempraktikkan Apache HTTP Server dari instalasi, struktur konfigurasi, sampai virtual host, mengikuti alur yang sama seperti Bab 12. Setelah itu, kita membahas dua module penting, mod_rewrite dan mod_ssl, lalu menutup bab dengan perbandingan langsung Apache vs Nginx supaya kita memiliki dasar objektif untuk memilih salah satunya sesuai kebutuhan proyek.

13.1 Instalasi dan Struktur Konfigurasi Apache

Apache HTTP Server, sering disingkat cukup "Apache" atau dikenal juga dengan nama proses httpd di banyak distribusi non-Debian, adalah web server yang sudah ada sejak 1995 dan sempat mendominasi pangsa pasar web server dunia selama bertahun-tahun sebelum Nginx mulai populer di pertengahan 2000-an. Berbeda dari arsitektur event-driven Nginx yang sudah kita bahas di Bab 12, Apache secara tradisional memakai model Multi-Processing Module (MPM) yang menentukan bagaimana setiap koneksi ditangani, mulai dari prefork yang membuat satu proses terpisah per koneksi, worker yang memakai thread di dalam proses, sampai event yang justru mendekati pendekatan event-driven ala Nginx. Ubuntu Server memakai MPM event sebagai default sejak beberapa rilis terakhir, sehingga kesenjangan performa antara Apache dan Nginx untuk beban kerja umum sebenarnya tidak selebar dugaan banyak orang, poin yang akan kita bahas lebih detail di Bagian 13.4.

13.1.1 Instalasi Apache dari Repository Ubuntu

Nginx dari Bab 12 kemungkinan masih berjalan dan mendengarkan di port 80 pada server yang sama. Oleh karena dua web server tidak bisa mendengarkan di port yang sama tanpa konfigurasi khusus, hentikan dahulu Nginx sebelum memasang Apache supaya kita bisa mempraktikkan Apache tanpa gangguan konflik port. Kita akan mengaktifkan kembali Nginx di akhir bab ini.

Langkah Praktik

  1. Hentikan sementara service Nginx.
    sudo systemctl stop nginx
  2. Perbarui daftar paket, lalu pasang Apache.
    sudo apt update
    sudo apt install apache2
  3. Sama seperti paket nginx di Bab 12, paket Debian/Ubuntu untuk Apache otomatis mengaktifkan dan menjalankan service-nya begitu instalasi selesai. Konfirmasi statusnya.
    systemctl status apache2.service
  4. Paket apache2 mendaftarkan profile aplikasi ke UFW secara otomatis, berbeda dari Nginx yang tadi kita buka portnya secara manual. Lihat profile yang tersedia.
    sudo ufw app list
    Akan muncul tiga profile terkait Apache: Apache (hanya port 80), Apache Secure (hanya port 443), dan Apache Full (port 80 dan 443 sekaligus). Oleh karena nanti kita juga akan mengaktifkan mod_ssl di Bagian 13.3.2, izinkan langsung profile Apache Full supaya tidak perlu mengubah aturan UFW lagi belakangan.
    sudo ufw allow 'Apache Full'
  5. Uji dari komputer lain di jaringan yang sama.
    curl http://192.168.1.20
    Jika berhasil, responsnya berupa halaman HTML default berjudul "Apache2 Ubuntu Default Page", tanda Apache sudah melayani request dengan konfigurasi bawaannya.

Verifikasi dan Troubleshooting

  • Periksa versi Apache yang benar-benar terpasang.
    apache2 -v
    Versi persisnya bisa berbeda tergantung kapan repository Ubuntu terakhir disinkronkan, jadi jangan heran jika angkanya tidak sama persis dengan contoh di modul ini.
  • Jika systemctl status menunjukkan service gagal start dengan pesan seperti (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80, kemungkinan besar Nginx belum benar-benar berhenti. Periksa dengan:
    sudo ss -tlnp | grep :80
    Jika Nginx masih terlihat mendengarkan di port tersebut, ulangi sudo systemctl stop nginx lalu jalankan sudo systemctl start apache2.
  • Jika curl dari komputer lain tetap gagal padahal service sudah active (running), cek ulang rule UFW.
    sudo ufw status

13.1.2 Anatomi Direktori Konfigurasi Apache

Struktur konfigurasi Apache di Ubuntu memiliki filosofi yang mirip dengan Nginx, yaitu memisahkan konfigurasi inti dari konfigurasi per site dan per module, tetapi Apache melangkah lebih jauh dengan menyediakan perintah helper khusus untuk mengelola semuanya, alih-alih mengandalkan symbolic link manual seperti yang kita lakukan di Nginx.

Langkah Praktik

  1. Lihat isi file konfigurasi utama.
    cat /etc/apache2/apache2.conf
    Bagian paling relevan dari file ini adalah baris-baris Include berikut, yang menentukan konfigurasi tambahan apa saja yang dibaca Apache.
    IncludeOptional mods-enabled/*.load
    IncludeOptional mods-enabled/*.conf
    IncludeOptional conf-enabled/*.conf
    IncludeOptional sites-enabled/*.conf
  2. Lihat isi ports.conf, file terpisah yang mengatur port berapa saja yang didengarkan Apache.
    cat /etc/apache2/ports.conf
    Baris Listen 80 ada di sana secara default. Baris Listen 443 untuk HTTPS baru muncul nanti, dibungkus kondisi <IfModule mod_ssl.c>, yang berarti port itu baru benar-benar didengarkan setelah kita mengaktifkan mod_ssl di Bagian 13.3.2.
  3. Bandingkan direktori-direktori berikut dengan pasangan sites-available/sites-enabled yang sudah kita kenal dari Nginx.
    ls /etc/apache2/
    Selain sites-available dan sites-enabled, Apache mempunyai pasangan serupa untuk module (mods-available/mods-enabled) dan untuk konfigurasi tambahan lain (conf-available/conf-enabled). Ketiganya memakai pola yang sama persis, yaitu file di direktori -available hanya aktif kalau ada symlink ke direktori -enabled.
  4. Bedanya dari Nginx, Apache menyediakan perintah khusus untuk mengelola symlink ini, sehingga kita tidak perlu memakai ln -s secara manual. Lihat site yang aktif saat ini.
    sudo apache2ctl -S

Perintah a2ensite dan a2dissite masing-masing mengaktifkan dan menonaktifkan site, a2enmod dan a2dismod melakukan hal yang sama untuk module, sedangkan a2enconf dan a2disconf untuk konfigurasi tambahan. Kita akan memakai semuanya sepanjang bab ini. Site bawaan bernama 000-default sudah aktif sejak awal, itulah yang tadi menjawab curl kita dengan halaman "Apache2 Ubuntu Default Page", dan isinya disajikan dari /var/www/html, document root yang sama persis dengan default Nginx di Bab 12.

Verifikasi dan Troubleshooting

  • Sama seperti kebiasaan nginx -t yang sudah kita bangun di Bab 12, biasakan menguji konfigurasi Apache sebelum diterapkan.
    sudo apache2ctl configtest
    Output yang sehat menunjukkan Syntax OK.
  • Perintah apache2ctl configtest sering memunculkan warning AH00558: apache2: Could not reliably determine the server's fully qualified domain name meski konfigurasi sebenarnya valid. Warning ini muncul karena directive ServerName belum diset secara global di apache2.conf, dan aman diabaikan untuk keperluan lab, tetapi di server production sebaiknya ditambahkan baris ServerName di /etc/apache2/conf-available/servername.conf untuk menghilangkannya secara permanen.

13.2 Virtual Host di Apache

Konsep yang disebut server block di Nginx, di Apache disebut virtual host, ditulis sebagai blok <VirtualHost> di dalam file konfigurasi. Sama seperti Nginx, satu server fisik atau satu IP address bisa melayani banyak domain sekaligus lewat mekanisme ini, dan Apache pun mengandalkan header Host dari request HTTP untuk menentukan virtual host mana yang harus menjawab, lewat directive ServerName dan ServerAlias yang fungsinya setara dengan server_name di Nginx.

13.2.1 Membuat Virtual Host untuk example.local

Document root /var/www/example.local/html yang sudah kita siapkan di Bab 12 masih berisi index.html dan 404.html, dan kepemilikannya sudah www-data:www-data, user yang sama juga dipakai Apache secara default. Kita bisa langsung memakai ulang direktori ini, praktik yang sekaligus membuktikan bahwa domain dan konten statis tidak terikat pada satu web server tertentu, hanya konfigurasi di baliknya yang berbeda.

Langkah Praktik

  1. Buat file virtual host baru di sites-available. Ekstensi .conf wajib dipakai, karena a2ensite mencarinya berdasarkan pola nama file ini.
    sudo nano /etc/apache2/sites-available/example.local.conf
  2. Isi dengan konfigurasi berikut.
    <VirtualHost *:80>
        ServerName example.local
        ServerAlias www.example.local
        DocumentRoot /var/www/example.local/html
    
        <Directory /var/www/example.local/html>
            Options -Indexes +FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/example.local.error.log
        CustomLog ${APACHE_LOG_DIR}/example.local.access.log combined
    </VirtualHost>
    Blok <Directory> menentukan hak akses untuk path filesystem tersebut. Require all granted adalah sintaks kontrol akses Apache 2.4 ke atas, menggantikan kombinasi Order allow,deny dan Allow from all yang dipakai versi lama, sedangkan AllowOverride All mengizinkan file .htaccess di dalam direktori ini menimpa sebagian konfigurasi, fitur yang akan kita manfaatkan di Bagian 13.3.1.
  3. Aktifkan virtual host ini dengan a2ensite, pengganti ln -s manual yang kita pakai di Nginx.
    sudo a2ensite example.local.conf
  4. Nonaktifkan site 000-default agar tidak lagi menjadi fallback yang membingungkan.
    sudo a2dissite 000-default.conf
  5. Uji sintaks, lalu terapkan perubahan.
    sudo apache2ctl configtest
    sudo systemctl reload apache2
  6. Uji dari komputer lain di jaringan yang sama.
    curl http://www.example.local
    Respons yang muncul seharusnya identik dengan halaman yang tadi disajikan Nginx di Bab 12, sebab kedua web server itu membaca file HTML yang sama persis dari disk.

Verifikasi dan Troubleshooting

  • Error 403 Forbidden pada Apache 2.4 ke atas hampir selalu berarti baris Require all granted hilang atau salah tulis di blok <Directory>. Ini adalah jebakan umum bagi Sysadmin yang terbiasa dengan konfigurasi Apache versi lama.
  • Jika curl masih mengembalikan halaman default Apache alih-alih halaman example.local, pastikan a2dissite 000-default.conf sudah dijalankan dan systemctl reload apache2 sudah dieksekusi setelahnya.
  • Pastikan virtual host yang aktif sesuai harapan.
    sudo apache2ctl -S

13.2.2 Multiple Virtual Host Berbasis Nama Domain

Domain blog.example.local sudah punya record DNS dari Bab 12. Bagian ini menambahkan virtual host kedua untuk domain tersebut di Apache, mengikuti pola name-based virtual hosting yang sama.

Langkah Praktik

  1. Siapkan document root khusus untuk virtual host kedua ini.
    sudo mkdir -p /var/www/blog.example.local/html
    echo "<h1>Blog example.local di Apache</h1>" | sudo tee /var/www/blog.example.local/html/index.html
    sudo chown -R www-data:www-data /var/www/blog.example.local
  2. Buat virtual host baru.
    sudo nano /etc/apache2/sites-available/blog.example.local.conf
    <VirtualHost *:80>
        ServerName blog.example.local
        DocumentRoot /var/www/blog.example.local/html
    
        <Directory /var/www/blog.example.local/html>
            Options -Indexes +FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/blog.example.local.error.log
        CustomLog ${APACHE_LOG_DIR}/blog.example.local.access.log combined
    </VirtualHost>
  3. Aktifkan, uji, dan terapkan.
    sudo a2ensite blog.example.local.conf
    sudo apache2ctl configtest
    sudo systemctl reload apache2
  4. Uji kedua domain dari IP server yang sama.
    curl http://www.example.local
    curl http://blog.example.local

Verifikasi dan Troubleshooting

  • Bandingkan konten dua domain tersebut. Perbedaan konten membuktikan Apache benar-benar memilih virtual host berdasarkan header Host, persis seperti mekanisme name-based virtual host di Nginx.
  • Sama seperti Nginx, jika dua virtual host punya ServerName yang identik secara tidak sengaja, Apache tidak akan menampilkan error saat configtest. Virtual host yang didefinisikan lebih dulu dalam urutan baca file yang akan dipakai, sumber kebingungan klasik yang tidak memunculkan pesan error apa pun.

13.3 Module Penting: mod_rewrite dan mod_ssl

Kekuatan Apache banyak bertumpu pada arsitektur module-nya yang bisa diaktifkan atau dinonaktifkan on the fly tanpa kompilasi ulang binary, lewat perintah a2enmod yang sudah kita singgung di Bagian 13.1.2. Dua module yang paling sering dipakai Sysadmin di lapangan adalah mod_rewrite untuk URL rewriting dan mod_ssl untuk mengaktifkan HTTPS.

13.3.1 mod_rewrite untuk URL Rewriting

mod_rewrite memungkinkan Apache mengubah atau mengarahkan ulang URL berdasarkan pola tertentu, memakai sintaks regular expression. Module ini menjadi andalan banyak aplikasi PHP lama dan CMS seperti WordPress untuk membuat URL yang SEO-friendly, atau sekadar mengarahkan Visitor dari URL lama ke URL baru setelah struktur website berubah.

Langkah Praktik

  1. Aktifkan module rewrite.
    sudo a2enmod rewrite
    Berbeda dari perubahan site biasa yang cukup di-reload, mengaktifkan module baru mewajibkan restart penuh Apache, karena module dimuat sekali saat proses Apache pertama kali start, bukan dibaca ulang saat reload konfigurasi.
    sudo systemctl restart apache2
  2. Tambahkan aturan rewrite ke dalam blok <Directory> pada virtual host example.local.
    sudo nano /etc/apache2/sites-available/example.local.conf
    <Directory /var/www/example.local/html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    
        RewriteEngine On
        RewriteRule ^halaman-lama$ /index.html [R=301,L]
    </Directory>
    Flag R=301 membuat Apache mengirim redirect permanen ke browser, bukan menyajikan konten baru secara diam-diam, sedangkan flag L (last) memberi tahu Apache untuk berhenti memproses aturan rewrite lain setelah baris ini cocok.
  3. Terapkan dan uji.
    sudo apache2ctl configtest
    sudo systemctl reload apache2
    curl -I http://www.example.local/halaman-lama
    Header respons seharusnya menunjukkan HTTP/1.1 301 Moved Permanently beserta baris Location: /index.html.

Verifikasi dan Troubleshooting

  • Jika rewrite tidak berefek sama sekali dan Apache tetap mengembalikan 404, pastikan module-nya benar-benar aktif.
    apache2ctl -M | grep rewrite
  • Aturan rewrite juga bisa ditaruh di file .htaccess di dalam document root, bukan di file virtual host, dan itu sebabnya AllowOverride All di Bagian 13.2.1 memang sengaja diaktifkan. Bedanya, Apache membaca ulang file .htaccess di setiap request yang masuk ke direktori tersebut, sedikit membebani performa dibanding aturan yang langsung ditaruh di file virtual host, yang hanya dibaca sekali saat Apache start atau reload. Di lapangan, taruh aturan rewrite langsung di virtual host kalau kita yang mengelola server sepenuhnya, dan sisakan .htaccess untuk kasus shared hosting atau saat Developer butuh mengubah aturan tanpa akses root ke konfigurasi Apache.

13.3.2 mod_ssl untuk HTTPS Dasar

mod_ssl adalah module yang menambahkan dukungan TLS/SSL ke Apache, sehingga web server bisa melayani request lewat HTTPS di port 443. Bagian ini hanya mempraktikkan cara mengaktifkan module-nya dengan sertifikat self-signed bawaan, sekadar memastikan mekanismenya berjalan. Menerbitkan sertifikat resmi dan gratis dari Let's Encrypt, lengkap dengan auto-renewal, adalah topik utama Bab 16.

Langkah Praktik

  1. Aktifkan module ssl.
    sudo a2enmod ssl
  2. Aktifkan site default-ssl yang sudah disediakan paket apache2, lengkap dengan sertifikat self-signed dari package ssl-cert yang umumnya sudah terpasang di Ubuntu Server.
    sudo a2ensite default-ssl.conf
  3. Restart Apache, karena mengaktifkan module ssl membuat Apache perlu membuka listener baru di port 443.
    sudo systemctl restart apache2
  4. Uji dari komputer lain di jaringan yang sama. Tambahkan flag -k supaya curl tidak menolak koneksi hanya karena sertifikatnya self-signed dan belum dipercaya oleh certificate authority mana pun.
    curl -k https://192.168.1.20

Verifikasi dan Troubleshooting

  • Pastikan port 443 benar-benar didengarkan.
    sudo ss -tlnp | grep :443
  • Flag -k pada curl hanya boleh dipakai untuk pengujian lab seperti ini. Jangan pernah membiasakan diri memakainya untuk memverifikasi endpoint production, karena flag itu justru mematikan validasi sertifikat yang seharusnya melindungi Visitor dari serangan man-in-the-middle.
  • Site default-ssl secara default melayani semua domain dengan document root /var/www/html, terpisah dari virtual host example.local yang kita buat sendiri. Menghubungkan sertifikat SSL ke virtual host domain kustom dengan cara yang benar akan kita praktikkan tuntas di Bab 16.

13.4 Apache vs Nginx: Kapan Memilih yang Mana

Setelah mempraktikkan Apache secara langsung, kita sekarang punya cukup pengalaman untuk membandingkannya secara objektif dengan Nginx dari Bab 12, bukan sekadar berdasarkan reputasi atau tren di forum. Perdebatan Apache vs Nginx sering dijawab terlalu simplistis dengan "Nginx lebih cepat", padahal perbedaan sebenarnya lebih kompleks dan sangat tergantung pada kasus penggunaan yang dihadapi Sysadmin.

Perbedaan paling mendasar ada di arsitektur penanganan koneksi. Apache secara historis memakai MPM prefork yang membuat satu proses terpisah untuk setiap koneksi, model yang boros memori saat menghadapi ribuan koneksi bersamaan karena setiap proses membawa overhead-nya sendiri. Nginx sejak awal dirancang dengan model event-driven yang satu proses worker bisa menangani ribuan koneksi sekaligus secara non-blocking, sesuai penjelasan C10K problem di Bab 12. Ubuntu Server sekarang memakai MPM event sebagai default untuk Apache, model yang jauh lebih mendekati pendekatan Nginx dibanding prefork lawas, sehingga kesenjangan performa murni untuk static content sebenarnya sudah menyempit signifikan dibanding perbandingan satu dekade lalu.

Yang membuat Apache tetap relevan bukan soal kecepatan mentah, melainkan fleksibilitas konfigurasi per direktori lewat .htaccess, fitur yang sudah kita praktikkan di Bagian 13.3.1 dan tidak punya padanan langsung di Nginx. Banyak aplikasi CMS dan shared hosting environment dibangun di atas asumsi ini, sehingga migrasi penuh ke Nginx sering butuh menulis ulang seluruh aturan rewrite ke sintaks location Nginx, pekerjaan yang tidak selalu sepadan dengan manfaatnya untuk aplikasi lawas yang sudah stabil.

Di lapangan, Sysadmin jarang benar-benar harus memilih salah satu secara eksklusif. Pola hybrid yang umum dijumpai adalah menaruh Nginx di depan sebagai reverse proxy dan static file server yang menghadap langsung ke Visitor, lalu meneruskan request tertentu ke Apache di belakangnya untuk aplikasi yang memang bergantung pada mod_php atau .htaccess. Pola reverse proxy semacam ini yang akan kita perdalam mekanismenya di Bab 15, meski contoh backend-nya nanti memakai aplikasi sederhana, bukan Apache secara spesifik.

AspekApacheNginx
Model penanganan koneksiMPM (prefork, worker, event)Event-driven sejak awal
Konfigurasi per direktoriDidukung penuh lewat .htaccessTidak ada padanan langsung, semua di konfigurasi pusat
Manajemen moduleDinamis lewat a2enmod/a2dismod, tanpa kompilasi ulangSebagian besar module bawaan perlu dikompilasi saat build; module dinamis mulai didukung sejak versi 1.9.11 tapi kurang lazim dipakai
Kekuatan utamaFleksibilitas konfigurasi, kompatibilitas aplikasi lawasEfisiensi resource, andal sebagai reverse proxy dan load balancer
Kasus penggunaan umumHosting CMS/aplikasi PHP lawas, shared hostingWeb server modern, reverse proxy, static content bervolume tinggi

Setelah bab ini, giliran Bab 14 membahas PHP dan PHP-FPM sebagai lapisan untuk menjalankan aplikasi dinamis di atas Nginx maupun Apache, sebelum kita lebih banyak memakai Nginx sebagai fondasi untuk topik-topik lanjutan seperti reverse proxy dan load balancing di Bab 15, serta TLS/SSL dengan Let's Encrypt di Bab 16. Oleh karena itu, kembalikan server ke kondisi awal supaya konfigurasi Bab 12 tetap konsisten untuk bab-bab berikutnya.

sudo systemctl stop apache2
sudo systemctl disable apache2
sudo systemctl start nginx

Uji ulang untuk memastikan Nginx sudah kembali menjawab di domain yang sama.

curl http://www.example.local

Instalasi Apache tetap ada di server, hanya service-nya yang tidak aktif dan tidak start otomatis saat boot, sehingga sewaktu-waktu kita masih bisa mengaktifkannya lagi dengan sudo systemctl enable --now apache2 tanpa perlu instalasi ulang dari awal.