ในตอนที่แล้วเราใช้งาน openldap ด้วยคำสั่ง เช่น ldapsearch หรือ ldapadd ได้แล้ว วันนี้เราจะเรียนรู้การใช้ dockerfile สร้าง image ชื่อ phpldapadmin เพื่อใช้เป็น web interface ในการเข้าไปจัดการ LDAP database ของ container ชื่อ openldap โดยที่ phpLDAPadmin นี้คือการรัน php บน apache2 แล้วเราจะติดต่อระหว่าง container กันได้อย่างไร มาดูกันครับ
เช่นเดียวกับครั้งที่แล้ว ผมจะแยกเป็น 3 ขั้นตอน คือ 1.ขั้นตอนเตรียมไฟล์ที่เกี่ยวข้อง 2.ขั้นตอนสร้างไฟล์ dockerfile และ 3.ขั้นตอนการรัน container
1.ขั้นตอนเตรียมไฟล์ที่เกี่ยวข้อง
ให้แน่ใจว่าอยู่ที่ home directory ให้ใช้คำสั่งนี้
$ cd
สร้างไดเรกทอรีของ image ที่เราจะสร้าง
$ mkdir phpldapadmin $ cd phpldapadmin $ mkdir src
เราจะเตรียมไฟล์ชื่อ apache2-foreground ให้เปิดไฟล์จากที่นี่ https://github.com/docker-library/php/blob/master/5.6/jessie/apache/apache2-foreground แล้วคัดลอกทุกบรรทัด นำมาสร้างไฟล์ ด้วยเอติเตอร์ที่ถนัด เช่น vi หรือ nano ก็ได้
$ vi ./src/apache2-foreground
2.ขั้นตอนสร้างไฟล์ dockerfile
ตอนนี้ก็มาถึงขั้นตอนการเขียน dockerfile ด้วยเอดิเตอร์ที่ถนัดเช่น vi หรือ nano ก็ได้
$ vi dockerfile # Composer: Wiboon Warasittichai FROM ubuntu:16.04 # Change apt source RUN sed -i 's/\/us.archive/\/th.archive/g' /etc/apt/sources.list && \ sed -i 's/\/archive/\/th.archive/g' /etc/apt/sources.list # Update ubuntu, then install packages RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt install -y php-ldap phpldapadmin ldap-utils # Timezone Asia/Bangkok RUN apt-get install -y tzdata && \ ln -sf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime && \ dpkg-reconfigure -f noninteractive tzdata # Cleaning RUN apt-get autoremove -y && apt-get clean -y EXPOSE 80 CMD RUN ulimit -n 1024 ENV HNAME ${HNAME} ADD ./src/startup.sh /startup.sh COPY ./src/apache2-foreground /usr/local/bin/ RUN chmod +x /usr/local/bin/apache2-foreground ENTRYPOINT ["/bin/bash","/startup.sh"]
ภายในไฟล์ dockerfile เราได้อ้างถึงการนำไฟล์ชื่อ startup.sh ก็ให้สร้างไฟล์นี้ด้วย
$ vi ./src/startup.sh #!/bin/bash sed -i "s/127.0.0.1/$HNAME/g" /etc/phpldapadmin/config.php /usr/local/bin/apache2-foreground
จุดน่าสนใจในไฟล์ dockerfile ในตัวอย่างนี้ คือ เราจะเขียนอย่างไรเพื่อให้เราเปลี่ยนค่า 127.0.0.1 ในไฟล์ /etc/phpldapadmin/config.php ใน container ที่รันขึ้นมาได้อัตโนมัติ เราจึงต้องใช้ ENV ในการระบุว่า container openldap ที่รันอยู่นั้นใช้ IP อะไร แล้วเราก็นำ IP ใส่ลงไปในตัวแปร HNAME เพื่อจะติดต่อไปยัง container openldap ได้ถูกต้อง ผมจึงเพิ่มบรรทัดนี้
ENV HNAME ${HNAME}
3.ขั้นตอนการรัน container
สร้าง image ด้วยคำสั่งนี้
$ docker build -t phpldapadmin .
ก่อนจะรัน container phpldapadmin ต้องไม่ลืมว่า เราจะต้องรัน container openldap ด้วยคำสั่งนี้แล้ว
$ docker run -d -p 636:636 -p 389:389 --name openldap --volume oldata:/var/lib/ldap --volume olconfig:/etc/ldap/slapd.d openldap
รัน container และ ตรวจสอบ ด้วยคำสั่งนี้
$ LDAPSERVER=$(docker exec -it openldap cat /etc/hosts | tail -1 | cut -f1) && docker run -d -p 8080:80 --env HNAME=${LDAPSERVER} --name phpldapadmin phpldapadmin $ docker ps
อธิบายได้ดังนี้ container จะรันแบบ detach (-d) เปิด port 8080 ที่ Host เข้าไปยัง port 80 ที่ container ตั้งชื่อ(–name) ว่า phpldapadmin โดยกำหนดค่า ENV สำหรับตัวแปรที่ชื่อ HNAME ให้ใช้ IP จากไฟล์ /etc/hosts ใน container openldap และรันจาก image ชื่อ phpldapadmin
ทดสอบการเข้าใช้งานทาง web ไปที่ http://ldap.example.com:8080/phpldapadmin/ (เนื่องจาก VM ที่ใช้ทดสอบ คือ ubuntu ที่ได้ติดตั้ง XFCE desktop environment ไว้ด้วยทำให้สามารถใช้งาน web browser ได้ด้วย)
หลังจาก login แล้วจะเห็นข้อมูล LDAP และจัดการ LDAP database ได้
โปรดสังเกตว่าคำสั่ง docker run นั้น หากต้องการให้รันทำงานทุกครั้งที่เปิดเครื่อง เราจะสามารถใส่ option นี้เข้าไปได้ด้วย คือ –restart always ใส่หลังจากคำว่า docker run ก็ได้ครับ (ในตัวอย่างข้างต้น ผมไม่ได้ใส่ไว้ เพราะกำลังทดสอบ) หากเรา reboot เครื่อง container ทั้ง 2 ก็หายไปครับ
แต่เราก็สามารถลบ container ได้ทันที ดังนี้
$ docker stop phpldapadmin $ docker rm phpldapadmin $ docker stop openldap $ docker rm openldap
สรุปว่า ในตอนนี้ เรารู้วิธีการใช้ dockerfile สร้าง container 2 อัน อันแรกคือ LDAP database และอีกอันคือ php web program ที่จะติดต่อกับ LDAP database ด้วยการใช้ตัวแปร ENV ร่วมด้วย
ในตอนต่อไป เราจะมาเรียนรู้ การใช้ docker compose รันทั้ง 2 services นี้แทนการแยกสร้าง dockerfile และ run แยกกัน