เรียนรู้ Docker part 3: Linux GUI

Phai Panda
5 min readJul 30, 2020

--

เรารู้จัก 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)

แหม~ฟังชื่อพวกนี้แล้วยากทำความเข้าใจจริงๆ ฟังผ่านๆไปก่อน

https://study.com/academy/lesson/linux-gui-components-x-windows-configuration.html

ถามว่าเราต้องการ 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 ทำงาน

จะได้ดังนี้

created bootstrap.sh & Dockerfile in working directory

Create Docker Image

เมื่อมี Dockerfile แล้วจึงสั่งสร้าง image ได้

docker build -t <tag-name> <path>

เช่น

docker build -t centos7gui .

เมื่อ . หมายถึงที่นี่แหละ (ใน working directory)

ผล

created centos7gui image successful

โปรดสังเกตว่า 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

โปรแกรมอื่นๆ

Fluxbox เป็นตัวกลางให้เราได้คุยกับ OS แต่ดูเหมือนว่าเวอร์ชันที่ผมสาธิตอยู่นี้จะขาดโปรแกรมและการ config อีกหลายส่วน มาดูว่าเราสามารถเก็บอะไรได้บ้าง

xterm

xterm มันคือตัวจำลอง terminal ใน X เมื่อคลิกขวาแล้วเรียกใช้งานปรากฏว่าหาไม่เจอ ดังนั้นเพิ่มคำสั่งต่อไปนี้ไว้ใน Dockerfile

RUN yum install -y xterm

ทุกครั้งหลังการแก้ไข Dockerfile ต้องบอก Docker สร้าง image ให้ใหม่ บอก docker รัน container ให้ใหม่และ VNC เข้าไปใหม่เสมอ

คลิกขวาเลือก xterm ได้ terminal ลองพิมพ์ ls

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/

--

--

No responses yet