Pembuatan Image MySQL-Server di Docker


A. Container tak persisten
B. Container persisten dengan Data Volume
C. Container persisten dengan Data-only Container

A. Container Tak Persisten

1. Buat direktori bernama “mysql-server”, cd (masuk) ke dalam direktori tersebut.
2. Buat file Dockerfile dengan isi sebagai berikut:

#Dockerfile untuk membuat Image MySQL server
FROM ubuntu

RUN apt-get update && apt-get -y install mysql-client mysql-server
RUN sed -i ‘s/^bind-address/#bind-adress/g’ /etc/mysql/my.cnf
RUN /etc/init.d/mysql start && echo “GRANT ALL ON *.* TO admin@’%’ IDENTIFIED BY ‘admin123’ WITH GRANT OPTION; FLUSH PRIVILEGES” | mysql -u root

EXPOSE 3306

CMD [“/usr/bin/mysqld_safe”]

Catatan:

Baris RUN sed -i ‘s/^bind-address/#bind-adress/g’ /etc/mysql/my.cnf dapat diganti dengan ADD ./my.cnf /etc/mysql/my.cnf. Ini dilakukan terutama jika ada banyak baris konfigurasi di dalam file my.cnf.

3. Buat image dengan perintah docker build dan jalankan:

docker build -t img-mysqlserver .
docker run -d -p 3306:3306 img-mysqlserver

4. Menguji MySQL Server.

Kita dapat mengakses MySQL Server tersebut, baik dari Host maupun container lain memanfaatkan socket TCP (port 3306):

# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker 11267 root 4u IPv6 51821 0t0 TCP *:mysql (LISTEN)

# mysql -u admin –protocol tcp -padmin -e “show databases”

+——————–+
| Database |
+——————–+
| information_schema |
| mysql |
| performance_schema |
+——————–+

Bagaimana dengan persistensi? Apakah semua data dan perubahan terhadapnya tetap tersimpan meskipun container telah di-stop? INGAT semua data yang di-update di dalam container TIDAK tersimpan di dalam image.

Ada 2 cara untuk membuat perubahan data di dalam Container menjadi persisten (tetap ada meski container telah tiada):

* Data volumes: A data volume is a specially-designated directory within one or more containers that bypasses the Union File System to provide several useful features for persistent or shared data

* Data volume containers: If you have some persistent data that you want to share between containers, or want to use from non-persistent containers, it’s best to create a named Data Volume Container, and then to mount the data from it.

Lebih detailnya, silakan akses panduan di https://docs.docker.com/userguide/dockervolumes/

B. Container Persisten dengan Data Volume

Jika image mysql-server di atas dijalankan dengan menggunakan parameter -v:

docker run -d -p 3306:3306 -v /data/mysql:/var/lib/mysql img-mysqlserver

maka akan mengakibatkan terhapusnya data sistem dari mysql (tabel-tabel dengan metadatanya), SOLUSINYA?

Berikut ini adalah langkah-langkah membuat image (moyangnya container) yang mampu menyediakan persistensi data:

1. Membuat Skrip Inisiasi Ulang Database

Kita harus membuat script untuk menginisiasi ulang database dimana sudah tidak ada metadata yang tersedia. Skrip ini dapat ditambahkan ke dalam Dockerfile dengan perintah ADD.

#!/bin/bash
#script run.sh untuk inisiasi ulang metadata database mysql

#jika direktori /data/mysql belum ada, database kosong
if [ ! -d /data/mysql ]; then #setup mysqldb
mysql_install_db –datadir=/data/mysql
echo “=> Starting MySQL.”
/usr/bin/mysqld_safe –datadir=/data/mysql > /dev/null 2>&1 &

RET=1
while [[ $RET -ne 0 ]]; do
echo “=> Waiting for confirmation of MySQL service startup”
sleep 5
mysql -uroot -e “status” > /dev/null 2>&1
RET=$?
done

PASS=’admin123′
echo “=> Creating MySQL user.”
mysql -uroot -e “CREATE USER ‘admin’@’%’ IDENTIFIED BY ‘$PASS'”
mysql -uroot -e “GRANT ALL PRIVILEGES ON *.* TO ‘admin’@’%’ \
WITH GRANT OPTION”

echo “=> Shutting down after setup.”
mysqladmin -uroot shutdown
#jika /data/mysql telah ada, database telah ada
else
echo “=> continuing with an existing mysql setup”
fi
echo “=> Running MySQL Server”
exec mysqld_safe –datadir=/data/mysql

2. Membuat Dockerfile

Berikut ini adalah Dockerfile (versi revisi) yang memanggil script run.sh:

#Dockerfile
#File skrip yang dipanggil bernama run.sh

FROM ubuntu:14.04

RUN apt-get update && apt-get -y install mysql-client mysql-server

VOLUME [“/data”]

ADD my.cnf /etc/mysql/conf.d/my.cnf
ADD run.sh /run.sh
RUN chmod +x run.sh

EXPOSE 3306

ENTRYPOINT [“/run.sh”]

3. Buat file my.cnf yang menyimpan konfigurasi MySQL.

Secara default, MySQL server hanya menerima koneksi dari localhost. Baris bind-address=0.0.0.0 memungkinkan MySQL server menerima koneksi dari manapun.

#my.cnf
[mysqld]
bind-address=0.0.0.0

Jadi ada 3 file di dalam direktori ~/husni/mysql-server: Dockerfile, my.cnf dan run.sh.

4. Membuat image, misalnya bernama img-mypersistentserver dengan perintah build.

docker build -t img-mypersistentserver .

5. Membuat direktori penampung data persistent dari MySQL server, misalnya ~/docker/mydata:

mkdir ~/docker/mydata
6. Menjalankan image img-mypersistentserver dengan run berikut:

docker run -d -p 3306:3306 -v ~/docker/mydata/:/data/ –name co-mysqlserver img-mypersistentserver

7. Pengujian: Mengakses database tersebut, membuat database, tabel dan memasukkan beberapa baris data.

* Membuat container dari salah satu image yang mempunyai program client mysql (misalnya image img-mypersistentserver) dan bangun koneksi ke MySQL server tersebut (password: “admin123″):

docker run -it –name co-mysqlclient –link co-mysqlserver:db \
–entrypoint=”mysql” img-mypersistentserver -u admin -p -h db

* Membuat database db_01 dan tabel tb_01

Berikut ini adalah contoh hasil eksekusi perintah di atas (serta langkah-langkah pembuatan database db_01 dan tabel tb_01):

Enter password: “admin123”
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| mysql |
| performance_schema |
+——————–+
3 rows in set (0.00 sec)

mysql> create database db_01;
Query OK, 1 row affected (0.00 sec)

mysql> use db_01;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> CREATE TABLE tb_01 (No INT, Nama VARCHAR(100), Email VARCHAR(100));
Query OK, 0 rows affected (0.11 sec)

mysql> INSERT INTO tb_01 VALUES (1, ‘Husni Ilyas’, ‘husni@if.trunojoyo.ac.id’), (2, ‘Muda Intan’, ‘mintan@yahoo.com’), (3, ‘Azzam Altaf’, ‘azzamalt@gmail.com’), (4, ‘Rohmi Nur Hidayah’, ‘rnhidayah@gmail.com’);
Query OK, 4 rows affected (0.42 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> show tables;
+———————+
| Tables_in_db_docker |
+———————+
| tb_01 |
+———————+
1 row in set (0.00 sec)

mysql> SELECT * FROM tb_01 WHERE Email LIKE ‘%gmail.com’;
+——+——————-+———————+
| No | Nama | Email |
+——+——————-+———————+
| 3 | Azzam Altaf | azzamalt@gmail.com |
| 4 | Rohmi Nur Hidayah | rnhidayah@gmail.com |
+——+——————-+———————+
2 rows in set (0.00 sec)

mysql> quit;
Bye

* Sekarang telah keluar dari program mysql dan container co-mysqlclient. Hapus container co-mysqlclient (docker rm co-mysqlclient).

Apakah data tersebut benar-benar tersimpan di dalam ~/docker/mydata? (persisten). Mari coba login lagi ke server MySQL:

* Mengakses MySQL Server (lagi).

Jalankan kembali container bernama co-mysqlclient (panah ke atas + Enter).

mysql> show databases;
+——————–+
| Database |
+——————–+
| information_schema |
| db_01 |
| mysql |
| performance_schema |
+——————–+
4 rows in set (0.04 sec)

Ternyata data tetap ada di MySQL, tidak hilang walaupun container telah ditutup/distop!

8. Pengujian: Mengakses database MySQL dari aplikasi PHP

* Buat file PHP sederhana (misal: index.php), misalnya:

connect_error) {
die(“Connection failed: ” . $conn->connect_error);
}

$sql = “SELECT No, Nama, Email FROM tb_01”;
$result = $conn->query($sql);

if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo “No: ” . $row[“No”]. ” – Nama: ” . $row[“Nama”]. ” ” . $row[“Email”]. “
“;
}
} else {
echo “0 results”;
}
$conn->close();
?>

Simpan file tersebut ke dalam ~/docker/webdata/.

* Jalankan image img-webserver yang telah dibuat sebelumnya:

sudo docker run -d -v ~/docker/webdata:/var/www -p 80:80 \
–name co-testweb img-webserver

* Buka web browser, akses ke IP_ADDRESS_HOST atau Nama_Host. Gambar berikut memperlihatkan hasil pada web browser Firefox:

curl localhost
No: 1 – Nama: Husni Ilyas husni@if.trunojoyo.ac.id
No: 2 – Nama: Muda Intan mintan@yahoo.com
No: 3 – Nama: Azzam Altaf azzamalt@gmail.com
No: 4 – Nama: Rohmi Nur Hidayah rnhidayah@gmail.com

* Memanfaatkan link.

Hentikan (stop) dan hapus container co-testweb tersebut. Coba jalankan image img-webserver dengan cara berikut:

sudo docker run -d -v ~/docker/webdata:/var/www \
–link co-mysqlserver:db -p 80:80 –name co-testweb img-webserver

Kemudian edit file index.php dan ganti baris:

$servername = “IP_ADDRESS_HOST”;

menjadi:

$servername = “db”;

Buka web browser, akses ke IP_ADDRESS_HOST. Perhatikan apa yang terjadi!
C. Container Persisten dengan Data-only Container

Pada pendekatan Data Volume, container MySQL-Server langsung mengakses direktori ~/docker/mydata memanfaatkan parameter -v. Pada teknik Data-only Container, sebuah container khusus menangani Data (tidak selain data) disiapkan terlebih dahulu. Semua akses ke Data Volume harus dilakukan via container data-only tersebut. Keuntungan utama adalah portabilitas (kata Docker).

Langkah-langkah pembuatan imagenya hampir sama dengan sebelumnya, berikut ini adalah contohnya:

1. Lakukan seperti bagian B sehingga ada satu direktori yang berisi 3 file: Dockerfile, run.sh dan my.cnf. Pastikan juga adanya direktori data ~/docker/mydata.

2. Buat image, misalnya bernama img-mypersistentserver2:

sudo docker build -t img-mypersistentserver2 .

3. Jalankan image tertentu (misalnya: ubuntu saja) untuk membuat Data-only container:

sudo docker run -d -v ~/docker/mydata:/data –name co-dataonly \
ubuntu:14.04 true

4. Jalankan image img-mypersistentserver2 dan akses ~/docker/mydata via Data-only container co-dataonly:

sudo docker run -d –volumes-from co-dataonly \
–name co-mysqlserver \
img-mypersistentserver2

Catatan:

Perhatikan opsi khusus –volumes-from. Kita meminta container co- mysqlserver menggunakan data volume dari container bernama co-dataonly, yaitu container Data-only. Sesungguhnya yang terjadi adalah direktori ~/docker/mydata hadir sebagai /data di dalam container co- mysqlserver. Skrip run.sh membuat ulang database mysql sehingga jika kita menghapus container, data tetap ada di sana. Itulah pentingnya direktori /data/mysql🙂.

Kita dapat melihat apakah container co- mysqlserver berjalan dengan sudo docker ps. Kita juga dapat melihat apa yang terjadi dalam container tersebut dengan sudo docker log -f co-mysqlserver. Apa yang terlihat adalah pesan yang dikeluarkan oleh skrip run.sh dan setup. Tekan Ctrl+C untuk keluar dari tampilan log tersebut.

Anehnya, kita tidak melihat container co-dataonly dalam status running. That’s alright, memang tidak harus berjalan. Kita dapat melihat bahwa co-dataonly ada dengan menjalankan perintah sudo docker ps -a.

5. Pengujian

* Mengakses MySQL Server: membuat database dan tabel

Jalankan image img-mypersistentserver (atau image lain yang ada program mysql di dalamnya) menjadi container (untuk digunakan secara interaktif) dengan memanfaatkan parameter –link:

sudo docker run -it –link co-mysqlserver:db –name co-mysqlclient \
–entrypoint=”mysql” img-mypersistentserver -u admin -p -h db

Masukkan “admin123″ sebagai password sehingga diperoleh prompt mysql>. Seperti sebelumnya, database db_01 dan tabel tb_01 dapat dibuatkan sebagai percobaan.

mysql> create database db_01
Query OK, 1 row affected (0.02 sec)

Masukkan beberapa baris record ke dalam tb_01. Jika telah selesai, silakan keluar dari bash dan containernya. Jika perlu, hapus container co-mysqlclient.

Catatan:

Kita melewatkan dua opsi kepada perintah docker run (di atas). Pertama –link, kedua –entrypoint. Di dalam Dockerfile dari image img-mypersistentserver2, kita menyebutkan run.sh sebagai ENTRYPOINT sehingga skrip run.sh berjalan saat container dimulai. Di sini kita membuat agar program mysql dijalankan sebagai ganti run.sh atau dengan kata lain menggantikan entrypoint default.

Opsi –entrypoint juga dapat digunakan sebagai sarana troubleshoot/melihat ke dalam container. Kita dapat menggunakan bash sebagai –entrypoint dan menggunakannya. Sebagai contoh:

sudo docker run -i -t –entrypoint=”bash” mysql -i

…dan kita berada console pada container.

* Jalankan image Web server (apache2 + php5):

sudo docker run -d -v ~/docker/webdata:/var/www \
–link co-mysqlserver:db -p 80:80 –name co-testweb img-webserver

Buka web browser dan akses http://IP_ADDRES_HOST dan perhatikan apa yang terjadi?!

Versi PDF dari tutorial ini dapat diperoleh di SINI. Sekian tutorial ini, semoga bermanfaat🙂

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: