Docker Container adalah sebuah “virtualisasi” sebuah sistem/aplikasi yang berjalan pada Docker Engine. Secara default, sistem/aplikasi yang berjalan pada Docker Container akan ter “isolasi” dari hostnya. Anda tidak dapat serta merta dengan mudah mengakses port aplikasi yang berada pada host. Untuk mengaksesnya port aplikasi pada host anda harus membuka Firewall dan konfigurasi lainnya.
Pada tutorial kali ini saya akan membahas cara sebuah Docker Container PHP mengakses MySQL yang berada pada host/terinstall secara langsung. Tahapan yang harus kita lakukan dalam tutorial kali ini adalah: konfigurasi MySQL agar di akses secara “remote”, konfigurasi Docker Container, dan membuka Firewall pada host.
1. Konfigurasi MySQL agar dapat di akses secara “Remote”
Pertama-tama, buka konfigurasi MySQL anda pada yang ada pada host dengan perintah,
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
Kemudian cari line “bind-address“. Pada konfigurasi awal, biasanya nilainya masih “127.0.0.1” artinya MySQL hanya dapat diakses melalui IP host saja.
bind-address = 127.0.0.1
Ganti nilainya menjadi “0.0.0.0“.
bind-address = 0.0.0.0
Setelah anda ganti, artinya MySQL host anda dapat diakses secara remote dari IP manapun. Jangan khawatir, karena kita akan membatasi akses tersebut pada Firewall. Setelah itu reset service MySQL anda.
service mysql restart
Jika tidak ada error, artinya konfigurasi baru anda telah berhasil diimplementasi. Selanjutnya, kita akan membutuhkan akun MySQL untuk mengakses secara remote.
Untuk langkah selanjutnya, anda harus membuat user MySQL baru dengan host “%” agar anda dapat mengakses MySQL anda melalui “remote”. Untuk pembuatan user baru ini pertama-tama masuk ke shell MySQL anda,
mysql -u root -p
Masukan sesuai dengan konfigurasi MySQL anda. Kemudian buat user baru dengan host “%”
mysql> CREATE USER 'root_docker'@'%' IDENTIFIED BY 'password';
Anda dapat mengganti username “root_docker” dan “password” sesuai keinginan anda. Setelah itu berilah hak akses ke MySQL user yang baru anda buat.
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root_docker'@'%' WITH GRANT OPTION;
Pemberian hak akses root ini sebenarnya BERBAHAYA. Oleh karena itu, pastikan anda telah menyesuaikan hak akses yang akan anda berikan kepada user yang baru sesuai dengan kebutuhan.
Setelah pemberian privilege selesai, lakukan flush.
mysql> FLUSH PRIVILEGES;
Setelah itu, anda dapat keluar dari shell MySQL anda. Dan proses konfigurasi MySQL telah selesai. Langkah selanjutnya konfigurasi pada Docker Container.
2. Konfigurasi Docker Container
Salah satu hal inti agar Docker Container anda dapat mengakses MySQL host adalah IP Address dari jaringan Docker Container anda. Sebab nantinya IP Address tersebut yang akan kita whitelist pada Firewall kita. Oleh karena itu pastikan Docker Container telah menggunakan network yang telah tentukan.
Pertama-tama buatlah network pada Docker anda,
docker network create -d bridge main-network
Jika sebelumnya sudah membuat default network, anda dapat melewati perintah diatas. Setelah menentukan network yang akan kita whitelist, langkah selanjutnya anda harus menghubungkan Docker Container anda pada Network tersebut.
Jika menggunakan perintah “docker container run” tambahkan perintah network.
docker container run --network=main-network --add-host=host.docker.internal:host-gateway ...
Jika menggunakan docker compose file, tambah konfigurasi network seperti.
...
extra_hosts:
- "host.docker.internal:host-gateway"
...
networks:
default:
name: main-network
external: true
Setelah itu, lakukan inspect pada network yang telah anda buat dengan perintah,
docker inspect main-network
Cari alamat subnet dari Network tersebut seperti pada contoh berikut.
[
{
"Name": "main-network",
"...",
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"..."
}
]
Setelah menemukan alamat Network tersebut, simpan alamat tersebut karna nantinya akan kita gunakan untuk whitelist network pada firewall kita.
3. Membuka Firewall pada host
Setelah anda mendapatkan alamat subnet jaringan anda, langkah selanjutnya adalah menambahkan whitelist pada firewall agar subnet jaringan anda dapat mengakses MySQL pada Host. Cara menambahkan firewall pada host cukup mudah, gunakan perintah dibawah ini dan sesuaikan dengan alamat subnet anda,
sudo ufw allow from 172.18.0.0/16 to any port 3306
Setelah itu anda dapat mencoba mengakses MySQL dengan menggunakan PHP Script yang anda jalankan dengan container.
$mysqli = new mysqli("host.docker.internal", "root_docker", "password-mysql-anda");
var_dump($mysqli);
echo $mysqli->host_info . "\n";
Jika output dari script PHP anda seperti di bawah ini, artinya konfigurasi anda telah berhasil.
object(mysqli)#1 (18) { ["affected_rows"]=> int(0) ["client_info"]=> string(14) "mysqlnd 7.4.29" ["client_version"]=> int(70429) ["connect_errno"]=> int(0) ["connect_error"]=> NULL ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["field_count"]=> int(0) ["host_info"]=> string(31) "host.docker.internal via TCP/IP" ["info"]=> NULL ["insert_id"]=> int(0) ["server_info"]=> string(6) "8.0.25" ["server_version"]=> int(80025) ["sqlstate"]=> string(5) "00000" ["protocol_version"]=> int(10) ["thread_id"]=> int(11) ["warning_count"]=> int(0) } host.docker.internal via TCP/IP
Selamat, anda telah berhasil menghubungkan Container anda dengan MySQL pada host.