Membuat Virtual Host di Ubuntu
Langkah Pertama — Buat Struktur Direktori
Langkah pertama yang perlu kita lalukan adalah membuat struktur direktori yang akan menyimpan data situs-situs kita.
Document root
kita (direktori paling atas yang digunakan Apache untuk mencari konten web) akan di atur ke dalam direktori individual di bawah /var/www
. Kita akan membuat sebuah direktori disini untuk kedua virtualhost kita. Lalu, di dalam kedua direktori ini kita akan membuat folder public_html
yang menyimpan konten untuk masing-masing domain. Sekarang mari kita buat direktorinya dengan perintah:
sudo mkdir -p /var/www/example.com/public_html
sudo mkdir -p /var/www/test.com/public_html
Langkah Kedua — Memberi Permissions
Sekrang kita sudah memiliki struktur direktori untuk file-file kita namun permissionnya masing dimiliki oleh user root. Sekarang kita perlu mengganti permissionnya sehingga user biasa dapat memodifikasi file di dalam direktori ini:
sudo chown -R $USER:$USER /var/www/example.com/public_html
sudo chown -R $USER:$USER /var/www/test.com/public_html
Variabel $USER
akan mengambil nilai dari user saat ini yang sedang aktif saat tombol Enter ditekan.
Kita juga perlu memodifikasi permissionnya sedikit untuk memastikan semua file dan folder di dalamnya dapat disajikan dengan benar:
sudo chmod -R 755 /var/www
Sekarang server web kita sudah meiliki permission yang seharusnya dan user biasa dapat menambah atau mengubah konten yang ada di dalam folder-folder tersebut.
Langkah Ketiga — Membuat Halaman Demo Untuk Tiap Virtual Host
Kita sudah memiliki struktur direktori yang dibutuhkan. Mari membuat beberapa konten untuk disajikan.
Untuk keperluan demo, kita hanya akan membuat sebuah index.html
sederhana untuk tiap situs. Mari dimulai dengan example.com
:
nano /var/www/example.com/public_html/index.html
Di dalam file ini, buat sebuah dokumen HTML sederhan sebagai berikut:
/var/www/example.com/public_html/index.html
<html>
<head>
<title>Welcome to Example.com!</title>
</head>
<body>
<h1>Success! The example.com virtual host is working!</h1>
</body>
</html>
Simpan dan tutup editor nano.
Kita dapat menyalin isi file ini untuk situs yang kedua dengan cara:
cp /var/www/example.com/public_html/index.html /var/www/test.com/public_html/index.html
Lalu ubah isi file yang kedua agar sesuai
nano /var/www/test.com/public_html/index.html
/var/www/test.com/public_html/index.html
<html>
<head>
<title>Welcome to Test.com!</title>
</head>
<body> <h1>Success! The test.com virtual host is working!</h1>
</body>
</html>
Simpan dan tutup nano.
Langkah Keempat — Buat File Virtual Host Baru
File virtual host adalah file-file yang mengatur konfigurasi untuk virtual host kita dan meberitahu Apache bagaimana respon yang harus dilakukan untuk tiap request.
Apache terpasang dengan virtual host default bernama 000-default.conf
yang dapat kita pakai sebagai titik awal. Kita akan menyalin isinya untuk membuat file virtual host baru untuk tiap domain kita.
Mari mulai dengan example.com
, atur isinya, lalu salin lagi untuk test.com
dan atur lagi sesuai kebutuhan. Konfigurasi Ubuntu memerlukan setiap file virtual host berakhir dengan .conf
.
Buat File Virtual Host yang Pertama
Mari kita mulai dengan menyalin file untuk domain yang pertama:
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf
Buka file baru ini dengan sudo:
sudo nano /etc/apache2/sites-available/example.com.conf
Isi file di atas akan terlihat kurang lebih seperti pada kode di bawah (baris-baris komentar dihapus agar lebih ringkas):
/etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Seperti yang dapat pembaca lihat, tidak banyak sebetulnya sisi file ini. Kita dapat mengatur nilai-nilainya dan menambah nilai baru agar sesuai dengan kebutuhan domain pertama. Virtual host ini akan membaca semua request di port 80, port default HTTP.
Pertama, kita perlu mengubah ServerAdmin
ke email yang dipakai oleh administrator (email kita):
ServerAdmin admin@example.com
Setelah ini kita akan tamabhkan dua nilai. Yang pertama bernama ServerName
, memberikan domain apa yang akan menggunakan virtualhost ini. Nilai yang kedua adalah ServerAlias
untuk menentukan alamat lain yang ingin menggunakan virtual host ini juga, misalnya www
:
ServerName example.com
ServerAlias www.example.com
Hal lain yang perlu kita atur agar file virtualhost bekerja adalah document root
untuk domain yang ditentukan. Karena kita di awal sudah membuat direktorinya, kita hanya perlu menambah alamatnya:
DocumentRoot /var/www/example.com/public_html
Akhirnya, isi file virtual host kita akan terlihat sebagai berikut:
/etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerAdmin admin@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Simpan dan tutup file ini.
Running several name-based web sites on a single IP address.
Your server has multiple hostnames that resolve to a single address, and you want to respond differently for www.example.com
and www.example.org
.
Creating virtual host configurations on your Apache server does not magically cause DNS entries to be created for those host names. You must have the names in DNS, resolving to your IP address, or nobody else will be able to see your web site. You can put entries in your hosts
file for local testing, but that will work only from the machine with those hosts
entries.
# Ensure that Apache listens on port 80
Listen 80
<VirtualHost *:80>
DocumentRoot "/www/example1"
ServerName www.example.com # Other directives here
</VirtualHost><VirtualHost *:80>
DocumentRoot "/www/example2"
ServerName www.example.org # Other directives here
</VirtualHost>
The asterisks match all addresses, so the main server serves no requests. Due to the fact that the virtual host with ServerName www.example.com
is first in the configuration file, it has the highest priority and can be seen as the default or primary server. That means that if a request is received that does not match one of the specified ServerName
directives, it will be served by this first <VirtualHost>
.
Name-based hosts on more than one IP address.
Any of the techniques discussed here can be extended to any number of IP addresses.
The server has two IP addresses. On one (172.20.30.40
), we will serve the "main" server, server.example.com
and on the other (172.20.30.50
), we will serve two or more virtual hosts.
Listen 80# This is the "main" server running on 172.20.30.40
ServerName server.example.com
DocumentRoot "/www/mainserver"<VirtualHost 172.20.30.50>
DocumentRoot "/www/example1"
ServerName www.example.com # Other directives here ...
</VirtualHost><VirtualHost 172.20.30.50>
DocumentRoot "/www/example2"
ServerName www.example.org # Other directives here ...
</VirtualHost>
Any request to an address other than 172.20.30.50
will be served from the main server. A request to 172.20.30.50
with an unknown hostname, or no Host:
header, will be served from www.example.com
.
Serving the same content on different IP addresses (such as an internal and external address).
The server machine has two IP addresses (192.168.1.1
and 172.20.30.40
). The machine is sitting between an internal (intranet) network and an external (internet) network. Outside of the network, the name server.example.com
resolves to the external address (172.20.30.40
), but inside the network, that same name resolves to the internal address (192.168.1.1
).
The server can be made to respond to internal and external requests with the same content, with just one <VirtualHost>
section.
<VirtualHost 192.168.1.1 172.20.30.40>
DocumentRoot "/www/server1"
ServerName server.example.com
ServerAlias server
</VirtualHost>
Now requests from both networks will be served from the same <VirtualHost>
.
On the internal network, one can just use the name server
rather than the fully qualified host name server.example.com
.
Note also that, in the above example, you can replace the list of IP addresses with *
, which will cause the server to respond the same on all addresses.
Running different sites on different ports.
You have multiple domains going to the same IP and also want to serve multiple ports. The example below illustrates that the name-matching takes place after the best matching IP address and port combination is determined.
Listen 80
Listen 8080<VirtualHost 172.20.30.40:80>
ServerName www.example.com
DocumentRoot "/www/domain-80"
</VirtualHost><VirtualHost 172.20.30.40:8080>
ServerName www.example.com
DocumentRoot "/www/domain-8080"
</VirtualHost><VirtualHost 172.20.30.40:80>
ServerName www.example.org
DocumentRoot "/www/otherdomain-80"
</VirtualHost><VirtualHost 172.20.30.40:8080>
ServerName www.example.org
DocumentRoot "/www/otherdomain-8080"
</VirtualHost>
IP-based virtual hosting
The server has two IP addresses (172.20.30.40
and 172.20.30.50
) which resolve to the names www.example.com
and www.example.org
respectively.
Listen 80<VirtualHost 172.20.30.40>
DocumentRoot "/www/example1"
ServerName www.example.com
</VirtualHost><VirtualHost 172.20.30.50>
DocumentRoot "/www/example2"
ServerName www.example.org
</VirtualHost>
Requests for any address not specified in one of the <VirtualHost>
directives (such as localhost
, for example) will go to the main server, if there is one.
Mixed port-based and ip-based virtual hosts
The server machine has two IP addresses (172.20.30.40
and 172.20.30.50
) which resolve to the names www.example.com
and www.example.org
respectively. In each case, we want to run hosts on ports 80 and 8080.
Listen 172.20.30.40:80
Listen 172.20.30.40:8080
Listen 172.20.30.50:80
Listen 172.20.30.50:8080<VirtualHost 172.20.30.40:80>
DocumentRoot "/www/example1-80"
ServerName www.example.com
</VirtualHost><VirtualHost 172.20.30.40:8080>
DocumentRoot "/www/example1-8080"
ServerName www.example.com
</VirtualHost><VirtualHost 172.20.30.50:80>
DocumentRoot "/www/example2-80"
ServerName www.example.org
</VirtualHost><VirtualHost 172.20.30.50:8080>
DocumentRoot "/www/example2-8080"
ServerName www.example.org
</VirtualHost>
Mixed name-based and IP-based vhosts
Any address mentioned in the argument to a virtualhost that never appears in another virtual host is a strictly IP-based virtual host.
Listen 80
<VirtualHost 172.20.30.40>
DocumentRoot "/www/example1"
ServerName www.example.com
</VirtualHost><VirtualHost 172.20.30.40>
DocumentRoot "/www/example2"
ServerName www.example.org
</VirtualHost><VirtualHost 172.20.30.40>
DocumentRoot "/www/example3"
ServerName www.example.net
</VirtualHost># IP-based
<VirtualHost 172.20.30.50>
DocumentRoot "/www/example4"
ServerName www.example.edu
</VirtualHost><VirtualHost 172.20.30.60>
DocumentRoot "/www/example5"
ServerName www.example.gov
</VirtualHost>
Using Virtual_host
and mod_proxy together
The following example allows a front-end machine to proxy a virtual host through to a server running on another machine. In the example, a virtual host of the same name is configured on a machine at 192.168.111.2
. The ProxyPreserveHost On
directive is used so that the desired hostname is passed through, in case we are proxying multiple hostnames to a single machine.
<VirtualHost *:*>
ProxyPreserveHost On
ProxyPass "/" "http://192.168.111.2/"
ProxyPassReverse "/" "http://192.168.111.2/"
ServerName hostname.example.com
</VirtualHost>
Using _default_
vhosts
_default_
vhosts for all ports
Catching every request to any unspecified IP address and port, i.e., an address/port combination that is not used for any other virtual host.
<VirtualHost _default_:*>
DocumentRoot "/www/default"
</VirtualHost>
Using such a default vhost with a wildcard port effectively prevents any request going to the main server.
A default vhost never serves a request that was sent to an address/port that is used for name-based vhosts. If the request contained an unknown or no Host:
header it is always served from the primary name-based vhost (the vhost for that address/port appearing first in the configuration file).
You can use AliasMatch
or RewriteRule
to rewrite any request to a single information page (or script).
_default_
vhosts for different ports
Same as setup 1, but the server listens on several ports and we want to use a second _default_
vhost for port 80.
<VirtualHost _default_:80>
DocumentRoot "/www/default80"
# ...
</VirtualHost><VirtualHost _default_:*>
DocumentRoot "/www/default"
# ...
</VirtualHost>
The default vhost for port 80 (which must appear before any default vhost with a wildcard port) catches all requests that were sent to an unspecified IP address. The main server is never used to serve a request.
_default_
vhosts for one port
We want to have a default vhost for port 80, but no other default vhosts.
<VirtualHost _default_:80>
DocumentRoot "/www/default"
...
</VirtualHost>
A request to an unspecified address on port 80 is served from the default vhost. Any other request to an unspecified address and port is served from the main server.
Any use of *
in a virtual host declaration will have higher precedence than _default_
.
Migrating a name-based vhost to an IP-based vhost
The name-based vhost with the hostname www.example.org
(from our name-based example, setup 2) should get its own IP address. To avoid problems with name servers or proxies who cached the old IP address for the name-based vhost we want to provide both variants during a migration phase.
The solution is easy, because we can simply add the new IP address (172.20.30.50
) to the VirtualHost
directive.
Listen 80
ServerName www.example.com
DocumentRoot "/www/example1"<VirtualHost 172.20.30.40 172.20.30.50>
DocumentRoot "/www/example2"
ServerName www.example.org
# ...
</VirtualHost><VirtualHost 172.20.30.40>
DocumentRoot "/www/example3"
ServerName www.example.net
ServerAlias *.example.net
# ...
</VirtualHost>
The vhost can now be accessed through the new address (as an IP-based vhost) and through the old address (as a name-based vhost).

Using the ServerPath
directive
We have a server with two name-based vhosts. In order to match the correct virtual host a client must send the correct Host:
header. Old HTTP/1.0 clients do not send such a header and Apache has no clue what vhost the client tried to reach (and serves the request from the primary vhost). To provide as much backward compatibility as possible we create a primary vhost which returns a single page containing links with an URL prefix to the name-based virtual hosts.
<VirtualHost 172.20.30.40>
# primary vhost
DocumentRoot "/www/subdomain"
RewriteEngine On
RewriteRule "." "/www/subdomain/index.html"
# ...
</VirtualHost><VirtualHost 172.20.30.40>
DocumentRoot "/www/subdomain/sub1"
ServerName www.sub1.domain.tld
ServerPath "/sub1/"
RewriteEngine On
RewriteRule "^(/sub1/.*)" "/www/subdomain$1"
# ...
</VirtualHost><VirtualHost 172.20.30.40>
DocumentRoot "/www/subdomain/sub2"
ServerName www.sub2.domain.tld
ServerPath "/sub2/"
RewriteEngine On
RewriteRule "^(/sub2/.*)" "/www/subdomain$1"
# ...
</VirtualHost>
Due to the ServerPath
directive a request to the URL http://www.sub1.domain.tld/sub1/
is always served from the sub1-vhost.
A request to the URL http://www.sub1.domain.tld/
is only served from the sub1-vhost if the client sent a correct Host:
header. If no Host:
header is sent the client gets the information page from the primary host.
Please note that there is one oddity: A request to http://www.sub2.domain.tld/sub1/
is also served from the sub1-vhost if the client sent no Host:
header.
The RewriteRule
directives are used to make sure that a client which sent a correct Host:
header can use both URL variants, i.e., with or without URL prefix.
Salin Virtual Host yang Sudah Jadi dan Atur Isinya Untuk Domain Kedua
Sekarang kita sudah memiliki file virtual host untuk domain pertama, dan kita bisa mengaturnya untuk domain yang kedua dengan menyalin dan menyesuaikan isinya. Mari kita mulai dengan menyalin file tadi:
sudo cp /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-available/test.com.conf
Buka file yang sudah disalin sebagai root:
sudo nano /etc/apache2/sites-available/test.com.conf
Sekarang kita perlu memodifikasi semua informasi agar sesuai dengan domain yang kedua. Setelah selesai, isi file yang kedua seharusnya seperti berikut ini:
/etc/apache2/sites-available/test.com.conf
<VirtualHost *:80>
ServerAdmin admin@test.com
ServerName test.com
ServerAlias www.test.com
DocumentRoot /var/www/test.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Simpan dan tutup.
Langkah Kelima — Mengaktifkan File Virtual Host yang Baru
Sekarang setelah kita membuat file virtual host yang baru, kita harus mengaktifkannya. Apache memiliki tool khusus untuk melakukan hal ini.
Kita akan menggunakan a2ensite
untuk mengaktifkan kedua website tadi seperti ini:
sudo a2ensite example.com.conf
sudo a2ensite test.com.conf
Lalu, nonaktifkan konfigurasi default di 000-default.conf
:
sudo a2dissite 000-default.conf
Setelah selesai, restart Apache untuk mendapatkan efeknya:
sudo systemctl restart apache2
Dalam dokumentasi lain, kita juga dapat merestart Apache menggunakan perintah service
:
sudo service apache2 restart
Perintah ini akan memberikan hasil yang sama namun kita tidak melihat keluaran seperti yang ada di sistem lain karena perintah service
merupakan pembungkus untuk perintah systemctl
.
Langkah Keenam — Mengatur File Host Lokal (Tambahan)
Jika belum memiliki nama domain untuk menguji prosedur tadi kita dapat menggunakan domain contoh menggunakan file hosts
yang ada di komputer lokal.
File ini akan memotong semua request untuk domain yang telah dikonfigurasi ke alamat IP tertentu.
Pastikan langkah ini dilakukan di komputer lokal bukan di server:
sudo nano /etc/hosts
Pengguna Windows dapat membaca panduan di sini .
Detail yang diperlukan adalah alamat IP publik dari server VPS dengan nama domain yang diinginkan.
Dalam tutorial ini, kita asumsikan alamat IP VPS ada di 111.111.111.111
(bisa diubah menjadi 127.0.0.1
jika mengikuti tutorial ini menggunakan komputer lokal saja tanpa VPS):
/etc/hosts
127.0.0.1 localhost
127.0.1.1 guest-desktop
111.111.111.111 example.com
111.111.111.111 test.com
File ini akan mengarahkan semua request ke example.com
dan test.com
menuju alamat 111.111.111.111
. Langkah ini dapat dilakukan jika ingin menguji virtual host dan bukan pemilik domain yang dipakai.
Simpan dan tutup file ini.
Langkah Ketujuh — Uji Hasilnya
Setelah virtual host selesai dikonfigurasi, sekarang buka browser dan arahkan ke alamat:
http://example.com
Kita seharusnya akan melihat halaman yang seperti ini:

Jika kita mengunjungi situs yang kedua
http://test.com
Maka kita juga akan melihat pesan sebagai berikut:

Jika kedua situs bekerja dengan benar, maka itu artinya kita sudah berhasil melakukan konfigurasi dua virtual host di satu server yang sama.
Jika sudah selesai dan virtualhost sudah bekerja, kita perlu menghapus dua baris yang ditambahkan ke file hosts
. Penghapusan ini untuk mencegah agar tidak file hosts
tidak berisi baris-baris yang tidak diperlukan.