준비 및 확인사항

  • 단일 Docker 이미지의 크기는 2GB(유료 구독 시 5GB)까지 지원합니다. 큰 용량의 이미지를 활용해야 하는 경우, 컨테이너보다는 VM이나 온프레미스 방식의 인프라 사용이 적합할 수 있습니다.

Windows Server나 ARM 아키텍처 기반의 Docker 이미지 런타임은 지원하지 않습니다.

공통

Dockerfile 작성 시 root 권한으로 스크립트 작성

클라우드타입에서 Dockerfile을 이용하여 배포를 진행하시는 경우 UID 및 GID를 설정하는 스크립트를 작성해야 합니다. 배포되는 서비스는 보안 및 서비스 안정성을 위해 non-root 권한으로 실행하도록 권장하고 있어, Dockerfile로 배포 시 정상적으로 작동하지 않는 경우 아래의 예시를 참고하여 스크립트 수정 후 재배포해주세요.

  • Java Spring Boot(Gradle)

    # jar 파일 빌드
    FROM eclipse-temurin:11 as builder
    
    COPY gradlew .
    COPY gradle gradle
    COPY build.gradle .
    COPY settings.gradle .
    COPY src src
    RUN chmod +x ./gradlew
    RUN ./gradlew bootjar
    
    # jar 실행
    FROM eclipse-temurin:11 as runtime
    
    RUN addgroup --system --gid 1000 worker
    RUN adduser --system --uid 1000 --ingroup worker --disabled-password worker
    USER worker:worker
    
    COPY --from=builder build/libs/*.jar app.jar
    
    EXPOSE 8080
    
    ENTRYPOINT ["java", "-Dspring.profiles.active=${PROFILE}", "-jar", "/app.jar"]
    
  • Java Spring Boot(Maven)

    # jar 파일 빌드
    FROM eclipse-temurin:11 as builder
    
    WORKDIR /opt/app
    COPY .mvn/ .mvn
    COPY mvnw pom.xml ./
    RUN ./mvnw dependency:go-offline
    COPY ./src ./src
    # -Dmaven.test.skip=true 이 mvn install 단계에 설정되지 않으면
    # 환경변수가 주입되지 않은 상태에서 어플리케이션이 실행되어 에러 발생
    RUN ./mvnw clean install -Dmaven.test.skip=true
    
    # jar 실행
    FROM eclipse-temurin:11 as runtime
    
    RUN addgroup --system --gid 1000 worker
    RUN adduser --system --uid 1000 --ingroup worker --disabled-password worker
    USER worker:worker
    
    WORKDIR /opt/app
    EXPOSE 8080
    COPY --from=builder /opt/app/target/*.jar /opt/app/*.jar
    
    ENTRYPOINT ["java", "-Dspring.profiles.active=${PROFILE}", "-jar", "/opt/app/*.jar"]
    
  • Python Flask

    FROM python:3.9-slim-buster
    
    ENV PYTHONDONTWRITEBYTECODE=1
    ENV PYTHONUNBUFFERED 1
    
    ARG UID=1000
    ARG GID=1000
    
    RUN groupadd -g "${GID}" python \
      && useradd --create-home --no-log-init -u "${UID}" -g "${GID}" python
    WORKDIR /home/python
    
    COPY --chown=python:python requirements.txt requirements.txt
    RUN pip3 install -r requirements.txt
    
    # USER 변경은 반드시 pip 패키지 설치 스크립트 이후에 작성되어야 함
    USER python:python
    ENV PATH="/home/${USER}/.local/bin:${PATH}"
    COPY --chown=python:python . .
    
    ARG FLASK_ENV
    ARG DB_USERNAME
    ARG DB_PASSWORD
    ARG DB_URL
    
    ENV FLASK_ENV=${FLASK_ENV}
    ENV DB_USERNAME=${DB_USERNAME}
    ENV DB_PASSWORD=${DB_PASSWORD}
    ENV DB_URL=${DB_URL}
    
    EXPOSE 5000
    
    CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
    
  • Node.js

    # 의존성 설치
    FROM node:16-buster
    WORKDIR /app
    COPY package*.json ./ 
    RUN npm ci --only=production
    
    ENV NODE_ENV production
    
    COPY . .
    
    # node 이미지에 이미 "node"라는 사용자가 uid/gid 1000번으로 생성되어 있음
    USER node
    
    EXPOSE 3000
    CMD ["npm", "start"]
    
  • React

    # 프로젝트 빌드
    FROM node:16-buster AS builder
    WORKDIR /app
    COPY package*.json .
    RUN npm ci
    COPY . .
    RUN npm run build
    
    # Production 런타임
    FROM nginxinc/nginx-unprivileged:1.23 AS runner
    WORKDIR /usr/share/nginx/html
    COPY --from=builder /app/build .
    
    EXPOSE 3000
    CMD ["nginx", "-g", "daemon off;"]
    

Dockerfile 내부에서 ARG 와 ENV 로 선언된 값 활용

Dockerfile을 활용하여 배포하는 경우 다음과 같이 변수를 넘기는 두 가지의 방법이 있습니다.

  • 빌드 인자(Build Arguments): 빌드 시점에 주입
    docker build -t app:latest . --build-arg ARG1="VAL1" --build-arg ARG2="VAL2"
    
  • 환경 변수(Environment Variables): 런타임 시점에 주입
    docker run -d -p 8080:8080 --name app -e ENV1="VAL1" -e ENV2="VAL2" app:latest
    

참고

공식문서