테크·3 min read
Docker 입문 — 개발자 필수 가이드
Docker의 핵심 개념부터 실전 사용법까지, 개발자가 알아야 할 Docker 기초를 정리했습니다.
Docker가 필요한 이유
"내 컴퓨터에서는 되는데..." — Docker는 이 문제를 해결합니다.
- 개발 환경을 코드로 정의
- 팀원 모두 동일한 환경에서 작업
- 로컬과 프로덕션의 차이 최소화
핵심 개념
이미지 (Image)
실행 환경의 스냅샷. Dockerfile로 정의합니다.
컨테이너 (Container)
이미지를 실행한 인스턴스. 격리된 프로세스.
Dockerfile
이미지를 만드는 레시피:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
자주 쓰는 명령어
# 이미지 빌드
docker build -t my-app .
# 컨테이너 실행
docker run -p 3000:3000 my-app
# 백그라운드 실행
docker run -d -p 3000:3000 my-app
# 실행 중인 컨테이너 확인
docker ps
# 컨테이너 중지
docker stop <container-id>
# 로그 확인
docker logs <container-id>
# 컨테이너 진입
docker exec -it <container-id> sh
Docker Compose
여러 서비스를 한 번에 실행:
# docker-compose.yml
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
pgdata:
# 전체 시작
docker compose up -d
# 전체 중지
docker compose down
# 로그 확인
docker compose logs -f app
Next.js Dockerfile 최적화
# 빌드 스테이지
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 프로덕션 스테이지
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]
multi-stage build로 최종 이미지 크기를 크게 줄일 수 있습니다.
.dockerignore
node_modules
.next
.git
*.md
.env*
개발 환경에서의 활용
Hot Reload와 함께 사용
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
command: npm run dev
volumes로 로컬 파일을 마운트하면 코드 수정 시 즉시 반영됩니다.
실무 팁
- Alpine 이미지 사용:
node:20대신node:20-alpine(900MB → 130MB) - 레이어 캐싱:
COPY package*.json먼저,COPY . .나중에 - non-root 유저: 보안을 위해 root가 아닌 유저로 실행
- healthcheck 추가: 컨테이너 상태 모니터링
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
- 시크릿 관리: 환경변수에 민감 정보 넣지 말고 Docker Secrets 사용