리액트를 다운 및 설치 받는다.
npx create-react ./
개발환경에서 사용할 Dockerfile.dev
를 작성해보자.
FROM node:alpine
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY ./ ./
CMD ["npm", "run", "start"]
이미지를 생성해주자
docker build ./
그런데 우리를 반기는 건 이런 에러이다.
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /Users/choi/Desktop/docker-react-app/Dockerfile: no such file or directory
원래 build하면 그 안에서 Dockerfile을 스스로 찾아서 이미지를 생성했는데 현재는 Dockerfile.dev가 있기에 못찾았다고 에러가 뜨는 것이다.
이럴 때는 옵션을 통해 참조해야 하는 파일명을 알려주면 된다.
docker build -f Dockerfile.dev ./ -t <이미지_이름>
이미지 생성이 잘 된다!!
자 이제 컨테이너를 실행해보자.
docker run <이미지_이름>
리액트 기본 포트는 3000으로 http://localhost:3000으로 들어가보자.
실행이 안된다😂 왜일까?!
포트 매핑을 안해줬으니 당연히 들어가지 못하고 있는 것이다
포트 매핑을 해주자
docker run -p 3000:3000 -it <이미지_이름>
-it
를 꼭 넣어줘야 한다.(여기서 i
는 상호입출력, t
는 bash 쉘을 이용)
잘 돌아간다!!!!!
COPY 대신 VOLUME을 이용하면 소스를 변경했을 때 다시 이미지를 빌드하지 않아도 반영되기에 적용해보겠다.
docker run -p 3000:3000 -v /usr/src/app/node_modules -v $(pwd):/usr/src/app <이미지_이름>
너무 길어요...해결할 수 있는 방법이 없을까🤔
version: "3"
services:
react:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- /usr/src/app/node_modules
- ./:/usr/src/app
stdin_open: true
version
: 도커 컴포즈의 버전services
: 이곳에 실행하려는 컨테이너들 정의react
: 컨테이너 이름build
: 한 디렉토리에 있는 Dockerfile 사용context
: 도커 이미지를 구성하기 위한 파일과 폴더들이 있는 위치dockerfile
: 도커 파일 어떤 것인지 지정ports
: 포트매핑 로컬포트:컨테이너포트volumes
: 로컬 머신에 있는 파일들 매핑stdin_open
: 리액트 앱을 끌 때 필요docker-compose를 통해 실행해보자
docker-compose up
잘 실행되는 것을 확인할 수 있다!!
docker run -it <이미지_이름> npm run test
테스트 소스가 추가되면 바로 반영되게 만들고 싶다. 이를 위해서는 소스 코드 변경을 위해 Volume을 이용한 것처럼 이번에도 Volume을 이용하지만 Test를 위한 컨테이너를 Compose 파일에 하나 더 만들어주면 된다.
version: "3"
services:
react:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- /usr/src/app/node_modules
- ./:/usr/src/app
stdin_open: true
test:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- /usr/src/app/node_modules
- ./:/usr/src/app
command: ["npm", "run", "test"]
test
: 컨테이너 이름build
: 현 디렉토리에 있는 Dockerfile 사용context
: 도커 이미지를 구성하기 위한 파일과 폴더들이 있는 위치dockerfile
: 도커 파일 어떤 것인지 지정volumes
: 로컬 머신에 있는 파일들 매핑command
: 테스트 컨테이너 시작할 때 실행되는 명령어이렇게 되면 앱을 시작할 때 두 개의 컨테이너를 다 시작하게 되니, 먼저 리액트 앱을 실행하고 그 앱을 테스트도 하게 된다.
두 개의 컨테이너 모두 다 실행해보자
docker-compose up --build
리액트 앱과 테스트가 둘 다 진행되는 모습을 볼 수 있다😎
리액트 개발환경에서 필요한 이미지를 생성하기 위해서는 Dockerfile.dev
리액트 운영환경에서 필요한 이미지를 생성하기 위해서는
Dockerfile
이 필요하다.
개발환경에서 리액트가 실행되는 과정
개발 서버가 따로 있고, build 되지 않은 파일들로 실행된다.
운영환경에서 리액트가 실행되는 과정
Dockerfile
에서 필요한 것은 build 파일을 생성하고(Builder Stage), nginx 도커 이미지를 이용한 nginx 가동(Run Stage)이 필요하다.
Dockerfile을 작성해보자.
#여기 FROM부터 다음 FROM전까지 모두 builder stage라는 것 명시
FROM node:alpine as builder
WORKDIR '/usr/src/app'
COPY package.json ./
RUN npm install
COPY ./ ./
CMD ["npm", "run", "build"]
FROM nginx
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
--from=builder
: 다른 Stage에 있는 파일 복사할 때 다른 Stage 이름 명시/usr/src/app/build /usr/share/nginx/html
: builder stage에서 생성된 파일들은 /usr/src/app/build
로 들어가게 되며, 그곳에 저장된 파일을 /usr/share/nginx/html
로 복사를 시켜줘서 nginx가 웹 브라우저의 http 요청이 올 때마다 알맞은 파일을 전해 줄 수 있게 만든다.자, 이제 이미지를 생성해준다.
docker build ./ -t <이미지_이름>
컨테이너를 실행시킨다.
docker run -p 8080:80 <이미지_이름>
http://localhost:80 으로 들어가면 잘 나온다!