ในกรณีใช้ VMWare/VirtualBox บางครั้งเราต้องการขยาย Disk ให้ Ubuntu มีพื้นที่มากขึ้น
Category: Linux (OS, shell script, etc)
-
Windows CRLF to Unix LF Issues in Cygwin Shell Script
เมื่อเรารัน shell script ของโปรแกรม Cygwin for Windows ซึ่งมีการเขียนคำสั่งไปตัดเอาข้อความผ่านคำสั่ง (Command Line) ของ Windows มาใส่ในตัวแปรของ shell script
เช่น ในตัวอย่างนี้คือคำสั่ง ipconfig เมื่อได้ข้อความที่ต้องการมาเราจะได้ \r แถมมาให้ด้วยต่อท้าย เพราะ Windows style line ending จะมี CRLF (\r\n) ในขณะที่ Linux style line ending จะมี LF (\n) เท่านั้น
น่าแปลกใจมากว่า เราเคยรัน shell script นี้ใน Windows 7 ใช้งานได้ แต่พอเป็น Windows 10 build 1709 มันรันไม่ได้
ปัญหา
เมื่อเปิด Cygwin Terminal ขึ้นมา จะได้เป็น bash shell
ในไฟล์ test.sh ดังตัวอย่างข้างล่างนี้ เมื่อสั่งรัน จะพบว่าพบข้อผิดพลาด ตัวแปร ZONEX จะไม่มีค่า ซึ่งจริง ๆ จะต้องได้คำว่า zone1
$ cat test.sh#!/bin/bash DHCPSERVER=$(ipconfig /all | grep -i "DHCP Server" | cut -d: -f2 | xargs) MAC=$(ipconfig /all | grep -A4 -i "^Ethernet Adapter Ethernet" | tail -1 | cut -d\: -f2 | tr - : | xargs) ZONEX=$(curl -s http://${DHCPSERVER}/dhcpd.txt | grep -i ${MAC} | awk '{print $2}' | cut -d'_' -f1) echo "DHCP SERVER is ${DHCPSERVER}" echo "MAC is ${MAC}" echo "Zone is ${ZONEX}"
สั่งรันดูผลลัพธ์ด้วยคำสั่ง bash test.sh
$ bash test.sh DHCP SERVER is 192.168.6.150 MAC is 50:7B:9D:30:2E:4B Zone is
ผมก็ตรวจสอบด้วยวิธีการ debug คือ เพิ่ม -x ดังตัวอย่างนี้
$ bash -x test.sh ++ ipconfig /all ++ grep -i 'DHCP Server' ++ cut -d: -f2 ++ xargs + DHCPSERVER=$'192.168.6.150\r' ++ ipconfig /all ++ grep -A4 -i '^Ethernet Adapter Ethernet' ++ tail -1 ++ cut -d: -f2 ++ tr - : ++ xargs + MAC=$'50:7B:9D:30:2E:4B\r' ++ curl -s $'http://192.168.6.150\r/dhcpd.txt' ++ grep -i $'50:7B:9D:30:2E:4B\r' ++ awk '{print $2}' ++ cut -d_ -f1 + ZONEX= ' echo 'DHCP SERVER is 192.168.6.150 DHCP SERVER is 192.168.6.150 ' echo 'MAC is 50:7B:9D:30:2E:4B MAC is 50:7B:9D:30:2E:4B + echo 'Zone is ' Zone is
จึงพบว่า ตัวแปร DHCPSERVER และ ตัวแปร MAC จะมี “/r” แถมมาให้ด้วย ซึ่งเป็นส่วนเกินที่ทำให้คำสั่งถัดไปทำงานผิดพลาดทำให้ได้ค่า ZONEX เป็น ว่างเปล่า
วิธีแก้ไข เราต้องใส่ option ” -o igncr ” หลังคำสั่ง bash เพื่อให้ตัด “/r” ออกไป
สั่งรันดูผลลัพธ์ด้วยคำสั่ง bash -o igncr test.sh
ผลลัพธ์คราวนี้ถูกต้องแล้ว
$ bash -o igncr test.sh DHCP SERVER is 192.168.6.150 MAC is 50:7B:9D:30:2E:4B Zone is zone1
วิธีแก้อีกวิธีคือ หากไม่ใส่ option ที่ว่านี้ เราก็ต้องไปแก้ไขบรรทัดคำสั่ง เพื่อเติม sed ‘s/\r$//’ ต่อท้าย เป็นการตัด /r ออกไปก่อนนำค่าที่ได้ไปใส่ในตัวแปร DHCPSERVER
เช่นDHCPSERVER=$(ipconfig /all | grep -i "DHCP Server" | cut -d: -f2 | xargs | sed 's/\r$//')
ซึ่งก็ทำได้เช่นกัน แต่ต้องแก้ไขไฟล์ shell script ซึ่งก็แล้วแต่ชอบวิธีไหน
Reference
https://stackoverflow.com/users/1010997/user1010997
https://stackoverflow.com/questions/11616835/r-command-not-found-bashrc-bash-profile
https://stackoverflow.com/questions/18608380/r-command-not-found -
วิธี upgrade Node.js ใน Bash ของ Windows 10 ให้เป็นรุ่นปัจจุบัน
ปัญหาคือ บน Windows 10 เราสามารถใช้ Windows Subsystem for Linux (WSL) หรือ Bash Shell ได้ ซึ่งจริงๆมันก็คือ Ubuntu 16.04.3
แต่ว่า เวลาจะใช้งาน Node.js ติดตั้งพวก Firebase, Angular อะไรพวกนี้ จะทำไม่ได้ เพราะรุ่นที่ให้มามันเก่ามาก
วิธีการคือ (Reference: https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions)
ใช้คำสั่งต่อไปนี้
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - apt-get install -y nodejs
ก็เรียบร้อย
-
วิธีติดตั้งระบบ Cyrus IMAP Cluster (Cyrus Murder)
ต่อจาก
Mail Clustering with Cyrus Murder และ How Cyrus Murder (Mail Clustering) work?คราวนี้ มาลง รายละเอียดทีละขั้นตอน
ระบบ Cyrus IMAP Cluster หรือ Cyrus Murder นี้ ประกอบด้วยเครื่องคอมพิวเตอร์ ขั้นต่ำ 3 เครื่อง คือ frontend, backend, mupdate ต่อไปนี้ จะเป็นวิธีการทำ แต่ละเครื่อง
Prerequisite
ทั้งหมดเป็น Ubuntu 16.04 Server, ทำการ update และ upgrade แล้ว และ เข้า SSH ด้วย user ที่สามารถ sudo ได้ และรุ่นของ cyrus-imapd, cyrus-murder ที่ใช้เป็น 2.4.18
ทุกเครื่อง มี user ชื่อ ‘cyrus’ และ ทำการตั้งรหัสผ่านไว้เรียบร้อย
เฉพาะเครื่องที่เป็น Backend จะต้องมี uesr ชื่อ ‘mailproxy’ และทำการตั้งรหัสผ่านไว้เรียบร้อย ด้วยอีก 1 คน
ในที่นี้ จะใช้ pam-ldap ติดตั้งใน Backend ทุกเครื่องMUPDATE ( mupdate1.example.com )
- ติดตั้ง cyrus-murder ด้วยคำสั่ง
sudo apt install cyrus-murder cyrus-common sasl2-bin
ระบบจะติดตั้งตั้งโปรแกรมที่เกี่ยวข้อง รวมถึง postfix ด้วย ให้เลือกเป็น No configuration ไป
- แก้ไขไฟล์ /etc/cyrus.conf ใน Section “SERVICES” ประมาณบรรทัดที่ 62 ให้ uncomment เพื่อได้บรรทัดนี้
mupdate cmd="mupdate -m" listen=3905 prefork=1
จุดสำคัญคือ mupdate -m คือ ตัวที่จะบอกว่า ทำหน้าที่เป็น MUPDATE Master
- แก้ไขไฟล์ /etc/imapd.conf เพื่อกำหนด admins ในที่นี้ให้ใช้ชื่อ cyrus โดยการ uncomment ประมาณบรรทัดที่ 55
และแก้ sasl_pwcheck_method เป็น saslauthdsasl_pwcheck_method: saslauthd sasl_mech_list: PLAIN admins: cyrus
- จากนั้น start ระบบขึ้นมา จะพบว่ามีการเปิด port 3905 รออยู่
sudo /etc/init.d/cyrus-imapd start netstat -nl | grep 3905
- แก้ไขไฟล์ /etc/default/saslauthd บรรทัดที่ 7
START=yes
แล้ว start saslauthd
sudo /etc/init.d/saslauthd start
BACKEND ( backend01.example.com)
- ติดตั้ง
sudo apt install cyrus-imapd cyrus-common cyrus-clients sasl2-bin
- แก้ไขไฟล์ /etc/imapd.conf โดยเพิ่มบรรทัดต่อไปนี้ไว้ท้ายไฟล์
#SASL sasl_pwcheck_method: saslauthd sasl_mech_list: PLAIN # MUPDATE servername: backend01.example.com admins: cyrus proxyservers: mailproxy lmtp_admins: mailproxy mupdate_server: mupdate.example.com mupdate_port: 3905 mupdate_username: cyrus mupdate_authname: cyrus mupdate_password: <secret>
- แก้ไข /etc/cyrus.conf
ใน START section ให้ uncommentmupdatepush cmd="/usr/sbin/cyrus ctl_mboxlist -m"
- เพิ่มส่วนนี้ ท้ายไฟล์ /etc/services ด้วย
#MUPDATE mupdate 3905/tcp # MUPDATE mupdate 3905/udp # MUPDATE
- *** ติดตั้ง PAM LDAP
sudo apt-get install ldap-auth-client nscd
ตั้งค่าต่อไปนี้
LDAP server Uniform Resource Identifier: ldap://ldap.your.domain/ Distinguished name of the search base: dc=example,dc=com LDAP version to use: 3 Make local root Database admin: No Does the LDAP database require login? No
ต่อไป สั่งให้ระบบแก้ไขเงื่อนไขการ authen เป็น LDAP
sudo auth-client-config -t nss -p lac_ldap
จากนั้นใช้คำสั่งต่อไปนี้ เพื่อเริ่มใช้งาน PAM LDAP
sudo pam-auth-update
จะมีคำถามว่า
PAM profiles to enable:
ให้เลือกทั้ง
Unix authentication และ
LDAP Authenticationสุดท้าย
sudo /etc/init.d/nscd restart
- แก้ไขไฟล์ /etc/default/saslauthd บรรทัดที่ 7
START=yes
แล้ว start saslauthd
sudo /etc/init.d/saslauthd start
FRONTEND ( frontend01.example.com )
- ติดตั้ง
sudo apt install cyrus-imapd cyrus-common cyrus-clients sasl2-bin
- แก้ไขไฟล์ /etc/imapd.conf โดยเพิ่มบรรทัดต่อไปนี้ไว้ท้ายไฟล์
#SASL sasl_pwcheck_method: saslauthd sasl_mech_list: PLAIN # MUPDATE mupdate_server: mupdate.example.com mupdate_port: 3905 mupdate_username: cyrus mupdate_authname: cyrus mupdate_password: <secret> #PROXY serverlist: backend01.example.com backend01_password: mailproxy proxy_authname: mailproxy
- แก้ไข /etc/cyrus.conf
ใน SERVICE section ให้ uncommentmupdate cmd="mupdate" listen=3905 prefork=1
- เพิ่มส่วนนี้ ท้ายไฟล์ /etc/services ด้วย
#MUPDATE mupdate 3905/tcp # MUPDATE mupdate 3905/udp # MUPDATE
- แก้ไขไฟล์ /etc/default/saslauthd บรรทัดที่ 7
START=yes
แล้ว start saslauthd
sudo /etc/init.d/saslauthd start
และ เมื่อทุกอย่างพร้อม ทุกเครื่องก็
sudo /etc/init.d/cyrus-imapd restart
เมื่อจะเพิ่มเครื่อง Backend ก็ทำตามขั้นตอน แล้ว เพิ่มใน /etc/imapd.conf ของเครื่อง Frontend ในส่วนของ serverlist และ password เช่น
จะเพิ่มเครื่อง backend02.example.com ก็ต้องเพิ่มดังนี้#PROXY serverlist: backend01.example.com backend02.example.com backend01_password: <secret> backend02_password: <secret> proxy_authname: mailproxy
เมื่อต้องการเพิ่ม Frontend ก็ให้ Sync ตัวไฟล์ /etc/imapd.conf ไปให้เหมือนกันทุกเครื่อง
หวังว่าจะเป็นประโยชน์
- ติดตั้ง cyrus-murder ด้วยคำสั่ง
-
GCP #01 วิธีการสร้าง Virtual Machine บน Google Cloud Platform
ขั้นตอน
- มี Google Account
- ไปที่ https://console.cloud.google.com/start
- สำหรับคนที่ใช้ครั้งแรก ควรจะใช้สิทธิ์ Free Trial 300 USD / 12 Month
- ในการใช้งาน จะต้องมี Billing Account โดยต้องกรอกข้อมูล บัตร Credit/Debit ซึ่งต้องเป็น VISA/MasterCard เท่านั้น และต้องไม่ใช่ Prepaid ด้วย
https://cloud.google.com/billing/docs/how-to/payment-methods#add_a_payment_method
- เมื่อเสร็จแล้วจะได้ Credit อย่างนี้
- ต่อไป สร้าง Virtual Machine กัน
ไปที่ เมนู > Cloud Launcher
จะเห็นได้ว่า ตอนนี้ระบบจะสร้าง “My First Project” ไว้ให้ ซึ่งเราสามารถ สร้าง Project ใหม่ก็ได้ แต่ตอนนี้ใช้อย่างนี้ไปก่อน - ต่อไป จะลองสร้าง Ubuntu Server ขึ้นมาใช้งาน ในที่นี้จะสร้าง Ubuntu 14.04
พิมพ์ Ubuntu ในช่องค้นหา แล้ว เลือก Ubuntu 14.04
- จากนั้น คลิก Launch on Compute Engine
- ตั้งชื่อตามต้องการ (ถ้าต้องการ)
- สามารถเลือก Zone และ Machine Type ได้ตามความเหมาะสม ซึ่งจะมีราคาแตกต่างกัน
- ค่าเริ่มต้น Machine Type: n1-standard-1 จะให้ 1 vCPU, 3.75 GB RAM และ 10 GB standard persistent disk หากต้องการ Disk เพิ่ม สามารถคลิก Change เพื่อเพิ่มได้ (standard persistent disk จะราคาถูกกว่า ssd มาก)
- ต่อไป กำหนดเรื่องเของ Firewall ถ้าให้บริการ HTTP/HTTPS ก็คลิกเลือกได้เลย
ในกรณีที่ต้องการกำหนดค่าอื่นๆ เช่น Disk, Network, SSH Key ให้คลิก “Management, disks, networking, SSH keys”
เสร็จแล้วกดปุ่ม Create
- รอสักครู่ ก็จะได้ VM มาใช้งานแล้ว
- ในที่นี้ จะได้ External IP ซึ่งใช้ในการติดต่อจาก Internet มา แต่หากมีการ Restart/Stop IP address นี้ก็จะเปลี่ยนไป (การ Fix มีค่าใช้จ่ายนิดหน่อย) และ การติดต่อไปยัง VM ก็สามารถทำได้ โดยการคลิก SSH ซึ่งสามารถเข้าถึงได้จาก Console นี้ หากต้องการใช้งานจาก Client อื่นก็ทำได้ แต่ต้องกำหนด SSH Key กันนิดหน่อย ซึ่งจะกล่าวในภายหลัง
- เพิ่มเติม ในกรณีต้องการเปิด Port เพิ่มที่ไม่ใช่ HTTP/HTTPS ให้คลิกที่ Menu > Network Services > Firewall Rules
แล้วกำหนดค่าตามต้องการ โดยการ Create Firewall Rule
หวังว่าจะเป็นประโยชน์ครับ
-
วิธีทำ Password-less SSH บน Ubuntu
ในการทำงานกับ Server Cluster ขนาดใหญ่ ซึ่งประกอบด้วย Ubuntu Server จำนวนมาก หากต้องแก้ไขระบบทั้งหมด โดยการ Secure Shell หรือ SSH เข้าไปทีละเครื่อง “โดยต้องเป็น root ด้วย” จะเป็นงานที่ใช้เวลาอย่างมาก เค้าจึงมีระบบที่เรียกว่า Password-less SSH โดยการแลกเปลี่ยน Public Key แทนที่จะต้อง Login ด้วย Username/Password
และเนื่องจาก Ubuntu โดย Default ไม่มีการสร้าง root password (มี root แต่ไม่มี password –> ก็เลย Login ไม่ได้ด้วย Password) ซึ่งก็ดีในเรื่องของ Security แต่ทำให้การทำงานยุ่งยากนิดหน่อย
บทความนี้จะกล่าวถึงวิธีการทำ Password-less SSH รวมไปถึง การที่ไม่ต้องถาม Known Host ในครั้งแรกที่เข้าใช้งานด้วย โดยระบบจะประกอบด้วย server01 เป็นเครื่องที่จะสั่งการเครื่อง server02 … serverNN ในสิทธิ์ root และในระบบนี้ ทุกเครื่องมี user ชื่อ mama ซึ่งมีสิทธิ์ sudo
ที่เครื่อง server01
- ใช้คำสั่งต่อไปนี้ เพื่อสร้าง Public/Private rsa key pair
ssh-keygen
จะได้ผลดังนี้
ซึ่งจะได้ไฟล์มา 2 file อยู่ใน directory: ~/.ssh
– id_rsa
– id_rsa.pub - เพื่อไม่ให้การ SSH ไปยังเครื่องใหม่ๆ มีการถาม Known Host แบบนี้ แล้วก็ต้องคอยตอบ yes ทุกเครื่องไป
ก็ให้สร้างไฟล์ .ssh/config ว่า (วิธีนี้จะมีผลเฉพาะ mama เท่านั้น) หรือสร้างใน /etc/ssh/ssh_config เพื่อให้มีผลทั้งระบบHost * StrictHostKeyChecking no UserKnownHostsFile=/dev/null
- จากนั้น ให้เอาไฟล์ Public Key คือ .ssh/id_rsa.pub ไปยังเครื่องปลายทาง ในที่นี้คือ server02 (ใช้วิธี scp ไปยัง mama@server02)
scp .ssh/id_rsa.pub mama@server02:~
ในครั้งแรกนี้ ยังต้องใส่ Password ของ mama บนเครื่อง server02 อยู่
จากนั้น ไปดำเนินการต่อใน server02
ที่เครื่อง server02
- ใน home directory ของ mama บน server02 จะมีไฟล์ id_rsa.pub อยู่ ลองตรวจสอบโดยใช้คำสั่ง
ls -l /home/mama/id_rsa.pub
- เปลี่ยนเป็น root ด้วยคำสั่ง
sudo su
แล้ว เข้าไปใน root home directory ด้วยคำสั่ง
cd
- สร้าง directory .ssh และ สร้างไฟล์ .ssh/authorized_keys โดยนำข้อมูลในไฟล์ /home/mama/id_rsa.pub มาต่อท้าย
mkdir .ssh cat /home/mama/id_rsa.pub >> .ssh/authorized_keys
- เพื่อความปลอดภัย ตั้งค่า Permission ให้ถูกต้อง
chmod 700 .ssh chmod 600 .ssh/authorized_keys
จากนั้น ลองทดสอบ ssh จาก mama บน server01 ไปยัง root บน server02
ssh root@server02
ก็จะไม่มีการถาม Password และ ไม่ถาม Known Host อีก
หลังจากนี้ สามารถ clone เครื่อง server02 ไปเป็นเครื่องต่างๆได้เลย
- ใช้คำสั่งต่อไปนี้ เพื่อสร้าง Public/Private rsa key pair
-
เตาะแตะไปกับ Docker ตอนที่ 12 Clone Docker Files From GitHub
จากบล็อกเรื่อง “เตาะแตะไปกับ Docker” ในตอนที่แล้ว เราได้เรียนรู้ขั้นตอนในการสร้างและรัน LDAP services อย่างละเอียด ก่อนที่ผมจะเขียนบทความในตอนนี้ผมได้นำไฟล์ทุกไฟล์นั้นขึ้นไปไว้บน GitHub เพื่อให้พวกเราไม่ต้องสร้างไฟล์เหล่านั้นเอง แต่จะทำด้วยคำสั่ง git clone ครับ
เรายังคงทดสอบด้วย VM โดยตั้งค่า network เป็น NAT network เพราะว่า เราใช้ domain สมมติ คือ ldap.example.com และทดสอบในสภาพแวดล้อมที่เป็นเครือข่ายภายใน
ขั้นตอนดังนี้
1. ติดตั้ง Ubuntu 16.04 64 bit แล้วติดตั้ง docker 17.06.2-ce แล้วต้องเปลี่ยนชื่อ hostname เป็น ldap.example.com จากนั้นรีบูตเครื่อง
2. ติดตั้ง docker-compose 1.8.0-2 (ถ้ายังไม่ได้ทำ) ด้วยคำสั่งดังนี้
sudo apt install docker-compose
3. ทำการ Clone project จาก github ด้วยคำสั่ง
git clone https://github.com/woonpsu/ex1-openldap.git
4. ทำคำสั่งตามนี้
cd ex1-openldap docker-compose up -d
หมายเหตุ
หากยังไม่มี image ชื่อ ubuntu:16.04 ก็จะใช้เวลานานสักหน่อยเมื่อรันคำสั่ง docker-compose เพราะว่าจะมีการสร้าง image ubuntu:16.04 ให้ใหม่5. ใช้คำสั่งเหล่านี้เพื่อตรวจสอบ
docker images docker ps docker volume ls
6. เพิ่ม users ตัวอย่าง
sudo apt install ldap-utils ldapadd -H ldap://ldap.example.com -f ./openldap/src/create-users.ldif -x -D "cn=admin,dc=example,dc=com" -w 123456
7. ทดสอบเข้าใช้งานเว็บจากเครื่องใน NAT network เดียวกัน หรือที่เครื่อง VM server ที่ผมได้ติดตั้ง Desktop Environment ไว้แล้ว ก็ต้องเปลี่ยนจาก text เป็น graphic ด้วยคำสั่ง
$ startx
เข้า browser ไปที่
http://ldap.example.com:8080/phpldapadmin/
สำหรับวิธีการทำ GitHub Repository ชื่อ ex1-openldap ของผมอย่างคร่าว ๆ คือ
1. เข้า browser ไป sign up แบบ free ที่ github.com ด้วย username ชือ woonpsu2. สร้าง Repository ชื่อ ex1-openldap
3. ไปที่เครื่อง server ใช้คำสั่ง
git clone https://github.com/woonpsu/ex1-openldap.git
4. เตรียมไฟล์
cd ex1-openldap
git init5. สร้างไฟล์ docker-compose.yml และไดเรกทอรี openldap กับ phpldapadmin ให้เสร็จ
6. ทำการส่งขึ้นไปไว้บน github
git add .
git commit -m “This is a first commit”
git push -u origin masterใส่ username และ password ของเราที่ sign up กับ github
หมายเหตุ
- หากต้องการใช้ VM ที่ผมเตรียมไว้ จะไม่ต้องติดตั้ง Ubuntu server ก็ download docker-vm file size 1.2G แล้ว import เข้า Oracle VM Virtualbox ทดสอบดูได้ (เข้าด้วย mama/123456)
-
เตาะแตะไปกับ Docker ตอนที่ 11 Docker Compose (LDAP services)
เราจะมาเรียนรู้ การใช้ docker compose รัน service 2 services คือ OpenLDAP และ phpLDAPadmin ซึ่ง docker จะมองว่าการใช้ docker compose คือ เรากำลังรัน project ที่ประกอบด้วย service หลาย ๆ service
ให้แน่ใจว่าอยู่ที่ home directory ให้ใช้คำสั่งนี้
$ cd
สร้างไดเรกทอรีของ project สมมติตั้งชื่อว่า ex1
$ mkdir ex1 $ cd ex1
สร้างไดเรกทอรี openldap ภายในมี dockerfile และไดเรกทอรีที่เกี่ยวข้อง ทำตามบล็อกเรื่อง “เตาะแตะไปกับ Docker ตอนที่ 9 Dockerfile (OpenLDAP)”
สร้างไดเรกทอรี phpldapadmin ภายในมี dockerfile และไดเรกทอรีที่เกี่ยวข้อง ทำตามบล็อกเรื่อง “เตาะแตะไปกับ Docker ตอนที่ 10 Dockerfile (phpLDAPadmin)”
สร้างไฟล์ docker-compose.yml ด้วยเอดิเตอร์ที่ถนัด เช่น vi หรือ nano ก็ได้
$ vi docker-compose.yml version: '2' services: openldap: build: ./openldap container_name: openldap volumes: - ldapdatavol:/var/lib/ldap - ldapconfigvol:/etc/ldap/slapd.d ports: - "389:389" - "636:636" restart: always phpldapadmin: build: ./phpldapadmin container_name: phpldapadmin environment: HNAME: "openldap" ports: - "8080:80" depends_on: - openldap restart: always volumes: ldapdatavol: external: false ldapconfigvol: external: false
อธิบายได้ดังนี้
ไฟล์ docker-compose.yml นี้ จะมี service แรกคือ openldap จะ build image จากไดเรกทอรี ./openldap เมื่อรันเป็น container จะตั้งชื่อว่า openldap โดยมีที่เก็บข้อมูลถาวรคือ ldapdatavol จะ mapped ไปยัง /var/lib/ldap ใน container และที่เก็บคอนฟิก ldapconfigvol จะ mapped ไปยัง /etc/ldap/slapd.d ใน container เช่นเดียวกัน
โดย Host และ container เปิด port ตรงกัน คือ เปิด port TCP 636(LDAPS) และ 389(LDAP) และ container นี้จะทำงานทุกครั้งเมื่อเปิดเครื่องต่อมา service ที่สองคือ phpldapadmin จะ build image จากไดเรกทอรี ./phpldapadmin เมื่อรันเป็น container จะตั้งชื่อว่า phpldapadmin มีการตั้งค่าตัวแปร HNAME เป็นชื่อ container อันแรก คือ openldap โดยที่ Host จะเปิด port TCP 8080 ไปยัง port TCP 80 ของ container นี้ ถัดมาคือ depends_on คือ จะรัน container นี้ได้ก็ต่อเมื่อมี container ชื่อ openldap และ container นี้จะทำงานทุกครั้งเมื่อเปิดเครื่อง
ท่อนล่างสุด คือ การกำหนดว่า จะมีการใช้ named volume ชื่อ ldapdatavol และ ldapconfigvol ทั้งสอง volume นี้ จะถูกสร้างโดยคำสั่ง docker-compose ไม่ได้ไปใช้ volume จากที่ได้สร้างไว้ก่อนแล้ว (external: false) หากจะย้อนกลับไปอ่านเรื่อง “เตาะแตะไปกับ Docker ตอนที่ 7 Manage data” จะเข้าใจเรื่อง named volume ครับ
ผลลัพธ์หลังจากเตรียมครบ ภายในไดเรกทอรี ex1 จะมี 1 ไฟล์ และ 2 ไดเรกทอรี ดังนี้
$ ls docker-compose.yml openldap phpldapadmin
ตอนนี้เราก็เตรียมการต่าง ๆ เสร็จแล้ว
ต่อไปก็ใช้คำสั่ง docker-compose เพื่อสร้าง service คือ openldap และ phpldapadmin ดังนี้
$ docker-compose up -d
ตรวจสอบรายการ image
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE phpldapadmin latest d314c021fd1a 6 hours ago 282MB ex1_phpldapadmin latest f2feaa90c59b 9 days ago 282MB ex1_openldap latest e98f6bad71a7 9 days ago 259MB openldap latest cb8b1c0057cc 11 days ago 259MB ubuntu 16.04 ccc7a11d65b1 5 weeks ago 120MB
จะพบว่ามี image ของ project ex1 คือ ex1_openldap และ ex1_phpldapadmin ส่วน image ชื่อ openldap และ phpldapadmin สองอันนั้นที่เห็นเป็น image ที่สร้างด้วยคำสั่ง docker build ตอนที่เราเรียนรู้เรื่อง “เตาะแตะไปกับ Docker ตอนที่ 9 Dockerfile (OpenLDAP)” และ “เตาะแตะไปกับ Docker ตอนที่ 10 Dockerfile (phpLDAPadmin)” ครับ
ตรวจสอบรายการ container ที่รันอยู่
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b61e8f24802c ex1_phpldapadmin "/bin/bash /run.sh..." 3 minutes ago Up 3 minutes 0.0.0.0:8080->80/tcp phpldapadmin 489bb2db70d3 ex1_openldap "/bin/sh -c '/usr/..." 3 minutes ago Up 3 minutes 0.0.0.0:389->389/tcp, 0.0.0.0:636->636/tcp openldap
จะพบว่ามี container ชื่อว่า openldap และ phpldapadmin เกิดขึ้นหลังคำสั่ง docker-compose up -d
ทดสอบการเข้าใช้งานทาง web ไปที่ http://ldap.example.com:8080/phpldapadmin/ (เนื่องจาก VM ที่ใช้ทดสอบ คือ ubuntu ที่ได้ติดตั้ง XFCE desktop environment ไว้ด้วยทำให้สามารถใช้งาน web browser ได้ด้วย)
หลังจาก login แล้วจะเห็นข้อมูล LDAP และจัดการ LDAP database ได้
จากความรู้ที่ได้เรียนมาหลาย ๆ ตอนจนถึงตอนนี้ เราก็น่าจะได้แนวทางในการสร้าง service ความเข้าใจอย่างง่าย ๆ คือ หากเป็น image ที่เราจะทำขึ้นเอง ไม่ได้ไป pull จาก docker hub เราก็ทำด้วย dockerfile และหากมี service ที่ใช้ร่วมกันระหว่าง service ก็เปลี่ยนไปทำต่อด้วย docker-compose จะสะดวกกว่า
อนึ่งหาก pull หรือมี image อยู่แล้ว ก็เปลี่ยนจาก build: ./openldap เป็น image: openldap และปรับแก้ไขนิดหน่อยตามที่ผู้พัฒนา image นั้นได้แจ้งวิธีการไว้ครับ
จากที่ได้เขียนบล็อกในชุด “เตาะแตะไปกับ Docker” ตั้งแต่ ตอนที่ 1 ถึง ตอนที่ 11 นี้ ผมคิดว่าก็น่าจะเพียงพอให้เข้าใจว่า docker ใช้งานอย่างไร หวังเป็นอย่างยิ่งว่าผู้อ่านคงได้รับความรู้กันครับ และสามารถลองทำตามได้โดยไม่ติดขัดอะไร
-
เตาะแตะไปกับ Docker ตอนที่ 10 Dockerfile (phpLDAPadmin)
ในตอนที่แล้วเราใช้งาน 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 แยกกัน