서론
최근에 Docker에 관한 글을 보았는데 많이 신기했고 또 개발 환경과 배포 환경이 일치하는 것이 개발을 하는데 안정감을 준다고 생각하여 Docker에 대해 알아보았다.
Docker
Docker는 OS에 따른 에러 문제를 해결하기 위해 나왔다.
OS에 따른 문제가 여태까지는 없었는데?라고 할 수도 있다. 하지만 그건 여태까지이고 앞으로 OS가 달라도 에러가 생기지 않을 거라고 단정 짓고 보장할 수 있을까?
예시를 들어보자
현재 내가 사용하고 있는 OS는 MacOS이고 Server의 OS는 Linux이다.
내가 MacOS에서 개발을 하고 해당 파일을 Server에 올려 실행시켰지만 제대로 작동되지 않는다.
해결을 하려고 알아보니 OS 차이에서 발생하는 문제이다.
그렇다면 우리는 어떻게 해결을 해야 할까?
MacOS에서 오류가 나더라도 신경 쓰지 않고 Linux Server에 올려서 되는지 확인하여 문제를 해결해야 할까?
아니다 Docker처럼 개발, 배포 환경을 일치시켜 주는 tool을 사용하면 된다.
Image
Docker에서 Image는 진짜 우리가 평소에 알고 있는 사진이 아니고 애플리케이션 실행에 필요한 모든 것을 모아둔 패키지이다.
예시를 들어보자면 Nextjs 프로젝트를 실행시키기 위해서는 OS와 nodejs 그리고 nextjs 프로젝트가 필요하다. 이렇게 실행에 필요한 모든 것들을 모든 것들을 하나의 패키지로 만들어 둔 것이 Image이다.
Container
Container는 위에서 말한 Image를 독립적으로 실행시키는 실행 환경이다.
Image, Container를 정리하자면 Image는 프로그램, Container는 프로세스 or 클래스, 인스턴스 관계라고 생각하면 될 것 같다.
Nextjs
Nextjs 프로젝트를 Docker 환경에서 실행시켜 보겠다.
1. Image 빌드
Image를 만들기 위해서는 Dockerfile을 작성해줘야 한다.
Dockerfile은 어떻게 Image를 만들 것인지를 작성해 놓은 파일이라고 생각하면 된다.
FROM node:18-alpine
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
EXPOSE 3000
CMD ["pnpm", "dev"]
FROM node:18-alpine - nodejs 18 버전 + linux의 가벼운 버전이 세팅된 Image를 사용한다.
WORKDIR /app - 작업 디렉터리를 설정한다. (mkdir app, cd app 이런 느낌)
COPY package.json pnpm-lock.yaml ./ - package.json과 pnpm-lock.yaml 파일을 Image 파일에 복사한다.
RUN npm install -g pnpm - Image에 pnpm을 설치한다.
RUN pnpm install --frozen-lockfile - package.json과 pnpm-lock.yaml 파일을 기반으로 의존성을 설치한다.
COPY . . - 나머지 파일들을 복사한다.
RUN pnpm build - 빌드를 실행한다.
EXPOSE 3000 - 컨테이너의 포트를 3000번으로 지정한다.
CMD ["pnpm", "dev"] - 컨테이너가 실행되면 local server를 실행시킨다.
# build 명령어
docker build -t <Image name>:<tag> <Dockerfile location>
위의 빌드 명령어를 입력하면 Image가 생성된다.
# 현재 Image 확인 명령어
docker images
2. Image 실행
# Image 실행 -> Container 셍성 후 실행
docker run -p 3000:3000 <Image name>
-p 3000:3000 - Container의 3000번 포트를 내 Local의 3000번과 매핑하는 옵션이다.
이렇게 되고 http://localhost:3000를 접속하면 Image가 제대로 실행된 것을 알 수 있다.
이렇게 해도 사용가능하긴 한데 nextjs standalone 방식을 사용하면 더 가벼운 Image를 만들 수 있다.
Standalone
독립형 말그대로 배포에 필요한 파일만 남겨서 배포하는 형식이다.
기본 배포 방식과 Image 크기를 비교해보면 수치상으로는 약 1/6 크기로 줄어든다.
Dockerfile을 작성하기전에 next.config output 옵션을 standalone으로 변경해야한다.
module.exports = {
output: 'standalone',
}
FROM node:18-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public public
EXPOSE 3000
CMD ["node", "server.js"]
기본 배포 Dockerfile이랑 조금 다르다는것을 알수있는데 해당 방식은 멀티 스테이지 빌드(multi-stage build) 방식으로 작성되었다.
multi-stage build를 간단하게 설명하자면 Image를 build를 할때 n차로 공정을 가져간다고 생각하면 된다.
Dockerfile을 봐보면 첫스테이지에서는 프로젝트 전체를 COPY해서 build를 하고 다음 스테이지에서 필요한 것들만 COPY해서 Image의 크기를 가볍게 만들수 있는것이다.
개발 환경 세팅
이제 개발 환경을 세팅해보겠다.
일단 IDE는 VSCode를 사용하고있다.
extension 설치
해당 extension을 설치하면 sidebar에 Docker icon이 보인다.
클릭해보면 현재 build된 Image들, Container들이 보인다.
이제 Container를 실행시키고 안에있는 파일을 가져와서 작업을 진행하면 된다.
생각보다 쉽게 세팅 할수 있다.
마무리
오늘은 Docker에 대해 공부해보았다.
개발만 하던 나에게는 Docker는 OS 차이에 따른 에러를 방지할수있다는 점이 매력적이고 새로웠다.
현재 AWS ec2를 사용해서 배포도 완료했는데 다음에 글을 작성해보겠다.
'Develop' 카테고리의 다른 글
첫 취업 준비 후기 (0) | 2025.05.07 |
---|---|
2024년 회고.. (0) | 2025.01.10 |
QA, TC.... (1) | 2024.09.04 |
이젠 공식문서 읽읍시다..! feat. react-hook-form (1) | 2024.07.13 |
AI·SW 체험 축전 참가 회고 (2) | 2024.06.04 |