เรียนรู้ Docker part 3: Linux GUI
เรารู้จัก Linux OS ผ่าน CentOS ซึ่งรันเป็น container บน Docker สิ่งที่ผมตั้งคำถามคือมีหนทางใดไหมที่จะรัน GUI นี้บน container
ความเดิมจาก part ที่แล้ว
อย่างที่เราทราบกันมาแล้ว image ที่ใช้ไม่มี Graphical User Interface (GUI) จึงต้องเขียนโปรแกรมผ่านโปรแกรม text-based เท่านั้น คำถามก็คือเป็นไปได้ไหมที่เราจะติดตั้งโปรแกรมที่เกี่ยวข้องกับ GUI ขออย่างน้อยได้ใช้เม้าส์ก็ยังดี :)
ค้นในอินเตอร์เน็ตด้วย keywords ที่เราอ่านจาก Wiki และเชื่อมโยงความคิดเข้าหากันก็ไปเจอกับบทความของคุณ Stephen Fox ซึ่งตรงกับความต้องการพอดี (ดีใจมาก) บทความนี้จึงขอแปลคำพูดและโค้ดจากผู้เขียนท่านนี้มาเล่าสู่พวกเราครับ
เครดิต
Linux GUI Components
icon, เม้าส์, windows (หน้าต่างมีปุ่มกากบาท) และกราฟิกอื่นๆล้วนเป็น interface หรือ GUI ที่จะช่วยให้เราสามารถติดต่อกับระบบได้
Linux มี Kernel เป็นหัวใจ มีสภาพแวดล้อมแบบกราฟิกเป็นหน้าตา
GUI ของ Linux ถูกสร้างด้วยสิ่งที่เรียกว่า X (ชื่อโครตเท่ห์) หรือ X Window System
X Window System เป็น protocol ที่ทำงานอยู่บนโปรแกรม X Server
X Window System ถูก implement ในหลายจ้าว จัดอยู่ในกลุ่มโปรแกรม window manager หรือ desktop environment จ้าวดังได้แก่
- GNU Network Object Model Environment (GNOME)
- Kool Desktop Environment (KDE)
แหม~ฟังชื่อพวกนี้แล้วยากทำความเข้าใจจริงๆ ฟังผ่านๆไปก่อน
ถามว่าเราต้องการ X Serverใช่ไหม? คำตอบใช่แล้ว เช่น
- Xvfb ย่อมาจาก X Virtual Framebuffer
Xvfb
Xvfb ทำงานด้วย virtual memory ดังนั้นมันต้องการระยะเวลาเตรียมตัวสักครู่ คำสั่ง local timeout=${XVFB_TIMEOUT:-5}
จะคอยจนกว่า Xvfb จะพร้อม
ต่อไปนี้คือฟังก์ชัน bash ที่ชื่อ launch_xvfb
launch_xvfb() {
# Set defaults if the user did not specify envs.
export DISPLAY=${XVFB_DISPLAY:-:1}
local screen=${XVFB_SCREEN:-0}
local resolution=${XVFB_RESOLUTION:-1280x1024x24}
local timeout=${XVFB_TIMEOUT:-5} # Start and wait for either Xvfb to be fully up,
# or we hit the timeout.
Xvfb ${DISPLAY} -screen ${screen} ${resolution} &
local loopCount=0
until xdpyinfo -display ${DISPLAY} > /dev/null 2>&1
do
loopCount=$((loopCount+1))
sleep 1
if [ ${loopCount} -gt ${timeout} ]
then
echo "[ERROR] xvfb failed to start."
exit 1
fi
done
}
Window Manager
ตอนนี้เรามี Xvfb เป็น display หรือกราฟิกแล้วแต่ยังขนาดหน้าต่างแสดงผลที่ประกอบด้วยปุ่มย่อ ขยายและปิดหน้าต่าง เรียกว่า window หน้าที่นี้ยกให้กับ window manager อย่าง Fluxbox
เช่นกันกับ Xvfb เราต้องการระยะเวลาสักครู่เพื่อเตรียมมันให้พร้อมใช้งาน คำสั่ง until wmctrl -m > /dev/null 2>&1
จะคอยจนกว่า Fluxbox จะพร้อม
ต่อไปนี้คือฟังก์ชัน bash ที่ชื่อ launch_window_manager
launch_window_manager() {
local timeout=${XVFB_TIMEOUT:-5} # Start and wait for either fluxbox to be fully up or we hit
# the timeout.
fluxbox &
local loopCount=0
until wmctrl -m > /dev/null 2>&1
do
loopCount=$((loopCount+1))
sleep 1
if [ ${loopCount} -gt ${timeout} ]
then
echo "${G_LOG_E} fluxbox failed to start."
exit 1
fi
done
}
และสุดท้ายจะเข้าถึง display ข้างต้นนี้ได้อย่างไร?
หนึ่งในคำตอบคือใช้โปรแกรม VNC server
VNC Server
VNC Server ย่อมาจาก Virtual Network Computing Server หัวใจคือ allows you to access remote desktop machines หรือก็คือเข้าใช้งานเครื่อง server ผ่านการ remote
เมื่อติดตั้ง VNC Server แล้ว เครื่องของเราที่รัน container อยู่ต้องดาวน์โหลด VNC Viewer เพื่อเชื่อมต่อเข้าไป
ฟังก์ชัน bash ต่อไปนี้ชื่อ run_vnc_server จะมีชีวิตอยู่ตราบเท่าที่ container นี้รันอยู่
run_vnc_server() {
local passwordArgument='-nopw' if [ -n "${VNC_SERVER_PASSWORD}" ]
then
local passwordFilePath="${HOME}/x11vnc.pass"
if ! x11vnc -storepasswd "${VNC_SERVER_PASSWORD}" "${passwordFilePath}"
then
echo "[ERROR] Failed to store x11vnc password."
exit 1
fi
passwordArgument=-"-rfbauth ${passwordFilePath}"
echo "[INFO] The VNC server will ask for a password."
else
echo "[WARN] The VNC server will NOT ask for a password."
fi x11vnc -display ${DISPLAY} -forever ${passwordArgument} &
wait $!
}
แล้วนำทั้งสามมารวมร่างตั้งชื่อไฟล์นี้ว่า bootstrap.sh
Create bootstrap.sh
เป็น bash script ประกอบด้วย 3 ฟังก์ชันข้างต้นซึ่งจะถูกเรียกให้ทำงานผ่าน container แต่ก่อนจะถึงขั้นตอนนั้นมันจะต้องถูกรวมเข้ากับ Dockerfile เสียก่อน
ใช้โปรแกรม text-based อะไรก็ได้ในเครื่องเรา (ไม่ใช่ใน container นะ) สร้างไฟล์ bootstrap.sh ไว้สักแห่งหนึ่ง ของผมไว้ที่
/Users/pros/works/medium/docker/03
จากนั้นคัดลอก script นี้ไปวาง
Create Dockerfile
เตรียม Dockerfile ชื่อ Dockerfile ไว้ที่เดียวกันกับ bootstrap.sh ข้างต้น เนื้อหาคือโหลด CentOS ติดตั้งโปรแกรมที่จำเป็น จากนั้นเรียก bootstrap.sh ทำงาน
จะได้ดังนี้
Create Docker Image
เมื่อมี Dockerfile แล้วจึงสั่งสร้าง image ได้
docker build -t <tag-name> <path>
เช่น
docker build -t centos7gui .
เมื่อ . หมายถึงที่นี่แหละ (ใน working directory)
ผล
โปรดสังเกตว่า CentOS ที่เลือกใช้คือเวอร์ชัน 7 เพราะเวอร์ชัน 8 จาก part ที่ผ่านมายังใหม่เกินไปที่โปรแกรมอื่นๆจะรองรับความเข้ากันได้
Create Docker Container
สร้าง container จาก image
docker run -p 5900:5900 centos7gui
ผล
VNC Viewer
ผมดาวน์โหลดจาก VNC Connect (ค้นหาเจออันดับแรก) เลือก VNC Viewer ตาม OS ของเครื่องได้เลยครับ ส่วนผมใช้ MacOS
ทดสอบ remote ไปยัง localhost:5900
ผล
โปรแกรมอื่นๆ
Fluxbox เป็นตัวกลางให้เราได้คุยกับ OS แต่ดูเหมือนว่าเวอร์ชันที่ผมสาธิตอยู่นี้จะขาดโปรแกรมและการ config อีกหลายส่วน มาดูว่าเราสามารถเก็บอะไรได้บ้าง
xterm
xterm มันคือตัวจำลอง terminal ใน X เมื่อคลิกขวาแล้วเรียกใช้งานปรากฏว่าหาไม่เจอ ดังนั้นเพิ่มคำสั่งต่อไปนี้ไว้ใน Dockerfile
RUN yum install -y xterm
ทุกครั้งหลังการแก้ไข Dockerfile ต้องบอก Docker สร้าง image ให้ใหม่ บอก docker รัน container ให้ใหม่และ VNC เข้าไปใหม่เสมอ
Mozilla Firefox
เพิ่มคำสั่งต่อไปนี้ไว้ใน Dockerfile
RUN yum install -y firefox
เข้าใช้งานด้วย xterm ที่ terminal เข้าไปยัง /usr/bin
จากนั้นเรียกfirefox
Google Chrome
เพิ่มคำสั่งต่อไปนี้ไว้ใน Dockerfile
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpmRUN yum install -y ./google-chrome-stable_current_x86_64.rpm
เข้าใช้งานด้วย xterm ที่ terminal เข้าไปยัง /usr/bin
จากนั้นเรียกgoogle-chrome --no-sandbox
หมายเหตุ ดูเหมือนว่าการจัดการหน่วยความจำของ OS ยังไม่เข้าที่เข้าทางกับโปรแกรมประยุกต์เหล่านี้ ก็ต้องแสวงหาวิธีการแก้ไขต่อไป
สรุป
เราสามารถใช้งาน GUI ของ Linux OS จาก X interface ที่จัดการโดย window manager ซึ่งถูก implement อีกทีหนึ่งด้วยโปรแกรม Fluxbox ผ่าน VNC Viewer
อ่านต่อตอนถัดไป
สืบค้น
https://georgik.rocks/how-to-install-fluxbox-on-centos-in-docker/
https://access.redhat.com/discussions/3141241
https://www.redhat.com/archives/fedora-list/2007-August/msg02702.html
https://www.cyberciti.biz/faq/install-google-chrome-on-centos-7/