Ops, Infra, etc/🐋 Docker (+Swarm)

docker 기반 nginx~react 개발 및 배포

DarrenKwonDev 2021. 3. 26. 01:38

1. 개발용 dockerfile과 배포용 dockerfile의 분리 및 stage

 

docs.docker.com/engine/reference/commandline/build/

 

Dockerfile과 Dockerfile.dev 두 파일을 생성하여 개발과 배포에서 각각 다른 Docker image를 사용하도록 합시다.

 

Dockerfile.dev

FROM node:alpine

WORKDIR /usr/src/app

COPY package.json ./
COPY package-lock.json ./

RUN yarn

# 로컬에 node_modules있으면 지워주자.
COPY ./ ./

CMD ["yarn", "start"]

 

Dockerfile

 

여기서 조금 다른 점은 'as builder'의 존재입니다.

builder의 경우 시작하는 FROM부터 다음 FROM까지 builder stage임을 명시해줍니다.

도커에는 stage라는 개념이 있는데, 다른 포스트에서 다뤄보록하겠습니다.

우선은 builder stage가 존재하며, as builder로 지정할 수 있다는 것,

run stage에서 builder 스테이지에 있는 파일을 가져올 때는 --from으로 명시해줘야 한다는 것을 알아둡시다.

# builder stage
FROM node:alpine as builder

WORKDIR '/usr/src/app'

COPY package.json .
COPY package-lock.json ./

RUN yarn

# 로컬에 node_module 있으면 지워줄 것
COPY ./ ./

RUN yarn build

# run stage
FROM nginx
EXPOSE 80
COPY --from=builder /usr/src/app/build /usr/share/nginx/html

 

Docker 명령어로 빌드시 (권장 안 됨. docker-compose 쓰세요 걍...)

docker build -t [name] .     // Dockerfile 빌드

docker build -t react-sample .     // Dockerfile을 참고하여 react-sample이란 이름으로 이미지 빌드함
docker build -f [dockerfile name] .     // Dockerfile 외의 다른 이름을 가진 Dockerfile을 빌드함

docker build -f Dockerfile.dev .     // Dockerfile.dev를 이용하며 이미지를 빌드함 이름은 none이 됨

docker build -f Dockerfile.dev -t react-sample-dev .	  // Dockerfile.dev를 이용. 이미지 이름은 react-sample-dev

 

그런데 사실 이런 문제들은, docker-compose를 사용하면 신경쓸 이유가 없는 것들입니다. build를 알아서 해주니까요. 

서빙을 위해 nginx와 같이 yml을 작성해보았습니다.

version: "3"
services:
  proxy:
    image: nginx:alpine
    container_name: proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    restart: "unless-stopped"
    
  react-dev:
    build: 
      context: .
      dockerfile: Dockerfile.dev
    ports:
     - "3000:3000"
    volumes:
     - /usr/src/app/node_modules # 로컬에 node_modules 없으니 매핑하지 말라
     - ./:/usr/src/app # 매핑
    stdin_open: true # docker run의 -i 옵션. react 한정으로 필요함.

 

docker 쓰면서 참 좋은 점이, 배포 환경을 실제로 로컬에서 작동 시켜봐서, 무의미한 커밋을 크게 줄일 수 있다는 점입니다.

너무 좋드아~~~

 

 

2. (node 한정) 로컬에 node_modules가 필요 없다.

 

다음을 개발용 dockerfile 내용이다. 흐름을 살펴보면, 당연히 node_module을 로컬에 가지고 있을 이유가 없다.

아니, 가지고 있으면 오히려 시간을 더 잡아먹는 악재다.

docker 기반 개발할 때는 로컬에 굳이 의존성 설치할 이유가 없어진다.

FROM node:alpine

WORKDIR /usr/src/app

COPY package.json ./
COPY package-lock.json ./

RUN yarn

# 이 단계에서 굳이 node_module을 가져올 필요는 없다.
# 컨테이너에 yarn으로 이미 설치했잖아.
COPY ./ ./

CMD ["yarn", "start"]

 

 

그 외의 자잘한 내용들)

 

  • docker run에서 -it 옵션은 버릇처럼
  • docker-compose up에서 --build는 버릇처럼
  • React 이 녀석은 -i 옵션 주던가, stdin_open: true로 설정해놓을 것.
  • test 코드가 있다면 별도 컨테이너를 따로 올릴 것.