> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ale.run/llms.txt
> Use this file to discover all available pages before exploring further.

# Dockerfile

> `ale`의 Dockerfile 템플릿을 활용해 Dockerfile을 간편하게 배포할 수 있습니다.

<Info>
  `ale` 의 템플릿 / 프리셋은 효율적인 리소스 관리를 위한 최소한의 라이브러리만 사용합니다.
  <Icon icon="windows" size={15} color="9fa3a5" /> **Windows,** <Icon icon="chrome" size={15} color="9fa3a5" /> **Chrome** 라이브러리처럼 기본으로 제공되지 않는 라이브러리를 사용하려는 경우,
  [예제 코드](/ko/developers/dockerfile#%EC%96%B8%EC%96%B4%EB%B3%84-%EC%B0%B8%EA%B3%A0-%EC%98%88%EC%A0%9C-%EC%BD%94%EB%93%9C)를 참고해 Dockerfile을 작성해서 배포하세요.
</Info>

***

## 저장소와 템플릿 선택

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_01.png" />
</Frame>

> 대시보드의 <Icon icon="circle-plus" iconType="solid" size={15} color="2396F1" /> 또는 `⌘ + K` 로 생성되는 배포창에서 **Dockerfile** 템플릿을 선택하고, 이어지는 드롭다운 메뉴에서 연동된 GitHub 계정의 저장소를 선택하거나 [Git URL 탭에서 Git 저장소 URL을 입력하세요.](/ko/developers/private-repo)

## 배포 설정과 배포

### 기본 설정

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_02.png" />
</Frame>

* **Environment variables(ENV)** : 컨테이너를 실행할 때 참조되는 환경변수

* **Build arguments(ARG)** : 이미지를 빌드할 때 참조되는 인자

* **Port** : 컨테이너가 실행되는 대상포트로, `docker run` 명령어의  `-p, --publish` 옵션에 적용되는 인자

* **Health Check** : 컨테이너 상태 검증 엔드포인트

* **Start commands** : 컨테이너 시작 명령어

### 더 많은 옵션

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_03.png" />
</Frame>

* **Dockerfile text** : Dockerfile의 전체 내용 입력

* **Build Labels(LABEL)** : Dockerfile로 컨테이너 이미지 빌드 시 버전, 라이센스 등 추가 정보 주입

* **uid** : 컨테이너에서 프로세스를 실행하는 사용자의 고유한 식별자(기본값 1000)

* **gid** : 컨테이너에서 프로세스가 속한 그룹의 고유한 식별자(기본값 1000)

* **Update strategy**

  * **Rolling Update** : 새로운 버전의 서비스 배포 시점에 기존 파드 종료, 노드 가용자원 확보 필요
  * **Recreate** : 모든 서비스 종료후 새로운 버전의 서비스 생성 및 구동, 다운타임 발생

* **Shell** : 컨테이너가 실행된 후 실행할 쉘(sh, bash, zsh 등)

### 성능(리소스) 설정과 배포

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_04.png" />
</Frame>

* **리소스 유형** : [온디맨드와 스팟 리소스](/ko/developers/resource#on-demand-spot) 중 선택

* **CPU** : 서비스가 사용할 vCPU 리소스의 최대값을 설정하며, '최소 vCPU' 선택 시 0.1 vCPU 사용

* **메모리** : 서비스가 사용할 메모리 리소스의 최대값을 설정

* [동시실행(레플리카)](/ko/developers/replica) : 설정한 수만큼 서비스가 수평확장되어 부하 분산 및 안정성 확보

* **배포** : `배포하기` 클릭

<Tip>
  리소스 제한으로 배포할 수 없는 경우 [스페이스 및 리소스 관리 페이지](/ko/operations/spaces#%EB%A6%AC%EC%86%8C%EC%8A%A4-%EB%B6%80%EC%97%AC%ED%95%98%EA%B8%B0)를 참고해 스페이스에 리소스를 추가하세요.
</Tip>

## 로그와 터미널

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_05.png" />
</Frame>

> 서비스 카드 또는 상세페이지의 **<Icon icon="terminal" size={15} color="9fa3a5" /> 아이콘**을 클릭하면, 배포/실행로그 조회 또는 터미널에 접속할 수 있습니다.

## 메트릭

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_06.png" />
</Frame>

> 서비스 상세페이지의 메트릭 탭에서, 서비스의 메트릭을 조회할 수 있습니다.

## 재배포(업데이트)

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_07.png" />
</Frame>

> **코드 수정, 리소스 변경 등** 업데이트할 내역이 있는 경우, 서비스 상세페이지 설정탭 하단부의 `배포하기`를 클릭하면 업데이트를 반영한 새로운 배포가 진행됩니다.

<Tip>
  배포 자동화를 위한 GitHub Actions 적용은 [GitHub Actions 페이지](/ko/developers/githubactions)를 참고하세요.
</Tip>

## 롤백(복원)

<Frame>
  <img className="block rounded-md" src="https://files.cloudtype.io/ale-docs/developers/images/08_08.png" />
</Frame>

> **서비스 상세페이지의 배포내역탭**에서 이전 버전의 서비스 상태로 복원할 수 있습니다.

<Tip>
  복원할 버전을 혼동하지 않기 위해, 커밋 메세지를 확인하세요.
</Tip>

## 언어별 참고 예제 코드

<AccordionGroup>
  <Accordion title="Node.js - Express">
    [Github 저장소로 이동](https://github.com/cloudtype-examples/docker-node-be)

    ```dockerfile theme={null}
    # 의존성 설치
    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"]
    ```
  </Accordion>

  <Accordion title="React">
    [Github 저장소로 이동](https://github.com/cloudtype-examples/docker-node-fe)

    ```dockerfile theme={null}
    # 프로젝트 빌드
    FROM node:16-buster AS builder
    WORKDIR /app
    COPY package*.json .
    RUN npm ci
    COPY . .
    RUN npm run build

    # Production 런타임 - nginx
    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;"]
    ```
  </Accordion>

  <Accordion title="Python Flask">
    [Github 저장소로 이동](https://github.com/cloudtype-examples/docker-python)

    ```dockerfile theme={null}
    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

    ENV FLASK_ENV=${FLASK_ENV}

    EXPOSE 5000

    # WSGI, 포트 번호, 모듈명 등은 각 소스 코드에 알맞게 수정하여 배포 진행
    CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
    ```
  </Accordion>

  <Accordion title="Spring Boot">
    [Github 저장소로 이동](https://github.com/cloudtype-examples/springboot-crud-example)

    ```dockerfile theme={null}
    # JDK 이미지를 통한 executable jar 빌드
    FROM eclipse-temurin:17-alpine AS build
    RUN apk add --no-cache bash

    WORKDIR /app

    COPY gradlew .
    COPY gradle gradle
    COPY build.gradle settings.gradle ./
    # COPY build.gradle.kts settings.gradle.kts ./    Kotlin인 경우 .kts 확장자 적용

    RUN ./gradlew dependencies --no-daemon

    COPY . .

    RUN chmod +x ./gradlew

    RUN ./gradlew bootJar --no-daemon

    # jar 실행을 위한 JRE 이미지 적용
    FROM eclipse-temurin:17-jre-alpine
    WORKDIR /app

    RUN addgroup -g 1000 worker && \
        adduser -u 1000 -G worker -s /bin/sh -D worker

    COPY --from=build --chown=worker:worker /app/build/libs/*.jar ./main.jar

    USER worker:worker

    EXPOSE 8080

    ENTRYPOINT ["java", "-jar", "main.jar"]
    ```
  </Accordion>

  <Accordion title="Spring Boot(멀티모듈)">
    [Github 저장소로 이동](https://github.com/cloudtype-examples/spring-multi-module)

    ```dockerfile theme={null}
    # JDK 이미지를 통한 executable jar 빌드
    FROM eclipse-temurin:17-alpine AS build
    RUN apk add --no-cache bash

    WORKDIR /app

    COPY gradlew .
    COPY gradle gradle
    COPY build.gradle settings.gradle ./
    # COPY build.gradle.kts settings.gradle.kts ./    Kotlin인 경우 .kts 확장자 적용

    RUN ./gradlew dependencies --no-daemon

    COPY . .

    RUN chmod +x ./gradlew

    RUN ./gradlew bootJar :api:bootJar --no-daemon
    # RUN ./gradlew bootJar :<main 지정 모듈명>:bootJar --no-daemon

    # jar 실행을 위한 JRE 이미지 적용
    FROM eclipse-temurin:17-jre-alpine
    WORKDIR /app

    RUN addgroup -g 1000 worker && \
        adduser -u 1000 -G worker -s /bin/sh -D worker

    COPY --from=build --chown=worker:worker /app/api/build/libs/*.jar ./main.jar
    # COPY --from=build --chown=worker:worker /app/<main 지정 모듈명>/build/libs/*.jar ./main.jar

    USER worker:worker

    EXPOSE 8080

    ENTRYPOINT ["java", "-jar", "main.jar"]
    ```
  </Accordion>

  <Accordion title="Spring Boot CRUD App(Gradle)">
    [Github 저장소로 이동](https://github.com/cloudtype-examples/springboot-crud-gradle)

    ```dockerfile theme={null}
    # Build
    FROM eclipse-temurin:17-alpine AS build
    RUN apk add --no-cache bash

    WORKDIR /app

    COPY gradlew .
    COPY gradle gradle
    COPY build.gradle.kts settings.gradle.kts ./

    RUN ./gradlew dependencies --no-daemon

    COPY . .

    RUN chmod +x ./gradlew

    RUN ./gradlew build --no-daemon -x test


    # Runtime
    FROM eclipse-temurin:17-jre-alpine AS runtime
    WORKDIR /app

    RUN addgroup -g 1000 worker && \
        adduser -u 1000 -G worker -s /bin/sh -D worker

    COPY --from=build --chown=worker:worker /app/build/libs/*.jar ./main.jar

    USER worker:worker

    ENV PROFILE=${PROFILE}

    EXPOSE 8080

    ENTRYPOINT ["java", "-Dspring.profiles.active=${PROFILE}", "-jar", "main.jar"]
    ```
  </Accordion>

  <Accordion title="Spring Boot CRUD App(Maven)">
    [Github 저장소로 이동](https://github.com/cloudtype-examples/springboot-crud-maven)

    ```dockerfile theme={null}
    # Build
    FROM eclipse-temurin:17-alpine AS build
    RUN apk add --no-cache bash

    WORKDIR /app

    COPY mvnw .
    COPY .mvn .mvn
    COPY pom.xml .

    RUN ./mvnw dependency:go-offline -B

    COPY . .

    RUN chmod +x ./mvnw

    RUN ./mvnw package -DskipTests


    # Runtime
    FROM eclipse-temurin:17-jre-alpine as runtime

    WORKDIR /app

    RUN addgroup -g 1000 worker && \
        adduser -u 1000 -G worker -s /bin/sh -D worker

    COPY --from=build --chown=worker:worker /app/target/*.jar ./main.jar

    USER worker:worker

    ENV PROFILE=${PROFILE}

    EXPOSE 8080

    ENTRYPOINT ["java", "-Dspring.profiles.active=${PROFILE}", "-jar", "main.jar"]
    ```
  </Accordion>
</AccordionGroup>
