ฉันรันเดสก์ท็อป Linux เต็มรูปแบบใน Docker แค่เพราะว่าฉันทำได้
เหมือนกับฉัน คุณคงเคยได้ยินกฎที่ไม่ได้เป็นทางการของ Docker: มันสำหรับเซิร์ฟเวอร์น้ำหนักเบาแบบไม่มีหัว และแอปพลิเคชันที่ใช้คำสั่งผ่านบรรทัดคำสั่ง ไม่ใช่สำหรับอินเทอร์เฟซกราฟิก คนส่วนใหญ่ปฏิบัติตามกฎนี้ด้วยเหตุผลที่ดี—CLI คือสิ่งที่ Docker ถูกสร้างขึ้นเพื่อมัน แต่จะเกิดอะไรขึ้นเมื่อคุณทำลายกฎเหล่านี้?
ฉันตัดสินใจที่จะทำอะไรที่ไม่ธรรมดา เป้าหมายของฉันคือการรันเดสก์ท็อป Linux แบบเต็มรูปแบบภายในคอนเทนเนอร์ ฉันไม่ได้แค่อยากได้เชลล์; ฉันต้องการ GUI ที่ทำงานได้เต็มรูปแบบที่อยู่ในที่ที่ไม่ควรจะอยู่ นี่คือสิ่งที่เกิดขึ้นเมื่อฉันลองทำ
ฉันทำสิ่งนี้ไปเพื่ออะไรนะ?
มันแค่บ้าเล็กน้อย
แล้วทำไมใครจะต้องมาลำบากไปติดตั้งและใช้งานลินุกซ์ด้วยล่ะ? อย่างไรก็ตาม เราก็สามารถใช้ VirtualBox หรือแม้แต่การติดตั้งลินุกซ์แบบคู่กับวินโดวส์ก็ได้ คำตอบของผมง่ายมาก: ความอยากรู้อยากเห็นและความต้องการความท้าทาย
ฉันสนใจเกี่ยวกับ Docker มาสักระยะหนึ่งแล้ว และแม้ว่าฉันจะมีประสบการณ์กับการพัฒนาเว็บแบบฟูลสแตก แต่ก็ยังไม่ค่อยมีความรู้เกี่ยวกับโลกของ Docker และการใช้คอนเทนเนอร์มากนัก ฉันอยากทดลองสิ่งต่าง ๆ และเรียนรู้จากการทำ ดังนั้นโครงการนี้จึงเป็นคำตอบ
ตั้งแต่เริ่มแรก ฉันก็รู้แล้วว่านี่จะไม่ง่าย ฉันคาดหวังว่าวันหนึ่ง หรือสองวันมากที่สุด ก็น่าจะเพียงพอที่จะทำให้ระบบลินุกซ์ที่มีกราฟิกทำงานได้ แต่ความเป็นจริงของความท้าทายนั้นตรงกันข้ามอย่างสิ้นเชิง อุปสรรคที่ฉันเผชิญในสี่วันถัดมานั้นไม่คาดคิดอย่างยิ่งและซับซ้อนกว่าที่ฉันเคยคาดคิดไว้ ทำให้ความอดทนของฉันต้องยืดเยื้อมากกว่าที่ฉันวางแผนไว้
ก่อนที่จะลงลึกในรายละเอียดทางเทคนิค นี่คือบริบทบางส่วน
การทดลองทั้งหมดนี้เกิดขึ้นบนพีซีที่ใช้ Windows 10 โดยมีคำถามเฉพาะเป็นแรงจูงใจ: จะเกิดอะไรขึ้นถ้าคุณสามารถมีสิ่งที่ดีที่สุดทั้งสองโลก? แนวคิดของสภาพแวดล้อม Linux เต็มรูปแบบที่รันภายในคอนเทนเนอร์ Docker เคียงข้างกับแอปพลิเคชัน Windows มาตรฐานของฉันนั้นน่าสนใจเกินกว่าจะปฏิเสธ ไม่มีการรีบูท ไม่มีพาร์ติชันแยก—มีเพียงเดสก์ท็อป Linux ที่อยู่ในคอนเทนเนอร์อย่างไหลลื่น
ดังนั้น ก่อนอื่นฉันต้องเตรียมห้องทดลองของฉัน ซึ่งหมายถึงการติดตั้ง Docker และการตั้งค่า WSL หลังจากวางรากฐานแล้ว ฉันก็ทบทวนพื้นฐานของ Docker และอ่านเอกสารของมัน ด้วยสิ่งนี้ การเตรียมตัวเริ่มแรกของฉันก็เสร็จสมบูรณ์; ตอนนี้ก็ถึงเวลานำทฤษฎีไปปฏิบัติ
กำลังรันคอนเทนเนอร์ Docker ของฉัน
ฉันพยายามทำสิ่งนี้ในแบบที่ยาก
ความพยายามครั้งแรกของผมในการเรียกใช้เดสก์ท็อป Linux ใน Docker นั้น เมื่อหันกลับมามอง ถือเป็นความผิดพลาดของมือใหม่จากความมั่นใจเกินไป ผมตัดสินใจสร้างอิมเมจแบบกำหนดเองตั้งแต่เริ่มต้น หากคุณเป็นมือใหม่กับ Docker อิมเมจคือแพ็กเกจที่มีทุกอย่างที่แอปพลิเคชันต้องการในการทำงาน ดังนั้นเมื่อคุณสร้างอิมเมจแล้ว มันจะทำงานได้เหมือนเดิมทุกที่ ไม่ว่าจะบนฮาร์ดแวร์หรือระบบปฏิบัติการใด
ฉันทำข้อผิดพลาดอีกครั้งตั้งแต่เริ่มต้น: ฉันพึ่งพาเครื่องมือ AI เป็นอย่างมากในการสร้างโค้ดสำหรับภาพที่ฉันสร้างเอง
นี่คือบทเรียนที่ได้มาด้วยความยากลำบาก: หากคุณไม่เข้าใจเทคโนโลยี อย่าคัดลอกโค้ดโดยไม่คิดเหมือนที่ฉันทำ ฉันใช้เวลาหลายชั่วโมงในการแก้ไขข้อผิดพลาดโดยไม่มีทางออกที่ชัดเจน พยายามแก้ไขด้วยกำลังทั้งหมดผ่านโค้ดที่ฉันไม่เข้าใจ
หลังจากเสียเวลาทั้งวันไปกับเส้นทางที่ไม่มีประสิทธิภาพนี้ ในที่สุดฉันก็ยอมแพ้และเปลี่ยนกลยุทธ์ วิธีใหม่ของฉันนั้นง่ายมาก: ฉันจะใช้ภาพที่สร้างไว้ล่วงหน้าจาก Docker Hub ลองนึกว่า Docker Hub เป็นเหมือน "แอปสโตร์" สำหรับภาพคอนเทนเนอร์ ที่เต็มไปด้วยโซลูชันที่นักพัฒนาคนอื่นสร้างและแบ่งปัน มันเป็นการปรับตัวที่จำเป็นอย่างมากและในที่สุดก็ทำให้การทำงานจริงเริ่มต้นได้
รำไรแรกของแสง: สิ่งดีและสิ่งร้าย
หลังจากที่ผมล้มเหลวในการลองสร้างอิมเมจคัสตอมเอง ผมก็พบอิมเมจ Debian ที่ใช้ XFCE ที่น่าสนใจบน Docker Hub ผมดาวน์โหลดมันภายในไม่กี่นาที และด้วยคำสั่งไม่กี่คำ ผมก็สามารถรันมันได้ เมื่อผมเปิด URL ผมก็เจอกับเดสก์ท็อป Linux ที่ใช้งานได้เต็มรูปแบบ รันอยู่ในเบราว์เซอร์ของผม ความสุขแบบสุดโต่งของการเห็นระบบปฏิบัติการครบถ้วนที่ให้บริการจากภายในคอนเทนเนอร์ Docker เป็นความรู้สึกที่ผมจะไม่มีวันลืม มันใช้ได้จริง!
ความสามารถในการใช้งานก็ค่อนข้างดีเกินคาด LibreOffice และ GIMP ทำงานได้ดี แม้ว่าจะมีความหน่วงเล็กน้อย ฉันประเมินว่าประสิทธิภาพประมาณ 70% ของเครื่องจริง แต่ก็ยังใช้งานได้ดี Firefox ก็เปิดขึ้นเช่นกัน และฉันยังลองเข้า YouTube นั่นคือเวลาที่ฉันพบอุปสรรคใหญ่ครั้งแรก: สีสันจืดชืดและล้างออก การตรวจสอบอย่างรวดเร็วยืนยันความสงสัยของฉัน: เบราว์เซอร์ใช้การเรนเดอร์ด้วยซอฟต์แวร์ GPU ของฉันไม่ได้ทำงานเลย
ฉันสังเกตเห็นปัญหาอีกอย่าง: Flatpak ใช้งานไม่ได้ ความพยายามใด ๆ ในการติดตั้งแอปจาก Flatpak ล้มเหลวพร้อมข้อผิดพลาด ดังนั้นฉันจึงต้องหันไปใช้แพ็กเกจ Debian แม้จะมีข้อจำกัดเหล่านี้ การได้เห็นเดสก์ท็อป Linux ที่สมบูรณ์ทำงานในเบราว์เซอร์ของฉันโดยตรงจาก Docker เป็นชัยชนะครั้งยิ่งใหญ่
ปรับและเรียนรู้
ช่วยตัวเองไม่ได้
หลังจากใช้ XFCE มาสองสามนาที ฉันตัดสินใจที่จะเปลี่ยนบรรยากาศและลองใช้ GNOME เป็นสภาพแวดล้อมเดสก์ท็อปของฉัน ความผิดพลาดครั้งใหญ่! ฉันต้องใช้เวลาหลายชั่วโมงในการแก้ไขปัญหาและแก้ไขข้อผิดพลาดเพื่อให้มันทำงานได้ และเมื่อมันเริ่มทำงานในที่สุด มันก็ช้าและใช้ทรัพยากรมาก สุดท้ายฉันต้องกลืนน้ำลายและกลับไปใช้ XFCE และบอกกับตัวเองว่า XFCE อาจจะไม่หรูหรา แต่ตอบสนองได้ดีกว่ามาก ดังนั้นมามุ่งเน้นไปที่ความเป็นจริงกันเถอะ
ด้วยความมุ่งมั่นใหม่ของฉันเกี่ยวกับประสิทธิภาพ ฉันตัดสินใจที่จะกลับไปดูความพยายามครั้งแรกของฉัน: การสร้างภาพแอปพลิเคชันแบบกำหนดเองตั้งแต่เริ่มต้น คราวนี้ฉันได้ศึกษากับไฟล์ Dockerfile ของภาพที่สร้างไว้ล่วงหน้าที่ฉันใช้ก่อนหน้านี้ ฉันต้องการที่จะเข้าใจอย่างชัดเจนว่าสิ่งที่เกิดขึ้นภายในนั้นทำงานอย่างไร และฉันก็อยากดูว่าฉันสามารถปรับปรุงประสิทธิภาพด้วยตัวเองได้หรือไม่ ฉันได้ทดลองกับการตั้งค่าใหม่บางอย่าง โดยเฉพาะการพยายามใช้ xrdp แทนวิธีการส่งต่อ noVNC เพื่อดูว่าการใช้โปรโตคอลที่แตกต่างจะให้ประสบการณ์ที่ราบรื่นขึ้นหรือไม่ แต่ฉันก็ไม่เห็นความแตกต่างใดๆ กับ xrdp
ในการทำซ้ำ ให้สร้างไฟล์ชื่อ "dockerfile" วางโค้ด และรันมัน
FROM ubuntu:jammy-20230425
RUN apt update && \
DEBIAN_FRONTEND=noninteractive apt install -y \
cinnamon locales sudo \
tigervnc-standalone-server tigervnc-common \
virtualgl mesa-utils mesa-vulkan-drivers \
dbus-x11 xterm wget && \
locale-gen en_US.UTF-8 && \
update-locale LANG=en_US.UTF-8
# Create user
# Enter the below username and passoword in xrdp login screen
ARG USER=user
ARG PASS=1234
RUN useradd -m $USER -p $(openssl passwd $PASS) && \
usermod -aG sudo $USER && \
chsh -s /bin/bash $USER
# Environment for Cinnamon
RUN echo "#!/bin/sh\n\
export XDG_SESSION_DESKTOP=cinnamon\n\
export XDG_SESSION_TYPE=x11\n\
export XDG_CURRENT_DESKTOP=X-Cinnamon\n\
export LIBGL_ALWAYS_INDIRECT=0\n\
exec cinnamon-session" > /home/$USER/.xinitrc && \
chown $USER:$USER /home/$USER/.xinitrc && chmod +x /home/$USER/.xinitrc
# Setup VNC password
RUN mkdir -p /home/$USER/.vnc && \
echo $PASS | vncpasswd -f > /home/$USER/.vnc/passwd && \
chmod 0600 /home/$USER/.vnc/passwd && \
chown -R $USER:$USER /home/$USER/.vnc
# Start script
RUN echo "#!/bin/bash\n\
export DISPLAY=:1\n\
Xvnc :1 -geometry 1920x1080 -depth 24 -SecurityTypes VncAuth -rfbport 5901 -localhost no &\n\
sleep 2\n\
sudo -u $USER startx &\n\
tail -f /dev/null" > /start && chmod +x /start
EXPOSE 5901
CMD ["/start"]
สำรวจ Docker Hub
นี่คือวิธีที่ฉันควรทำตั้งแต่เริ่มต้น
ถ้าทั้งหมดนี้ฟังดูเหมือนงานมาก ข่าวดีคือ คุณไม่จำเป็นต้องสร้างภาพของตัวเองเพื่อเริ่มต้นหรือต้องรับมือกับข้อผิดพลาด งานวิจัยของฉันได้นำฉันไปสู่สองโซลูชันที่ยอดเยี่ยม พร้อมใช้งานทันที ที่มอบประสบการณ์ที่ราบรื่นมากขึ้น
- Webtop โดย LinuxServer.io: นี่เป็นตัวเลือกโอเพ่นซอร์สที่ยอดเยี่ยมซึ่งมีรสชาติเดสก์ท็อป Linux หลายแบบที่บรรจุเป็นภาพ Docker พร้อมใช้งาน มันใช้ noVNC เพื่อส่งเดสก์ท็อปตรงไปยังเบราว์เซอร์ของคุณ และการตั้งค่าง่ายต่อการทำความเข้าใจ
- Kasm Workspaces: นี่คืออีกหนึ่งตัวเลือกแบบโอเพ่นซอร์สสำหรับการใช้งานส่วนตัว
ข้อดีของภาพเหล่านี้คือมีการตั้งค่าทุกอย่างไว้ล่วงหน้า โดยเฉพาะ Webtop คุณเพียงแค่ดึงภาพ Docker และรันมัน เมื่อคอนเทนเนอร์กำลังทำงาน คุณสามารถเข้าถึง Linux ของคุณโดยการป้อน URL ฉันพบว่าประสิทธิภาพดีกว่าทุกสิ่งที่ฉันเคยลองมาก่อน และที่สำคัญมีการส่งผ่านเสียง ซึ่งฉันไม่ได้พบในภาพ Kasm
ในการเรียกใช้ Webtop ให้เปิด CMD ของ Windows แล้ววางโค้ดนี้
docker run -d ^
--name webtop-xfce ^
-e PUID=1000 ^
-e PGID=1000 ^
-e TZ=Etc/UTC ^
-p 3000:3000 ^
--shm-size=1gb ^
lscr.io/linuxserver/webtop:latest
ฉันค้นพบข้อดีที่ไม่คาดคิดไม่กี่อย่าง
มีประโยชน์บางอย่างจากการตั้งค่าที่โง่แบบนี้
สิ่งที่เริ่มต้นจากโครงการสนุก ๆ เพื่อเรียนรู้ Docker และทดลองกับคอนเทนเนอร์ของ Linux กลับพบคุณสมบัติที่มีประโยชน์อย่างคาดไม่ถึงระหว่างทาง การค้นพบที่ใหญ่ที่สุด และช่วงเวลาที่ทำให้ฉันร้องว่า 'อ้อ!' คือการตระหนักถึงพลังของการเข้าถึงเดสก์ท็อประยะไกล
เมื่อฉันเห็นเดสก์ท็อป Linux แบบเต็มรูปแบบทำงานบนเบราว์เซอร์ของฉัน ฉันนึกไอเดียบ้าๆ ขึ้นมา: ถ้าฉันเข้าถึงมันจากอุปกรณ์ที่มีประสิทธิภาพต่ำกว่านี้ล่ะ? ฉันหยิบ Chromebook ของฉัน—เครื่องธรรมดาที่มีโปรเซสเซอร์ Intel Celeron—เปิด URL และนี่คือมัน: พลังเต็มรูปแบบของพีซีหลักของฉัน สตรีมมิ่งบน Chromebook ของฉัน ทันใดนั้นฉันก็ไม่ได้ถูกผูกติดกับโต๊ะทำงานอีกต่อไป ฉันสามารถทำงานต่อจากโซฟาหรือที่ไหนก็ได้ในบ้าน Chromebook ที่มีประสิทธิภาพต่ำของฉันกลายเป็นหน้าต่างประสิทธิภาพสูงสู่เดสก์ท็อปของฉัน ทั้งหมดนี้ขอบคุณคอนเทนเนอร์
เพื่อประสบการณ์ที่ดีที่สุด ใช้การเชื่อมต่ออีเทอร์เน็ตแบบมีสาย หรือเครือข่าย Wi-Fi 5 GHz ที่เร็ว
นอกจากสิ่งนี้แล้ว ฉันยังสามารถเห็นประโยชน์อื่นๆ หลายข้อได้อีกด้วย:
- กล่องทรายแบบใช้ครั้งเดียว: ฉันสามารถทดสอบและทำให้สิ่งต่าง ๆ เสียหายในสภาพแวดล้อมลินุกซ์ได้โดยไม่ต้องกลัวว่าจะทำให้ระบบปฏิบัติการหลักของฉันพัง สนามเด็กเล่นที่สมบูรณ์แบบสำหรับการทดลองที่มีความเสี่ยง
- การเรียกดูแบบส่วนตัว: ฉันสามารถสร้างคอนเทนเนอร์ใหม่ ใช้เว็บเบราว์เซอร์ จากนั้นลบสภาพแวดล้อมทั้งหมดด้วยการคลิกเพียงครั้งเดียว โดยไม่ทิ้งร่องรอยไว้
- พื้นที่ทำงานเฉพาะทาง: ฉันสามารถสร้างอิมเมจ Linux แบบกำหนดเองที่เหมาะกับงานเฉพาะ—สภาพแวดล้อมการเขียนที่ปราศจากสิ่งรบกวน การตั้งค่าการเขียนโค้ดพร้อมเครื่องมือพัฒนาทั้งหมดติดตั้งไว้ล่วงหน้า
ความยืดหยุ่นนี้เปิดโอกาสที่ฉันยังไม่เคยพิจารณาเมื่อเริ่มโครงการ
ต่อไปคืออะไร?
การทดลองที่ยังไม่เสร็จของฉัน
แม้ว่าฉันจะเห็นด้วยตัวเองว่าการใช้งานเดสก์ท็อป Linux ใน Docker เป็นไปได้ แต่การเดินทางของฉันยังไม่จบ ฉันมีการทดลองบางอย่างที่อยากทำ แต่ไม่มีเวลาทำ:
- Flatpak และ Snap Store: ผมอยากหาวิธีให้ร้านแอปเหล่านี้ทำงานภายในคอนเทนเนอร์เพื่อขยายไลบรารีซอฟต์แวร์
- การเล่นเกม: ถ้าไม่มีการส่งผ่าน GPU สิ่งนี้จะเป็นไปไม่ได้ แต่ฉันอยากหาวิธีแก้ปัญหาสำหรับเรื่องนี้
- การปรับแต่งเพิ่มเติม: ฉันต้องการปรับแต่งการตั้งค่าเพิ่มเติมเพื่อดูว่าฉันสามารถเพิ่มประสิทธิภาพให้ดียิ่งขึ้นและลดความหน่วงของอินพุตได้หรือไม่
ทำไมการรัน Linux ใน Docker จึงยาก?
ความท้าทาย
ดังนั้น ตอนนี้เมื่อฉันเข้าใจแล้วว่าการรันสภาพแวดล้อมเดสก์ท็อปเต็มรูปแบบภายในคอนเทนเนอร์และคาดหวังให้มันทำงานเหมือนเดสก์ท็อปปกติบน Windows เป็นไปได้ แต่ก็เจ็บปวด เปราะบาง และซับซ้อนกว่าการรัน VM อย่างมาก สาเหตุหลักๆ ของสิ่งเหล่านี้คือ:
- คอนเทนเนอร์ไม่ได้เป็นระบบปฏิบัติการที่แยกตัวออกมา: คอนเทนเนอร์ของ Docker ใช้เคอร์เนลของโฮสต์ร่วมกัน นี่คือสิ่งที่ทำให้มันมีน้ำหนักเบาและดีสำหรับบริการเดี่ยว ๆ ในขณะที่สภาพแวดล้อมเดสก์ท็อปคาดหวังว่าบริการของระบบเช่น (systemd, logind, udev, DBus) และการเข้าถึงอุปกรณ์จะพร้อมใช้งาน คอนเทนเนอร์ไม่ได้ให้สิ่งนั้นโดยค่าเริ่มต้น
- ไม่มีเซิร์ฟเวอร์แสดงผลในตัว: GUI ของ Linux จำเป็นต้องมีตัวผสาน/เซิร์ฟเวอร์แสดงผล (X11 หรือ Wayland) คอนเทนเนอร์ไม่ได้จัดหาให้ ดังนั้นเราต้องทำเอง
- การเข้าถึง GPU: คอนเทนเนอร์ไม่ได้ทำการเสมือน GPU โดยค่าเริ่มต้น ดังนั้นคุณต้องส่งผ่านโหนดอุปกรณ์เข้าไปในคอนเทนเนอร์ และใน Windows ยังมีชั้น WSL เพิ่มเติมที่ต้องข้าม
มันคุ้มกับความยุ่งยากไหม?
แน่นอน นี่เป็นโครงการที่สนุกและให้รางวัลลึกซึ้งมาก ผมได้เรียนรู้มากมายเกี่ยวกับการทำงานภายในของ Docker และ Linux และมีความพึงพอใจแบบพิเศษที่เกิดขึ้นจากการแก้ไขปัญหาหลายชั่วโมงและในที่สุดก็เห็นผลลัพธ์จากงานของคุณ
งั้นฉันจะแนะนำไหม? ใช่ โดยเฉพาะถ้าคุณอยากรู้อยากเห็นและกำลังมองหาโปรเจ็กต์สุดแปลกในช่วงวันหยุดสุดสัปดาห์ แต่แม้ว่าคุณจะไม่อยาก ก็ยังมีประโยชน์เชิงปฏิบัติที่ฉันค้นพบ—เช่น การเข้าถึงเดสก์ท็อประยะไกล, กล่องทรายแบบใช้แล้วทิ้ง, และพื้นที่ทำงานเฉพาะ—ซึ่งทำให้เรื่องนี้มากกว่าแค่การทดลอง ฉันเห็นกรณีการใช้งานเชิงปฏิบัติที่นี่
แม้ว่ากฎที่ไม่เป็นทางการของ Docker จะมีเหตุผลอยู่ แต่บางครั้งบทเรียนที่มีค่าสูงสุดก็ได้จากการละเมิดมัน ดังนั้น เปิดเทอร์มินัลของคุณ ใช้ภาพที่สร้างไว้ล่วงหน้า (หรือกล้าและสร้างของคุณเอง!) และดูเวทมนตร์ด้วยตัวคุณเอง คุณอาจพบสิ่งที่คาดไม่ถึงบางอย่างระหว่างทางด้วย











