มาจับ React ยัดใส่ Container กันเถอะ! (React+Docker)
เคยเป็นกันรึเปล่า? รันโค้ดในเครื่องตัวเองผ่านแต่ทำไมรันเครื่องคนอื่นแล้วพังไม่เป็นท่าเลย วันนี้เราจะมาแก้ปัญหานั้นสำหรับการ Deploy react website กันโดยใช้ docker และ react
Docker คืออะไร?
Docker คือเทคโนโลยีที่ช่วยการ Development และการ Deployment ให้ง่ายขึ้นและไวขึ้น โดยเฉพาะถ้าเราทำงานกับ Microservices โดย Docker นั้นจะนำมาใช้ในการเชื่อมระหว่างแต่ละ Services ภายในโครงสร้างระบบของเรานั่นเอง และข้อดีอีกข้อที่สำคัญคือ การกำจัดปัญหาที่เกิดขึ้นจาก OS, หรือ Environment ที่เราทำงานอยู่ทำให้ไม่ว่าจะนำ Project นี้ไปทำงานที่ไหนก็ทำงานได้ โม้มามากแล้ว มาลองใช้จริงกันเลยจะดีกว่า!
ตัวอย่างนี้จะนำเสนอวิธีการนำ Create React App มาใช้งานกับ Docker
โดยสิ่งที่ต้องมีก็ได้แก่
- Node v9.+
- Docker CE v18.+
- Create React App v1.5.+
- Docker Compose
Project Setup
ทำการติดตั้ง create-react-app:
$ npm install -g create-react-app
ทำการติดตั้ง Docker ขั้นตอนของแต่ละ OS แตกต่างกันแนะนำให้ติดตั้งโดยศึกษาขั้นตอนผ่านลิงค์ข้างล่าง
- ติดตั้ง Docker (Community edition)
- ติดตั้ง Docker Compose
หลังจากที่ติดตั้งทุกอย่างสำเร็จแล้วก็จะทำการ generate project ขึ้นมา
$ create-react-app application
$ cd application
create-react-app จะทำการ generate โปรเจคที่ชื่อ application ขึ้นมา
หลังจากนั้นทำการสร้าง Dockerfile เพื่อใช้เป็น Instruction ในการสร้าง Container
# base image
FROM node:9.11
# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts -g
# start app
CMD ["npm", "start"]
Dockerfile ข้างต้นนั้นจะทำงานตามลำดับ
- ดึงข้อมูลจาก base image ของ node และนำไปใช้กับคำสั่งต่อๆไป
- สร้าง directory และ set directory เป็น base directory สำหรับใช้งานคำสั่ง RUN, COPY, CMD
- เพิ่ม node_modules เข้าไปใน environment path
- copy package.json ที่อยู่ใน directory ปัจจุบันไปไว้ใน container
- npm install เพื่อลง dependencies
- ทำการติดตั้ง react-scripts เพื่อใช้ในการเรียกใช้งานคำสั่งภายใน package.json
- npm start เพื่อเรียกใช้งาน react-scripts start
อ่านเพิ่มเติมเกี่ยวกับ Dockerfile
หลังจากนั้นทำการสร้าง .dockerignore เพื่อทำให้ build process รวดเร็วขึ้นเพราะ dependencies จะไม่ถูกส่งเข้าไปใน container
node_modules
เริ่มทำการ build image จาก dockerfile ภายใน directory ปัจจุบัน
$ docker build -t docker-react .
จะได้ images ชื่อ docker-react หลังจากนั้นก็ทำการเรียกใช้งาน container ผ่าน terminal ด้วยคำสั่ง
$ docker run -it \
-v ${PWD}:/usr/src/app \
-v /usr/src/app/node_modules \
-p 3000:3000 \
--rm \
docker-react
ผลลัพธ์ที่ได้จะอยู่บน localhost:3000 แต่เราก็ต้องเปิด process ที่ใช้เรียก container ค้างไว้ ทีนี้ถ้าเราไม่อยากเปิด process ค้างไว้แล้วสั่งให้มันทำงานอยู่เบื้องหลังแทนล่ะ? ก็เพิ่มคำสั่ง detach เข้าไป
$ docker run -it \
-v ${PWD}:/usr/src/app \
-v /usr/src/app/node_modules \
-p 3000:3000 \
--rm \
-d \
docker-react
จะสังเกตว่าถึงแม้เราจะย้าย development server เรามาไว้บน container เรียบร้อยแล้วแต่ก็ยังต้องผ่านกระบวนการมากมายกว่าจะได้ใช้งานและในกรณีที่ต้องทำ multi-container ตัวอย่างเช่น react production server ภายใต้ nginx ก็ทำให้ยุ่งยากอยู่ดี จึงขอนำ docker compose มาช่วยในการจัดการเรื่อง multi-container
การใช้งาน docker-compose ทำได้โดยการเพิ่ม docker-compose.yml ไว้ใน base directory
version: '3.5'services:sample-app:
container_name: react-docker
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- '3000:3000'
environment:
- NODE_ENV=${NODE_ENV}
และสร้าง .env ไว้สำหรับเรียกใช้ environment variables
#!/usr/bin/env bash# Node
NODE_ENV=development
หลังจากนั้นก็เรียกใช้งานคำสั่ง
$ docker-compose up -d --build
จบขั้นตอนการใช้งานสร้าง container โดยใช้ docker-compose ทีนี้ลูกเล่นเพิ่มเติมของ docker-compose ก็คือการเขียน multi-container สำหรับเรียกใช้งานหลายๆ application พร้อมๆกันโดยสามารถศึกษาเพิ่มเติมการเขียน docker-compose.yml จาก
อ่านเพิ่มเติมเกี่ยวกับ Docker Compose
วันนี้ก็ขอจบการสร้าง react container โดยใช้ docker เพียงเท่านี้
Happy coding ❤