Docker & Node.js

Sittipong Saychum
NECTEC
Published in
3 min readFeb 16, 2021

เนื่องจากจำเป็นต้องใช้ windows ในการพัฒนา node.js ตอนแรกคิดว่าจะลง node.js ที่เครื่องเลย แต่คิดไปคิดมาเนื่องจากมันมีข้อจำกัดบางอย่างที่ทำไม่ได้ (เอาไว้ว่างๆ จะมีเล่าให้ฟัง) ก็เลยคิดได้ว่าลง docker ดีกว่า วันนี้ก็เลยจะมารื้อฟื้นความจำเรื่อง docker ซะหน่อยยิ่งบน windows ผมถือว่าผมมือใหม่เลยล่ะ

ก่อนอื่นต้อง download เจ้า docker destop มาก่อน

https://www.docker.com/products/docker-desktop

เครื่องผมเป็น windows 10 pro ไม่มีปัญหาเรื่อง wsl 2 หลังจากลงเสร็จแล้วต่อไปให้อัพเดทหรือติดตั้ง WSL2

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

จากนั้นเปิด PowerShell ขึ้นมาแล้วรับคำสั่ง

wsl --set-default-version 2

เสร็จแล้วเข้าไปที่ Microsoft store ลง ubuntu version ล่าสุด เสร็จแล้วเปิด docker destop ไปที่ Setting > Resources > WSL Integration แล้วเซ็ตค่าตามรูปด้านล่าง

ผมต้องการสร้าง docker container node.js ผมต้อง ทำการ pull image node มาเสียก่อน ให้เป็น PowerShell แล้วใช่ทำสั่ง docker pull

docker pull node

ใช้คำสั่งด้านล่างจะเห็น image ที่เรา pull มา

docker image ls

เนื่องจากไอ้เจ้า node image มันไม่มี openssh-server เราต้องลงให้มันก่อน แต่เราจะไม่สามารถ commit สิ่งที่เราทำภายใน container ได้ดังนั้นเราจำเป็นต้อง สร้าง image เราก่อน ให้ใช้คำสั่งด้านล่างนี้ เพื่อสร้าง image ของเราเอง แนะนำให้ใช้คำสั่งโดยมี user/ก่อนหน้าชื่อใหม่ image ด้วยนะครับ เพราะจะสามารถ push เข้าไปใน Docker Hub ของเราได้ด้วย

docker tag image_id user/new_name

เสร็จแล้วเรามาสร้าง container กันดีกว่าครับ

docker run --name name_container -it -p 80:8888 -p 8822:22 -v D:\Docker:/opt/docker image_name

— name name_container คือ การตั้งชื่อให้กับ Container โดยเมื่อเราใช้คำสั่ง start stop หรือ rm สามารถสั่งงาน container ได้จากชื่อ container ได้เช่นกัน

-d เป็นการสั่ง Container ให้รันแบบ background หรือใช้ -it เพื่อเป็นการสั่ง Container ให้รันแบบ interactive

-v $(pwd)/me:/home/docker คือการ mount volume หรือเป็นการแชร์ไฟล์ระหว่าง container กับเครื่องเราให้สามารถเรียกใช้ไฟล์ร่วมกันได้

-p 80:8888 เป็นการ map port ระหว่างเครื่อง และ container

image_name ชื่อของ Docker image ที่เราต้องการเรียกใช้

เสร็จแล้วใช้คำสั่งด้านล่างเพื่อเข้าไปยัง container ที่เรารันไว้

docker exec -it name_container /bin/bash

เข้ามาแล้วทำการเพิ่ม user เข้าไปก่อนใช้ตอนเรา ssh เข้ามาจาก VSCode

แต่ถ้าอยากให้ root สามารถ login ผ่าน ssh ได้ ให้เข้าไปที่

/etc/ssh/sshd_config

แล้วแก้ PermitRootLogin ให้เป็น yes

# Authentication:
#LoginGraceTime 2m
PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

อย่าลืม set password ให้ root ด้วยนะ

passwd

หลังจากนั้นให้ลงตัว net-tool และ openssh

apt update
apt install net-tools
apt install openssh-server

ลอง start service แล้วลองใช้คำสั่งด้านล่าง check port ดู

service ssh start
netstat -tunlp

จะเห็นว่า port เปิดให้บริการเรียบร้อยแล้ว

ทดสอบ ssh เข้าใช้งาน

ssh root@localhost -p 8822

คราวนี้เราจะทำการ commit ที่เราทำการ modify container ของเราให้เข้าไปอยู่ใน image ใช้คำสั่ง ด้านล่างเพื่อดู container_id

docker ps

แล้วใช้คำสั่ง commit image ของเราจะมี user ที่เรา add เข้าไป และ openssh แล้ว

docker commit  container_id name_images

จากนั้นเราจะมาสร้าง Dockerfile(ตั้งชื่อไฟล์แบบนี้เลย) หน้าตาจะเป็นแบบด้านล่าง เพื่อสร้าง image จากตัวที่เรา modify มา เพื่อที่จะสามารถ สั่งให้ container เรา start service ต่างได้

FROM baseImage
COPY source destination (copy ไฟล์จากเครื่องเราไป container)
EXPOSE port (Open TCP/UDP port)
ENV name=value (define variable in the container environment)
RUN apt-get update && apt-get install -y vim (รันเฉพาะตอน build)
WORKDIR path
CMD [command] (ใช้ cmd script ใน workdir)

ตัวอย่าง

FROM bablueza/ubuntu20miniconda3:latest
EXPOSE 8888 22
WORKDIR /opt/Vaja_WebAPP/
CMD ["./startService.sh"]

ผมต้องสร้างไฟล์ startService.sh ไว้ใน folder /opt/Vaja_WebAPP/ ด้วย หน้าตาก็จะประมาณนี้

#!/bin/bash
#export LANG=th_TH.UTF-8
service ssh start
# wait forever
while true; do
sleep 3600
done

เสร็จแล้วใช้คำสั่งด้านล่างนี้เพื่อสร้าง image

$docker build -t user/ตั้งชื่อ_image:version path_dockerfile

ตัวอย่าง

docker build -t babalueza/vajaapp_node:latest .

เสร็จแล้ว ใช้คำสั่ง docker run แล้วลองเข้าจาก VSCode ได้เลย

--

--