본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

앱 구성 (fly.toml)

원문 보기 위키 갱신

fly.toml 파일을 사용해 Fly.io에 배포할 앱을 구성하는 방법을 알려드릴게요. 빌드, 환경 변수, 인터넷에 노출되는 서비스, 디스크 마운트, 릴리스 명령 등에 대한 설정이 모두 여기 들어갑니다. Fly Launch 명령으로 관리되는 앱에 이 fly.toml 구성이 적용돼요.

출처: 문서

본문

fly.toml 파일을 사용해 Fly.io에 배포할 앱을 구성할 수 있습니다. 빌드, 환경 변수, 인터넷에 노출되는 서비스, 디스크 마운트, 릴리스 명령에 대한 구성이 여기에 들어갑니다. fly.toml 구성은 Fly Launch 명령으로 관리되는 앱에 적용됩니다.

앱 구성 파일

대부분의 경우 fly launch로 앱을 만들 때 자동으로 얻는 fly.toml 파일을 사용하게 됩니다. 구성 파일을 재사용하거나 다른 형식으로 생성하는 방법도 있습니다.

구성 파일을 얻는 방법

  • 프로젝트 소스 디렉토리에서 flyctl launch를 실행해 새 앱과 fly.toml 파일을 자동으로 만듭니다.
  • flyctl config save -a <existing-app-name>를 실행해 기존 앱에서 fly.toml 파일을 다운로드합니다.
  • 이 참조 문서의 도움을 받아 직접 만들거나, 예시 파일을 복사해 수정합니다.

구성 파일 형식

Fly Launch가 생성하는 기본 구성 파일의 이름은 fly.toml입니다.

TOML은 간단한 구성 파일 형식입니다. VSCode 사용자라면 Even Better TOML 확장을 설치해 이 문서에서 얻은 힌트와 함께 fly.toml 검증을 자동으로 수행할 수 있습니다.

구성 파일을 JSON이나 YAML 형식으로 원한다면 flyctl 명령에서 --json과 --yaml 옵션을 사용하세요:

  • fly launch에 --yaml 또는 --json 옵션을 추가하세요.
  • 기존 앱의 경우 fly config save -a <existing-app-name을 실행하고 --yaml 또는 --json을 지정하세요. 완료되면 우선순위가 높은 fly.toml 파일을 제거하세요.
  • fly config show --local을 실행해 터미널에서 다양한 형식을 미리 볼 수 있습니다. fly config show는 기본적으로 JSON이며, --toml 또는 --yaml 옵션도 지정할 수 있습니다.

app 이름

모든 fly.toml 파일의 첫 번째 key/value는 애플리케이션 이름입니다. 이 이름은 애플리케이션이 기본적으로 사용할 호스트 이름을 만드는 데도 사용됩니다. 예:

app = "restless-fire-6276"

flyctl이 실행될 때마다 현재 디렉토리에서 fly.toml 파일을 찾고 그 안의 애플리케이션 이름을 사용합니다. 이 동작은 -a 플래그로 애플리케이션 이름을 설정하거나, 일부 명령(예: deploy)에서 -c 플래그로 다른 fly.toml 파일을 가리켜 재정의할 수 있습니다.

기본 지역(primary region)

fly deploy는 primary_region 옵션을 사용해 새 Machines를 만들 위치를 결정하고, 배포하는 Machines 안에 PRIMARY_REGION 환경 변수를 설정합니다. ord를 원하는 Fly 지역의 세 글자 코드로 바꾸세요.

primary_region = "ord"

런타임 옵션

실행 중인 애플리케이션의 수명 주기를 제어하는 데 사용할 수 있는 옵션입니다. 선택 사항이며 fly.toml 파일의 최상위에 배치할 수 있습니다:

kill_signal 옵션

Fly Machine을 종료할 때 Fly.io는 기본적으로 실행 중인 프로세스에 SIGINT 신호를 보냅니다. 보통 대부분의 애플리케이션에서 하드 종료를 트리거합니다. kill_signal 옵션을 사용하면 다른 신호로 재정의해 더 부드럽고 덜 방해하는 종료를 트리거할 수 있습니다: SIGTERM, SIGQUIT, SIGUSR1, SIGUSR2, SIGKILL, SIGSTOP.

예를 들어 kill 신호를 SIGTERM으로 설정하려면 다음을 추가하세요:

kill_signal = "SIGTERM"

kill_timeout 옵션

참고: `kill_timeout` 설정은 최선(best-effort)으로 간주해야 하며, 앱은 더 짧은 중지 시간을 처리할 준비가 되어 있어야 합니다.

이 옵션은 Fly.io가 kill_signal을 보낸 후 강제 종료로 넘어가기 전에 기다리는 시간(초)을 설정합니다. 앱이 우아하게(gracefully) 종료할 충분한 시간을 주는 값으로 kill_timeout을 설정하세요. 기본값은 5초입니다. 최대 300초(5분)까지 설정할 수 있습니다.

예를 들어 타임아웃을 2분으로 설정하려면:

kill_timeout = 120

종료 시퀀스가 동작하는 방식

이 옵션들은 다음과 같은 통제된 종료 중에 사용됩니다:

  • fly deploy 사용 시
  • fly machine stop 사용 시
  • auto_stop_machines로 머신이 중지될 때

시퀀스는 다음과 같습니다:

  1. Fly가 메인 프로세스(Dockerfile의 ENTRYPOINT 또는 CMD로 정의되거나 --entrypoint로 재정의된)에 kill_signal을 보냅니다.

  2. 최대 kill_timeout 초 동안 기다립니다.

  3. 그런 다음 무조건적으로 SIGTERM을 보냅니다.

이렇게 하면 앱이 요청을 마치고, 연결을 닫고, 새 작업 수신을 중지하는 등 깔끔하게 종료할 기회를 얻습니다. 5분 안에 마무리할 수 있는 앱을 위해 설계되었습니다.

많은 워커는 완료되지 않은 작업을 다시 큐에 넣어 다른 머신이 처리하게 합니다. 앱이 이를 지원하지 않거나 종료에 더 오랜 시간이 필요하다면 그에 맞춰 계획해야 합니다.

배포나 유휴 중지 중에 fly logs를 보면 종료 동작을 관찰할 수 있습니다.

콘솔 명령

fly console 명령을 실행할 때 실행할 명령입니다. console_command 필드를 프레임워크의 콘솔을 여는 명령으로 구성하면, fly console이 새 전용 Machine에서 해당 명령을 자동으로 실행합니다. 새 Machine은 앱의 최신 릴리스 이미지와 환경으로 구성되지만, 앱은 시작되지 않으며 트래픽도 라우팅되지 않습니다. 콘솔을 종료하면 Machine은 파괴됩니다.

Django용 콘솔 명령 예시:

console_command = "/code/manage.py shell"

swap_size_mb 옵션

이 옵션을 설정하면 Machines에서 Linux 스왑을 활성화합니다. swap_size_mb 크기(메가바이트 단위)의 스왑 파티션이 생성됩니다.

디스크로 스와핑하면 메모리 사용량의 짧은 급증 시 메모리 부족(OOM) 크래시를 피하는 데 도움이 될 수 있습니다. 스왑은 RAM보다 훨씬 느리므로, 성능이 중요하다면 fly scale memory로 Machine 메모리를 늘리는 것이 더 나은 해결책입니다.

swap_size_mb = 512

build 섹션

선택적인 빌드 섹션은 애플리케이션이 어떻게 빌드되어야 하는지에 관한 key/value를 포함합니다. 빌더에 대해 더 알아보려면 Builders and Fly를 읽어보세요.

builder

[build]
  builder = "paketobuildpacks/builder-jammy-base"

builder "builder"는 CNB Buildpacks와 Builders를 사용해 애플리케이션 이미지를 만듭니다. 이들은 Heroku 호환 빌드 프로세스나 다른 도구를 사용할 수 있는 타사 툴킷입니다. 모든 도구는 빌드팩에 의해 관리되며, 빌드팩은 도구 체인을 실행하는 OS와 빌드팩을 포함한 이미지인 CNB Builders로 조립됩니다.

위 예시에서 builder는 필요한 빌드팩을 자동으로 감지하는 Paketo의 범용 builder를 사용하도록 설정됩니다.

빌드팩을 명시적으로 정의할 수도 있습니다:

[build]
  builder = "paketobuildpacks/builder-jammy-base"
  buildpacks = ["docker.io/paketobuildpacks/nodejs"]

Docker 이미지 지정하기

[build]
  image = "flyio/hellofly:latest"

image builder는 기존 공개 이미지를 즉시 배포하려 할 때 사용됩니다. 배포 시 빌드 과정이 없으며 이미지는 그대로 Fly.io 인프라에 준비·업로드됩니다. 이 옵션은 이미 동작하는 Docker 이미지가 있거나, 저장소에서 잘 알려진 Docker 이미지를 실행하고 싶을 때 유용합니다.

Dockerfile 지정하기

[build]
  dockerfile = "Dockerfile.test"

dockerfile은 Dockerfile에 대한 상대 경로 또는 URL을 허용합니다. 기본적으로 flyctl은 애플리케이션 루트에서 Dockerfile을 찾습니다.

**주의사항:**
  • 이 옵션은 기본적으로 프로젝트 루트 디렉토리로 설정되는 Docker 컨텍스트 경로를 변경하지 않습니다. Dockerfile이 포함된 디렉토리를 컨텍스트 루트로 사용하려면 fly deploy <directory>를 사용하세요.
  • 로컬 Dockerfile을 지정할 때 .dockerignore에서 Docker 빌드 컨텍스트에서 제외되지 않도록 확인하세요.

Docker ignore 파일 지정하기

[build]
  ignorefile = "/path/.dockerignore"

ignorefile은 .dockerignore 파일에 대한 상대 경로를 허용합니다. 기본적으로 flyctl은 작업 디렉토리에서 .dockerignore 파일을 찾습니다.

멀티 스테이지 Docker 빌드 타겟 지정하기

[build]
  build-target = "test"

Dockerfile에 여러 스테이지가 있다면 그중 하나를 배포 타겟으로 지정할 수 있습니다. 타겟 스테이지에는 CMD 또는 ENTRYPOINT가 설정되어 있어야 합니다.

Docker 빌드 인자 지정하기

[build.args] 하위 섹션을 사용해 Dockerfile과 Buildpack 빌드 모두에 빌드 타임 인자를 전달할 수 있습니다:

[build.args]
  USER="plugh"
  MODE="production"

flyctl deploy에 --build-arg를 사용해 빌드 인자를 전달할 수도 있습니다. 명령줄 인자가 fly.toml의 같은 이름의 인자보다 우선합니다.

빌드 인자는 런타임 컨테이너에서 사용할 수 없습니다는 점에 유의하세요. Git 리비전 같은 빌드 정보를 런타임에 필요로 한다면 빌드 시점에 파일로 저장하세요. 예:

RUN echo $GIT_REVISION > REVISION

마찬가지로 애플리케이션 환경 변수와 시크릿도 빌드에서 사용할 수 없습니다.

deploy 섹션

이 섹션은 릴리스 명령이나 배포 전략 같은 배포 관련 설정을 구성합니다.

릴리스 전에 일회성 명령 실행하기

release_command는 배포된 Machines가 생성되거나 업데이트되기 전에 데이터베이스 마이그레이션 같은 일회성 작업을 실행할 수 있게 해 줍니다. 새로 빌드된 이미지를 사용해 임시 Machine에서 배포 시도당 한 번 실행됩니다. 이는 Rails나 Phoenix 같은 프레임워크에서 흔한 패턴이지만 그에 국한되지는 않습니다. 앱이 부팅할 때마다가 아니라 한 번만 실행해야 하는 모든 설정 작업에 사용할 수 있습니다.

명령이 실패하면 배포가 중지됩니다. 목표는 배포를 더 안전하게 만드는 것입니다. 위험한 부분을 먼저 하고, 성공할 때만 계속하는 것입니다.

릴리스가 배포되기 전에 임시 Machine에서 명령을 실행하려면 release_command를 정의하세요:

[deploy]
  release_command = "bin/rails db:prepare"

release_command 값은 임시 Machine의 CMD를 대체합니다. 데이터베이스 마이그레이션에 가장 흔히 사용되지만, 앱을 새 릴리스에 준비시키는 어떤 작업이든 될 수 있습니다. Docker 이미지의 ENTRYPOINT는 release_command로 재정의되지 않으며 항상 실행된다는 점에 유의하세요.

기본적으로 임시 Machine은 네트워크, 환경 변수, 시크릿에 대한 전체 접근 권한을 갖지만 영구 볼륨에는 접근하지 않습니다. 임시 Machine의 파일 시스템에 대한 변경은 유지되지 않습니다. 볼륨이 연결되어 있지 않으며, 명령이 완료된 후 Machine은 파괴됩니다. 프로젝트의 빌드/컴파일은 Dockerfile에서 수행해야 합니다. 영구 볼륨을 수정하거나 애플리케이션을 구성해야 한다면 Dockerfile의 CMD나 ENTRYPOINT, 또는 프로세스 그룹 명령을 사용하는 것을 고려해 보세요.

임시 Machine은 flyctl v0.0.508부터 앱의 기본 프로세스 그룹에서 가장 큰 Machine의 크기를 상속합니다(비어 있거나 새 앱에서는 Machine shared-cpu-2x 프리셋으로 더 크게 기본 설정됩니다). 기본 프로세스 그룹은 app 프로세스 또는 (app 프로세스가 없을 때) 알파벳 순으로 첫 번째 프로세스 그룹으로 정의됩니다.

[deploy.release_command_vm]을 설정해 Machine 크기를 명시적으로 정의할 수도 있습니다. 예:

[deploy]
  release_command = "bin/rails db:prepare"

  [deploy.release_command_vm]
    size = "performance-1x"
    memory = "8gb"

이 명령의 0이 아닌 종료 상태는 배포를 중지합니다. fly deploy는 명령의 로그를 표시합니다. 로그는 fly logs에서도 볼 수 있습니다.

dfw 같은 특정 지역에서 명령이 실행되도록 하려면 fly.toml의 애플리케이션 환경에 PRIMARY_REGION = 'dfw'를 설정하거나 fly deploy -e PRIMARY_REGION=dfw를 사용하세요. 여러 지역에 데이터베이스 복제본을 실행하는 경우 PRIMARY_REGION 설정은 중요합니다.

임시 릴리스 Machine 안에는 RELEASE_COMMAND=1 환경 변수가 설정됩니다. 이를 사용해 릴리스 Machine에서 실행 중일 때만 적용되는 동작을 Dockerfile의 ENTRYPOINT에 정의할 수 있습니다.

기본적으로 릴리스 명령은 종료되기 전까지 5분의 시간이 있습니다. fly deploy --release-command-timeout=10m을 사용하거나 fly.toml의 [deploy] 섹션에 release_command_timeout = "10m"을 설정해 타임아웃을 늘리거나 줄일 수 있습니다.

자세한 맥락은 Seamless Deployments 가이드를 참조하세요.

**`release_command`에 대해 알아야 할 것:**
  • CMD는 대체하지만 ENTRYPOINT는 대체하지 않습니다
  • 볼륨이 없는 임시 Machine에서 실행됩니다
  • 환경, 시크릿, 네트워크 구성은 상속합니다
  • 0이 아닌 종료 코드면 배포가 실패합니다
  • 기본적으로 5분 후 타임아웃됩니다(구성 가능)
  • 로그는 fly deploy와 fly logs로 스트리밍됩니다

배포 전략 선택하기

[deploy]
  strategy = "bluegreen"

strategy는 새 릴리스가 이전 릴리스를 대체하는 방식을 제어합니다. 각 전략은 다운타임과 신뢰성 사이에 서로 다른 트레이드오프를 제공합니다.

strategy는 배포 시점에 flyctl deploy --strategy로도 지정할 수 있습니다.

사용 가능한 전략:

rolling: 볼륨이 있거나 없는 앱의 기본 전략입니다. 실행 중인 각 Machine이 하나씩 내려지고 새 릴리스 Machine으로 교체됩니다.

immediate: 헬스 체크 통과를 기다리지 않고 모든 Machines를 새 릴리스로 즉시 교체합니다. 이는 릴리스 상태에 확신이 있고 헬스 체크를 기다릴 수 없는 긴급 상황에 유용합니다.

canary: 새 릴리스로 단일 새 Machine을 부팅해 헬스 상태를 확인한 다음 rolling 재시작 전략으로 진행합니다. canary 전략은 볼륨이 연결된 Machines에는 사용할 수 없습니다.

bluegreen: 실행 중인 각 Machine에 대해 같은 지역에 새 Machine을 나란히 부팅합니다. 모든 새 Machines가 헬스 체크를 통과하면 트래픽이 새 Machines로 마이그레이션되고 이전 Machines는 파괴됩니다. 앱이 2개 이상의 Machine으로 스케일링되어 있다면 이 전략은 작업을 병렬로 실행해 배포 시간을 줄일 수 있습니다. bluegreen 전략을 사용하려면 최소 하나의 헬스 체크를 구성해야 합니다. bluegreen 전략은 볼륨이 연결된 Machines에는 사용할 수 없습니다.

**참고:** `max-per-region`이 1로 설정되면 기본 전략은 `rolling`로 설정됩니다. 이는 `canary`가 올바르게 동작하려면 일시적으로 둘 이상의 Machine을 실행해야 하기 때문입니다. `bluegreen` 전략도 `max-per-region`이 1이면 비슷하게 동작합니다.

Rolling 배포 구성

[deploy]
  strategy = "rolling"
  max_unavailable = 1

rolling 배포의 경우 max_unavailable을 사용해 한 번에 내릴 수 있는 Machine 수를 제어할 수 있습니다.

1 이상의 정수 값은 한 번에 정확히 몇 대의 Machine을 내릴 수 있는지 지정합니다. 예를 들어 값이 "1"이면 한 번에 하나씩 업데이트됩니다.

0과 1 사이의 분수 값은 한 번에 내릴 수 있는 Machine의 백분율을 제공합니다. 예를 들어 기본값 0.33은 배포 중 최대 1/3의 Machine이 내려질 수 있음을 의미합니다.

새 버전 배포 중 타임아웃 오류 처리하기

fly deploy가 실행될 때마다 새 Docker 이미지를 빌드하고 내부 레지스트리로 push한 다음 앱의 Machines를 업데이트하거나 생성합니다. 때때로 이미지가 너무 크거나 플랫폼이 새 이미지 레이어를 평소보다 느리게 pull하여, Machine이 시작 상태가 되기를 기다리는 기본 5분 타임아웃이 트리거됩니다.

좋은 점은 이 타임아웃을 --wait-timeout 옵션으로 제어할 수 있다는 것입니다. 예를 들어 fly deploy --wait-timeout=10m, 또는 더 영구적인 fly.toml 설정:

[deploy]
wait_timeout = "10m"

env 변수 섹션

[env]
  LOG_LEVEL = "debug"
  RAILS_ENV = "production"
  S3_BUCKET = "my-app-production"

이 선택적 섹션은 민감하지 않은 정보를 애플리케이션의 런타임 환경의 환경 변수로 설정할 수 있게 해 줍니다.

자격 증명이나 비밀번호 같은 민감한 정보는 secrets CLI 명령을 사용하세요.

Env 변수 이름은 대소문자를 엄격히 구분하며 FLY_로 시작할 수 없습니다(런타임 환경과 충돌할 수 있기 때문). Env 값은 문자열만 될 수 있습니다.

시크릿이 같은 이름의 env 변수보다 우선합니다.

참고: Apps V2에서 primary_region 옵션은 Machine 안에 PRIMARY_REGION 환경 변수를 설정하며 [env] 섹션에 설정된 값을 재정의합니다.

http_service 섹션

HTTP와 HTTPS 서비스만 필요한 앱의 경우 [[services]] 섹션을 더 간단한 이 대안으로 교체할 수 있습니다.

[http_service] 섹션은 80번과 443번 포트에서 수신 대기하는 서비스를 정의합니다. 80번 포트에는 HTTP 핸들러가 있습니다. 443번 포트에는 TLS와 HTTP 핸들러가 있습니다. [[services]] 섹션을 추가해 다른 포트에서 추가 서비스를 구성할 수 있습니다.

더 자세한 [[services]]와 마찬가지로 프로세스 목록을 지정해 HTTP 요청을 받아야 하는 프로세스 그룹에 속한 Machines로 서비스 정의를 제한할 수 있습니다.

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = "stop"
  auto_start_machines = true
  min_machines_running = 0
  [http_service.concurrency]
    type = "requests"
    soft_limit = 200
    hard_limit = 250
  • processes: 여러 프로세스가 있는 앱의 경우. 이 서비스가 속한 프로세스 그룹. processes 섹션에서 프로세스 그룹을 정의하세요.
  • internal_port: 이 서비스(및 애플리케이션)가 클라이언트와 통신하는 데 사용할 포트. 기본값은 8080입니다. 애플리케이션이 기본값을 사용할 것을 권장합니다.
  • force_https: HTTP에서 HTTPS로의 리다이렉트를 강제할지 여부를 결정하는 Boolean.
  • auto_stop_machines: 앱이 수 분간 유휴 상태일 때 Fly Proxy가 취해야 할 동작(있다면). 옵션은 "off", "stop", "suspend"입니다. "off"이면 Fly Proxy는 머신을 절대 중지하지 않습니다. "stop"이면 앱에 과잉 용량이 있을 때 Fly Proxy가 머신을 중지합니다. "suspend"이면 앱에 과잉 용량이 있을 때 Fly Proxy가 (가능하다면) 머신을 일시 중지합니다. suspended 상태에서 머신을 시작하는 것은 stopped 상태에서 시작하는 것보다 빠르지만 몇 가지 주의사항이 있습니다. 지역에 머신이 하나뿐이면 트래픽이 없을 때 머신이 중지되거나 일시 중지됩니다. Fly Proxy는 몇 분마다 머신을 자동으로 중지하는 프로세스를 실행합니다. 설정되지 않으면 기본값은 "off"입니다.
  • auto_start_machines: 애플리케이션에 새 요청이 있을 때 과잉 용량이 없는 경우, 지역별로 애플리케이션의 Machines를 자동으로 시작할지 여부. 지역에 머신이 하나뿐이면 애플리케이션에 요청이 있을 때마다 시작됩니다. 설정되지 않으면 기본값은 true입니다.
  • min_machines_running: auto_stop_machines가 "stop" 또는 "suspend"일 때, 기본 지역에서만 계속 실행할 Machine 수. 설정되지 않으면 기본값은 0입니다.
절대 시작되지 않거나 절대 중지되지 않는 Machines가 생기는 것을 피하기 위해 `auto_stop_machines`와 `auto_start_machines`를 둘 다 활성화하거나 둘 다 비활성화하도록 구성할 것을 권장합니다. Fly Proxy가 `soft_limit` 설정으로 지역의 과잉 용량을 결정하는 방법을 포함해 [Fly Proxy autostop/autostart가 동작하는 방식](/reference/fly-proxy-autostop-autostart)에 대해 자세히 알아보세요.

http_service.concurrency

http_service 동시성 섹션은 애플리케이션의 로드를 측정하는 방법을 구성해 Fly Proxy 로드 밸런싱과 autostop/autostart에 정보를 제공합니다. [http_service.concurrency] 섹션은 [services.concurrency]와 동일한 설정을 가지며, 그 설정은 다음과 같습니다:

  • type은 자동 시작/중지 시점, 또는 주어진 Machine이 더 많거나 적은 트래픽을 받아야 할 때(로드 밸런싱)를 결정하는 데 사용되는 지표를 지정합니다. 지원되는 두 값은 connections와 requests입니다.

connections: 동시 TCP 연결 수에 기반해 로드 밸런싱하고 스케일링합니다. 지정하지 않으면 이 값이 기본입니다. fly launch로 fly.toml을 만들 때도 이 값이 기본입니다. 각 HTTP 요청에 대해 새 연결이 맺어집니다. HTTP 앱에는 requests 타입을 고려하세요.

requests: HTTP 요청 수에 기반해 로드 밸런싱하고 스케일링합니다. 웹 서비스에 권장됩니다. Fly Proxy가 요청을 위해 연결을 풀링하고 재사용할 수 있기 때문입니다.

  • hard_limit: Fly Machine이 이 동시 연결 또는 요청 수에 도달하거나 초과하면 시스템이 그 Machine으로 새 트래픽 보내기를 중지합니다. 설정되지 않으면 hard_limit은 적용되지 않습니다.
  • soft_limit: Fly Machine이 이 동시 연결 또는 요청 수에 도달하거나 초과하면 시스템이 그 Machine으로 새 트래픽 보내기의 우선순위를 낮추고, 다른 모든 Machines도 soft_limit 이상일 때만 그 Machine으로 보냅니다. 이 설정은 autostop/autostart 기능의 과잉 용량 결정에도 사용됩니다. 설정되지 않으면 기본값은 20입니다.

동시성 설정에 대한 자세한 내용은 Guidelines for concurrency settings를 참조하세요.

http_service.http_options.idle_timeout

앱에 대한 연결의 유휴 타임아웃을 구성합니다.

 [http_service.http_options]
   idle_timeout = 600

http_service.http_options.response.pristine

Fly Proxy가 HTTP 응답에 Fly 헤더를 추가하지 않도록 구성합니다. 다음 응답 헤더는 추가되지 않으며, 앱이 반환하더라도 수정되지 않습니다:

  • Server
  • Via
  • Fly-Request-Id
  • Fly-Cache-Status

이미 유사한 응답 헤더를 추가하는 자체 로드 밸런서가 있고 Fly 위에 플랫폼을 구축하고 있다면 유용합니다.

  [http_service.http_options.response]
    pristine = true

http_service.http_options.response.headers

HTTP 응답 헤더를 추가하거나 제거합니다.

다음 예시에서 Example-Header는 Fly Proxy가 보내는 최종 응답에서 제거되고, Example-Header-1과 Example-Multi-Value 및 그 값들은 응답 헤더에 추가됩니다.

  [http_service.http_options.response.headers]
    Example-Header = false
    Example-Header-1 = "value"
    Example-Multi-Value = ["value1", "value2"]

http_service.http_options.h2_backend

앱이 사전 지식으로 HTTP/2 cleartext(H2C)를 지원하는지 여부를 나타냅니다.

다음 예시에서 h2_backend는 true로 설정되어, 앱이 gRPC 같은 HTTP/2 전용 서비스를 http 핸들러를 통해 노출할 수 있게 합니다.

  [http_service.http_options]
    h2_backend = true

http_service.http_options.replay_cache

세션 기반 리플레이 캐싱을 구성합니다. 앱이 fly-replay 응답을 보내면 Fly Proxy는 쿠키나 헤더 값을 기반으로 그 리플레이 결정을 캐시해, 동일한 식별자의 후속 요청에 자동으로 적용할 수 있습니다.

각 http_options.replay_cache 항목이 캐싱 규칙을 구성합니다:

[[http_service.http_options.replay_cache]]
  path_prefix = "/"
  ttl_seconds = 300
  type = "cookie"
  name = "session_id"
  allow_bypass = false

리플레이에 대한 문서와 캐싱에 대한 추가 설명은 Session-based Replay Caching을 참조하세요.

http_service.http_options.replay_cache.path_prefix

이 캐싱 규칙이 적용되는 경로 패턴.

/api 같은 경로(모든 호스트 이름에 적용)이거나 example.com/api 같은 호스트 이름을 포함할 수 있습니다. 여러 규칙이 요청과 일치하면 가장 긴 일치 경로가 우선합니다.

호스트 이름을 포함한다면 프로토콜이나 포트는 포함하지 마세요. 호스트 이름이 제공되지 않으면 캐시 규칙은 모든 호스트 이름에 적용되지만, 각 호스트 이름은 별도의 캐시를 유지합니다.

암시적으로 /*로 끝나므로 example.com/api, example.com/api/, example.com/api/*는 모두 동일합니다.

http_service.http_options.replay_cache.ttl_seconds

리플레이 결정을 캐시할 시간(초). 최소값은 10초입니다.

http_service.http_options.replay_cache.type

"cookie" 또는 "header" 중 하나. 쿠키 또는 요청 헤더 중 무엇을 캐시 키로 사용할지 지정합니다.

http_service.http_options.replay_cache.name

캐시 키로 사용할 쿠키 또는 헤더의 이름.

http_service.http_options.replay_cache.allow_bypass

선택적 Boolean. true이면 클라이언트가 fly-replay-cache-control: skip 요청 헤더를 설정해 캐시를 우회할 수 있습니다. 기본값은 false입니다.

http_service.tls_options

Fly의 엣지가 애플리케이션의 TLS를 종료하는 데 사용할 TLS 버전과 ALPN 프로토콜을 구성합니다:

[http_service.tls_options]
  alpn = ["h2", "http/1.1"]
  versions = ["TLSv1.2", "TLSv1.3"]
  default_self_signed = false
  • alpn: 클라이언트와의 ALPN 협상을 어떻게 처리할지 나타내는 문자열 배열.
  • versions: 허용되는 TLS 버전을 나타내는 문자열 배열.
  • default_self_signed: true이면 인증서가 없을 때 자체 서명 인증서를 제공합니다. 기본값은 false.

Fly.io는 TLS만 종료하고 서비스에 직접 패스스루할 수도 있습니다. 자세한 내용은 services.ports.tls\_options를 참조하세요.

http_service.checks

HTTP 서비스에 대한 헬스 체크를 구성하려면 http_service.checks 섹션을 사용할 수 있습니다. 이 체크는 응답에서 성공적인 HTTP 상태(예: 2xx)를 기대합니다. http_service.checks 섹션 예시:

[[http_service.checks]]
  grace_period = "10s"
  interval = "30s"
  method = "GET"
  timeout = "5s"
  path = "/"

대략 해석하면, 이 섹션은 30초마다 서비스의 루트 경로에 HTTP GET을 수행해 5초 안에 HTTP 200 상태가 반환되기를 기대합니다. 체크는 공개 appname.fly.dev 호스트 이름이 아니라 앱의 사설 네트워크를 통해 Machine의 서비스에 대해 실행되므로, 공개적으로 노출되지 않는 서비스에서도 동작합니다. check의 파라미터는 아래에 나열됩니다.

단위가 지정되지 않으면 시간은 밀리초 단위입니다.

  • grace_period: Machine이 시작된 후 헬스 상태를 확인하기 전에 기다리는 시간. 앱이 시작할 수 있을 만큼 충분히 길게 하세요. 예를 들어 앱 시작에 2초 걸리면 grace_period를 최소 3초로 설정해 여유를 주세요.
  • interval: 연결성 체크 사이의 시간. interval과 grace period 사이에는 균형이 있어야 합니다. interval이 길고 grace\_period가 앱의 시작 시간보다 짧으면 헬스 체크가 너무 오래 걸려 배포 시간이 늘어납니다.
  • timeout: 연결이 헬스 체크 실패로 보고되기 전에 걸릴 수 있는 최대 시간.
  • method: 체크에 사용할 HTTP 메서드. 생략하면 기본값은 get입니다.
  • path: 요청할 URL의 경로.
  • protocol: 사용할 프로토콜(http 또는 https). 생략하면 기본값은 http입니다.
  • tls_server_name: 프로토콜이 https이면 TLS 인증서 검증에 사용할 호스트 이름.
  • tls_skip_verify: true(및 HTTPS 프로토콜 사용)일 때 서버가 보내는 인증서 검증을 건너뜁니다.
  • http_service.checks.headers: http_service.checks의 하위 섹션입니다. 체크 호출에 전달될 헤더와 헤더 값의 사양으로 key/value 쌍을 사용합니다.
헬스 체크는 `HTTP 301` 또는 `302` 리다이렉트를 자동으로 따라가지 않으므로 `200 OK`가 아닌 응답을 받으면 실패합니다. 헬스 체크가 `protocol = http`(기본값)을 지정하는데 앱이 `https`를 강제하면 이 문제가 발생할 수 있습니다. `[http_service.checks.headers]` 하위 섹션에 `X-Forwarded-Proto = "https"`를 추가하면 이 리다이렉트를 피하고 헬스 체크에 `http`를 계속 사용할 수 있습니다.

http_service.machine_checks 섹션

HTTP 서비스에 대해 services와 동일한 machine_checks 섹션을 사용할 수 있습니다. machine_checks 섹션은 서비스의 헬스 상태를 확인하는 파라미터를 정의합니다.

[[http_service.machine_checks]]
  image = "curlimages/curl"
  entrypoint = ["/bin/sh", "-c"]
  command = ["curl http://[$FLY_TEST_MACHINE_IP] | grep 'Hello, World!'"]
  kill_signal = "SIGKILL"
  kill_timeout = "5s"

services 섹션

services 섹션은 앱의 공개 Anycast 또는 사설 Flycast 주소에 도달하는 요청을 Machines 안에서 실행되는 서비스에 어떻게 연결하는지, 그리고 서비스에 대한 다른 Fly Proxy 동작을 구성합니다. 서비스가 표준 포트의 HTTP와 HTTPS만 필요하다면 더 간결한 http_service를 사용할 수 있습니다.

services 섹션 자체는 TOML의 테이블 집합이므로 이중 대괄호로 구분됩니다. [[services]] 안의 테이블은 서비스의 추가 기능과 동작을 구성하며, 이후 섹션에서 설명합니다.

들어오는 요청의 포트와 핸들러를 설정하려면 각 `services` 섹션에 최소 하나의 [`services.ports`](#services-ports) 항목이 필요합니다.

앱은 다음을 가질 수 있습니다:

  • services 섹션 없음(http_service 섹션도 없음): 애플리케이션은 공개 인터넷이나 Flycast 주소로 접근할 수 없습니다. 이는 같은 네트워크의 다른 앱과 6PN 사설 네트워킹으로만 통신하는 앱의 전형입니다.
  • services 섹션 하나(http_service 섹션도 포함): 하나의 내부 포트를 하나 이상의 외부 포트에 매핑.
  • 여러 services 섹션(http_service 섹션과 하나 이상의 services 섹션 포함): 여러 내부 포트를 여러 외부 포트에 매핑.

예시(이중 대괄호에 주목):

[[services]]
  internal_port = 8080
  protocol = "tcp"
  auto_stop_machines = "stop"
  auto_start_machines = true
  min_machines_running = 0

설정:

  • processes: 여러 프로세스 그룹이 있는 앱의 경우. 이 서비스가 속한 프로세스 그룹. processes 섹션에서 프로세스 그룹을 정의하세요.
  • internal_port: 이 서비스(및 애플리케이션)가 클라이언트와 통신하는 데 사용할 포트. 기본값은 8080입니다. 애플리케이션이 기본값을 사용할 것을 권장합니다.
  • protocol: 이 서비스가 통신에 사용할 프로토콜. 대부분의 애플리케이션에서 보통 tcp이지만 udp도 될 수 있습니다.
  • auto_stop_machines: 앱이 수 분간 유휴 상태일 때 Fly Proxy가 취해야 할 동작(있다면). 옵션은 "off", "stop", "suspend"입니다. "off"이면 Fly Proxy는 머신을 절대 중지하지 않습니다. "stop"이면 앱에 과잉 용량이 있을 때 Fly Proxy가 머신을 중지합니다. "suspend"이면 앱에 과잉 용량이 있을 때 Fly Proxy가 (가능하다면) 머신을 일시 중지합니다. suspended 상태에서 머신을 시작하는 것은 stopped 상태에서 시작하는 것보다 빠르지만 몇 가지 주의사항이 있습니다. 지역에 머신이 하나뿐이면 트래픽이 없을 때 머신이 중지되거나 일시 중지됩니다. Fly Proxy는 몇 분마다 머신을 자동으로 중지하는 프로세스를 실행합니다. 설정되지 않으면 기본값은 "off"입니다.
  • auto_start_machines: 애플리케이션에 새 요청이 있을 때 과잉 용량이 없는 경우, 지역별로 애플리케이션의 Machines를 자동으로 시작할지 여부. 지역에 머신이 하나뿐이면 애플리케이션에 요청이 있을 때마다 시작됩니다. 설정되지 않으면 기본값은 true입니다.
  • min_machines_running: auto_stop_machines가 "stop" 또는 "suspend"일 때, 기본 지역에서만 계속 실행할 Machine 수. 설정되지 않으면 기본값은 0입니다.
절대 시작되지 않거나 절대 중지되지 않는 Machines가 생기는 것을 피하기 위해 `auto_stop_machines`와 `auto_start_machines`를 둘 다 활성화하거나 둘 다 비활성화하도록 구성할 것을 권장합니다. Fly Proxy가 `soft_limit` 설정으로 지역의 과잉 용량을 결정하는 방법을 포함해 [Fly Proxy autostop/autostart가 동작하는 방식](/reference/fly-proxy-autostop-autostart)에 대해 자세히 알아보세요.

services.ports

fly.toml의 각 services 섹션에 대해, 즉 연결을 수락하려는 각 외부 포트에 대해 services.ports 섹션이 필요합니다. 이 섹션은 다음과 같이 이중 대괄호로 표시됩니다:

  [[services.ports]]
    handlers = ["http"]
    port = 80
    force_https = true  # optional

이 예시는 80번 포트에 HTTP 핸들러를 정의합니다.

  • handlers: 각 문자열이 엣지에서 연결을 종료할 핸들러 프로세스를 선택하는 문자열 배열. 여기서 http 핸들러는 HTTP 트래픽을 수락해 위 services 섹션에서 정의한 애플리케이션의 internal_port로 전달합니다. 사용 가능한 핸들러 목록과 네트워크 트래픽 관리 방식은 Public Network Services 문서를 참조하세요.
  • port: 수신 대기할 외부 포트를 나타내는 정수 (포트 1-65535).
  • start_port: 포트 범위의 경우, 수신 대기할 첫 번째 포트.
  • end_port: 포트 범위의 경우, 수신 대기할 마지막 포트.
  • force_https: HTTP에서 HTTPS로의 리다이렉트를 강제할지 여부를 결정하는 Boolean.

services.ports 섹션은 둘 이상 가질 수 있습니다. 예를 들어 기본 구성은 두 개를 포함합니다. 위에서 하나를 이미 봤습니다. 두 번째는 tls 핸들러를 사용해 보안 연결을 위한 외부 포트 443을 정의합니다.

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

UDP 애플리케이션의 경우 애플리케이션을 관련 services.ports 섹션에 정의된 것과 같은 포트에 바인딩하세요. 예를 들어 아래 구성은 5000번 포트에서 수신 대기하며, 애플리케이션은 트래픽을 받기 위해 fly-global-services:5000에 바인딩해야 합니다. UDP 서비스에는 handlers를 설정하지 않은 채로 두세요.

[[services]]
  internal_port = 5000
  protocol = "udp"
  [[services.ports]]
    port = 5000

여러 포트 정의를 사용하는 대신 포트 범위를 지정할 수 있습니다. 예를 들어 아래 구성은 8080, 8081, 8082, 8083, 8084, 8085 포트에서 수신 대기합니다:

[[services.ports]]
  handlers = ["tls"]
  start_port = 8080
  end_port = 8085

services.ports.http_options.idle_timeout

앱에 대한 연결의 유휴 타임아웃을 구성합니다.

 [services.ports.http_options]
   idle_timeout = 600

services.ports.http_options.response.pristine

Fly Proxy가 HTTP 응답에 Fly 헤더를 추가하지 않도록 구성합니다. 다음 응답 헤더는 추가되지 않으며, 앱이 반환하더라도 수정되지 않습니다:

  • Server
  • Via
  • Fly-Request-Id
  • Fly-Cache-Status

이미 유사한 응답 헤더를 추가하는 자체 로드 밸런서가 있고 Fly 위에 플랫폼을 구축하고 있다면 유용합니다.

  [services.ports.http_options.response]
    pristine = true

services.ports.http_options.response.headers

HTTP 응답 헤더를 추가하거나 제거합니다.

다음 예시에서 Example-Header는 Fly Proxy가 보내는 최종 응답에서 제거되고, Example-Header-1과 Example-Multi-Value 및 그 값들은 응답 헤더에 추가됩니다.

  [services.ports.http_options.response.headers]
    Example-Header = false
    Example-Header-1 = "value"
    Example-Multi-Value = ["value1", "value2"]

services.ports.http_options.h2_backend

앱이 사전 지식으로 HTTP/2 cleartext(H2C)를 지원하는지 여부를 나타냅니다.

다음 예시에서 h2_backend는 true로 설정되어, 앱이 gRPC 같은 HTTP/2 전용 서비스를 http 핸들러를 통해 노출할 수 있게 합니다.

  [services.ports.http_options]
    h2_backend = true

services.ports.http_options.replay_cache

세션 기반 리플레이 캐싱을 구성합니다. 앱이 fly-replay 응답을 보내면 Fly Proxy는 쿠키나 헤더 값을 기반으로 그 리플레이 결정을 캐시해, 동일한 식별자의 후속 요청에 자동으로 적용할 수 있습니다.

각 http_options.replay_cache 항목이 캐싱 규칙을 구성합니다:

  [[services.ports.http_options.replay_cache]]
    path_prefix = "/"
    ttl_seconds = 300
    type = "cookie"
    name = "session_id"
    allow_bypass = false

리플레이에 대한 문서와 캐싱에 대한 추가 설명은 Session-based Replay Caching을 참조하세요.

services.ports.http_options.replay_cache.path_prefix

이 캐싱 규칙이 적용되는 경로 패턴.

/api 같은 경로(모든 호스트 이름에 적용)이거나 example.com/api 같은 호스트 이름을 포함할 수 있습니다. 여러 규칙이 요청과 일치하면 가장 긴 일치 경로가 우선합니다.

호스트 이름을 포함한다면 프로토콜이나 포트는 포함하지 마세요. 호스트 이름이 제공되지 않으면 캐시 규칙은 모든 호스트 이름에 적용되지만, 각 호스트 이름은 별도의 캐시를 유지합니다.

암시적으로 /*로 끝나므로 example.com/api, example.com/api/, example.com/api/*는 모두 동일합니다.

services.ports.http_options.replay_cache.ttl_seconds

리플레이 결정을 캐시할 시간(초). 최소값은 10초입니다.

services.ports.http_options.replay_cache.type

"cookie" 또는 "header" 중 하나. 쿠키 또는 요청 헤더 중 무엇을 캐시 키로 사용할지 지정합니다.

services.ports.http_options.replay_cache.name

캐시 키로 사용할 쿠키 또는 헤더의 이름.

services.ports.http_options.replay_cache.allow_bypass

선택적 Boolean. true이면 클라이언트가 fly-replay-cache-control: skip 요청 헤더를 설정해 캐시를 우회할 수 있습니다. 기본값은 false입니다.

services.ports.proxy_proto_options

앱이 수락하는 PROXY 프로토콜의 버전을 구성합니다. 버전 1이 기본값입니다.

예를 들어:

[[services.ports]]
  handlers = ["proxy_proto"]
  port = 5000
  proxy_proto_options = { version = "v2" }
  • version: TCP 연결이 PROXY 프로토콜 버전 2를 사용함을 나타내는 문자열. 설정하지 않으면 기본값은 버전 1입니다.

services.ports.tls_options

Fly의 엣지가 애플리케이션의 TLS를 종료하는 데 사용할 TLS 버전과 ALPN 프로토콜을 구성합니다:

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443
    tls_options = { "alpn" = ["h2", "http/1.1"], "versions" = ["TLSv1.2", "TLSv1.3"] }
  • alpn: 클라이언트와의 ALPN 협상을 어떻게 처리할지 나타내는 문자열 배열.
  • versions: 허용되는 TLS 버전을 나타내는 문자열 배열.
  • default_self_signed: true이면 인증서가 없을 때 자체 서명 인증서를 제공합니다. 기본값은 false.

Fly.io는 TLS만 종료하고 직접 서비스에 패스스루할 수도 있습니다. 이는 TLS 종료를 오프로드하고 암호화되지 않은 연결을 수락하는 데 이점이 있는 다양한 애플리케이션에서 동작합니다.

한 가지 사용 사례는 MQTT를 통한 메시지 전송입니다. Fly의 엣지는 TLS를 종료하고 백홀을 통해 암호화되지 않은 MQTT를 애플리케이션에 직접 보냅니다. 아래 구성은 클라이언트와 TLS를 통한 MQTT를 협상한 다음 암호화되지 않은 MQTT를 애플리케이션에 보냅니다:

  [[services.ports]]
    handlers = ["tls"]
    port = 443
    tls_options = { "alpn" = ["mqtt"] }

services.concurrency

services 동시성 하위 섹션은 애플리케이션의 로드를 측정하는 방법을 구성해 Fly Proxy 로드 밸런싱과 autostop/autostart에 정보를 제공합니다.

이 섹션은 단순한 key/value 목록이므로 단일 대괄호로 표시됩니다:

  [services.concurrency]
    type = "connections"
    hard_limit = 25
    soft_limit = 20

type은 주어진 Machine이 동시성 한도에 도달했는지 결정하는 데 사용되는 지표를 지정합니다. 지원되는 두 값은 connections와 requests입니다.

connections: 동시 TCP 연결 수에 기반해 로드 밸런싱하고 스케일링합니다. 지정하지 않으면 이 값이 기본입니다. fly launch로 fly.toml을 만들 때도 이 값이 기본입니다. 각 HTTP 요청에 대해 새 연결이 맺어집니다. HTTP 앱에는 requests 타입을 고려하세요.

requests: HTTP 요청 수에 기반해 로드 밸런싱하고 스케일링합니다. 웹 서비스에 권장됩니다. Fly Proxy가 요청을 위해 연결을 풀링하고 재사용할 수 있기 때문입니다.

  • hard_limit: Fly Machine이 이 동시 연결 또는 요청 수에 도달하거나 초과하면 시스템이 그 Machine으로 새 트래픽 보내기를 중지합니다. 설정되지 않으면 hard_limit은 적용되지 않습니다.
  • soft_limit: Fly Machine이 이 동시 연결 또는 요청 수에 도달하거나 초과하면 시스템이 그 Machine으로 새 트래픽 보내기의 우선순위를 낮추고, 다른 모든 Machines도 soft_limit 이상일 때만 그 Machine으로 보냅니다. 이 설정은 autostop/autostart 기능의 과잉 용량 결정에도 사용됩니다. 설정되지 않으면 기본값은 20입니다.

동시성 설정에 대한 자세한 내용은 Guidelines for concurrency settings를 참조하세요.

services.tcp_checks

서비스가 실행 중일 때 Fly Proxy는 포트에 연결해 서비스를 확인할 수 있습니다. services.tcp_checks 섹션은 이러한 체크의 파라미터를 정의합니다. 예를 들어 기본 tcp_checks는 다음과 같습니다:

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    timeout = "2s"

단위가 지정되지 않으면 시간은 밀리초 단위입니다.

  • grace_period: Machine이 시작된 후 헬스 상태를 확인하기 전에 기다리는 시간. 애플리케이션이 시작할 수 있을 만큼 충분히 길게 하세요. 예를 들어 앱 시작에 2초 걸리면 최소 3초로 설정해 여유를 주세요.
  • interval: 연결성 체크 사이의 시간. interval이 길고 grace_period가 앱의 시작 시간보다 짧으면 헬스 체크가 더 오래 걸려 배포 시간이 늘어납니다.
  • timeout: 연결이 헬스 체크 실패로 보고되기 전에 걸릴 수 있는 최대 시간.

services.http_checks

서비스가 실행 중인지 확인하는 또 다른 방법은 services.http_checks 섹션에서 정의된 HTTP 체크입니다. 이 체크는 연결뿐 아니라 응답의 성공적인 HTTP 상태(예: 2xx)를 요구하므로 services.tcp_checks보다 철저합니다. services.http_checks 섹션 예시:

  [[services.http_checks]]
    interval = 10000
    grace_period = "5s"
    method = "get"
    path = "/"
    protocol = "http"
    timeout = 2000
    tls_skip_verify = false
    [services.http_checks.headers]

대략 해석하면, 이 섹션은 10초마다 서비스의 루트 경로에 HTTP GET을 수행해 2초 안에 HTTP 200 상태가 반환되기를 기대합니다. 체크는 공개 appname.fly.dev 호스트 이름이 아니라 앱의 사설 네트워크를 통해 Machine의 서비스에 대해 실행되므로, 공개되지 않는 서비스에서도 동작합니다. http_check의 파라미터는 아래에 나열됩니다.

단위가 지정되지 않으면 시간은 밀리초 단위입니다.

  • grace_period: Machine이 시작된 후 헬스 상태를 확인하기 전에 기다리는 시간. 앱이 시작할 수 있을 만큼 충분히 길게 하세요. 예를 들어 앱 시작에 2초 걸리면 grace_period를 최소 3초로 설정해 여유를 주세요.
  • interval: 연결성 체크 사이의 시간. interval과 grace period 사이에는 균형이 있어야 합니다. interval이 길고 grace\_period가 앱의 시작 시간보다 짧으면 헬스 체크가 너무 오래 걸려 배포 시간이 늘어납니다.
  • timeout: 연결이 헬스 체크 실패로 보고되기 전에 걸릴 수 있는 최대 시간.
  • method: 체크에 사용할 HTTP 메서드.
  • path: 요청할 URL의 경로.
  • protocol: 사용할 프로토콜(http 또는 https).
  • tls_server_name: 프로토콜이 https이면 TLS 인증서 검증에 사용할 호스트 이름.
  • tls_skip_verify: true(및 HTTPS 프로토콜 사용)일 때 서버가 보내는 인증서 검증을 건너뜁니다.
  • services.http_checks.headers: services.http_checks의 하위 섹션입니다. http\_check 호출에 전달될 헤더와 헤더 값의 사양으로 key/value 쌍을 사용합니다.

참고: services.http_checks 섹션은 선택 사항이며 기본 fly.toml 파일에는 생성되지 않습니다.

services.machine_checks

Machine 체크는 다른 체크와 약간 다르게 동작합니다. 각 배포 시 실행되며, 실패하면 배포가 중지됩니다. 테스트 중인 Machine의 6PN IPv6 주소로 FLY_TEST_MACHINE_IP 환경 변수가 설정된 새 Machine이 생성됩니다. 이는 배포 전에 Machines에서 통합 테스트를 실행하는 데 유용합니다. 예시:

  [[services.machine_checks]]
    image = "curlimages/curl"
    entrypoint = ["/bin/sh", "-c"]
    command = ["curl http://[$FLY_TEST_MACHINE_IP] | grep 'Hello, World!'"]
    kill_signal = "SIGKILL"
    kill_timeout = "5s"

이 예시는 curl 이미지를 사용해 테스트를 실행합니다. Machine이 "Hello, World!"라는 텍스트를 가진 페이지를 제공하는지 확인합니다.

  • image: 테스트에 사용할 Docker 이미지. 기본값은 Machine이 속한 프로세스 그룹에 사용되는 이미지입니다.
  • entrypoint: 테스트의 엔트리포인트. 설정하지 않으면 테스트 중인 Machine의 엔트리포인트가 기본값입니다.
  • command: 테스트에 실행할 명령.
  • kill_signal: 테스트 프로세스가 너무 오래 실행되면 보낼 신호. 사용자 지정 이미지가 설정된 경우 이미지의 신호가 기본값입니다.
  • kill_timeout: kill 신호를 보내기 전에 기다리는 시간. 사용자 지정 이미지가 설정된 경우 이미지의 타임아웃이 기본값입니다.

Machine 체크는 특히 canary 배포에 유용합니다. flyctl은 새 Machine을 생성해 모든 Machine 기능이 작동하는지 확인한 다음 앱의 나머지 Machines를 배포합니다.

Machine 체크는 rolling 및 canary 배포 전략을 사용하는 앱에서 지원됩니다.

mounts 섹션

이 섹션은 영구 스토리지용 Volumes 기능을 지원합니다. 필수 항목이 두 개 있습니다: source와 destination.

[mounts]
  source = "myapp_data"
  destination = "/data"
  processes = ["disk"] # optional - attach volumes to Machines that belong to one or more process groups
  initial_size = "20gb" # optional - the size of the volume created on first deploy

source

source는 이 앱이 마운트해야 하는 볼륨 이름입니다. 이 이름과 앱이 같은 지역에 있고 아직 마운트되지 않은 볼륨은 모두 마운트될 수 있습니다. 이 이름의 볼륨이 어떤 지역에는 존재해야 앱이 배포됩니다.

destination

destination은 실행 중인 앱에서 source 볼륨이 마운트될 디렉토리입니다. 루트 파일 시스템이 마운트되는 /는 될 수 없습니다.

processes

선택적으로 프로세스 목록을 지정해 볼륨 마운트를 프로세스 그룹별로 제한할 수 있습니다. 심지어 서로 다른 프로세스 그룹의 Machines에 서로 다른 소스 볼륨을 마운트하도록 두 개의 다른 [[mounts]] 섹션을 지정할 수도 있습니다. 여러 [[mounts]]가 정의된 경우 이중 대괄호를 사용해야 한다는 점에 유의하세요.

initial_size

선택적으로 앱을 처음 실행할 때 생성할 볼륨의 크기를 지정할 수 있습니다.

이 값은 새 볼륨을 만들어야 할 때 fly launch 및 fly deploy 명령에서만 사용되며, fly volume create 명령에서는 무시됩니다.

값은 initial_size = "30GB"처럼 단위가 있는 문자열일 수 있습니다. 값은 initial_size = 30처럼 정수일 수도 있으며, 기본 단위는 GB입니다.

snapshot_retention

선택적으로 이 앱의 볼륨 스냅샷이 보관되는 일 수를 지정할 수 있습니다.

설정되지 않으면 기본값은 5일입니다. 최소 1일, 최대 60일입니다.

예를 들어 다음 구성은 볼륨 스냅샷을 14일간 보관합니다:

[mounts]
  source = "myapp_data"
  destination = "/data"
  snapshot_retention = 14

scheduled_snapshots

선택 사항. 볼륨의 자동 일일 스냅샷을 활성화하거나 비활성화합니다.

설정되지 않으면 기본값은 true(활성화)입니다.

예를 들어 다음 구성은 자동 일일 스냅샷을 비활성화합니다:

[mounts]
  source = "myapp_cache"
  destination = "/cache"
  scheduled_snapshots = false

auto_extend_size_threshold

선택 사항. 볼륨에 사용된 스토리지의 백분율 임계값으로, 결과 크기가 auto_extend_size_limit을 초과하지 않는 한 이 값을 auto_extend_size_increment만큼 볼륨 크기를 늘리는 것을 트리거합니다.

auto_extend_size_increment

auto_extend_size_threshold에 도달한 후 볼륨을 늘릴 크기(GiB).

auto_extend_size_limit

확장이 완료된 후 볼륨의 최대 크기(GB).

볼륨의 자동 확장 기능을 사용할 때 `auto_extend_size_increment`와 `auto_extend_size_limit`는 모두 필수입니다. 이 값이 없으면 사용량 임계값에 도달해도 볼륨이 자동으로 크기가 조정되지 않습니다.

볼륨 크기 자동 확장 구성

선택적으로 볼륨이 사용량 임계값에 도달했을 때 자동으로 확장되도록 구성할 수 있습니다.

예를 들어 다음 구성은 볼륨이 80% 용량에 도달하면 1GB씩 크기를 늘립니다. 볼륨 확장은 총 5GB로 제한됩니다.

[[mounts]]
  source = "data"
  destination = "/data"
  auto_extend_size_threshold = 80
  auto_extend_size_increment = "1GB"
  auto_extend_size_limit = "5GB"

vm 섹션

이 섹션은 애플리케이션에 사용되는 Machines의 컴퓨팅 요구사항을 정의합니다.

기본 Machine 크기는 shared-cpu-1x이지만 fly.toml에 지정되지 않으면 강제되지 않습니다. 즉 fly deploy 같은 명령이 Machine의 컴퓨팅 요구사항(또는 크기)을 업데이트하려 시도하지 않습니다. fly scale 명령은 새 Machine 크기를 추론하기 위해 기존 Machines를 사용하며, Machines가 없으면 shared-cpu-1x를 사용합니다.

예측 가능한 zero에서 스케일 업을 신경 쓰거나, 프로세스 그룹마다 다른 컴퓨팅 요구사항이 있다면 이 섹션을 fly.toml에 추가하는 것을 강력히 권장합니다. 컴퓨팅 요구사항이 설정되면 fly deploy와 fly scale count 명령이 이를 강제합니다. fly scale vm(또는 그 형제인 fly scale memory)으로 Machine 크기를 변경하면, fly.toml이 그에 맞게 업데이트되지 않는 한 다음 fly deploy에서 재설정됩니다. Machine 크기 구성 우선순위에 대해 자세히 알아보세요.

`fly scale vm` 또는 `fly scale memory`로 Machine 크기를 업데이트했지만 `fly.toml` 파일에 `[[vm]]` 섹션이 여전히 있으면, 다음 `fly deploy`가 Machines를 파일의 구성으로 재설정합니다. Machines를 수동으로 스케일링하고 그 설정을 유지하려면 `fly.toml` 파일에서 `[[vm]]` 섹션을 제거하세요.

모든 키는 선택 사항이며 size는 다른 모든 키보다 우선순위가 낮습니다.

[[vm]]
  size = "shared-cpu-2x"
  memory = "1gb"
  cpus = 2
  cpu_kind = "shared"
  kernel_args = "no-hlt=true"
  host_dedication_id = "customer-id"
  persist_rootfs = "never"
  processes = ["app"]

size

기본으로 사용할 Machine 프리셋 크기. 예: size = "shared-cpu-1x".

전체 목록은 fly platform vm-sizes를 실행하거나 가격 페이지를 확인하세요.

memory

요청할 메모리. memory = "2GB" 또는 memory = "512mb"처럼 단위로 표현할 수 있습니다. 값은 memory = 1024처럼 정수일 수도 있으며 기본 단위는 MB입니다.

cpus

요청할 vCPU 수. 유효한 값은 1, 2, 4, 8, 16이지만 cpu_kind에 따라 다릅니다.

cpu_kind

요청할 CPU 종류. 유효한 값은 shared와 performance입니다.

kernel_args

VM 부팅 시 커널에 제공되는 추가 커널 파라미터.

host_dedication_id

전용 호스트가 있는 경우, Machines가 전용 하드웨어에서 실행되도록 설정할 값.

persist\_rootfs

재시작과 업데이트에 걸친 루트 파일시스템의 지속성. 유효한 값은 never(기본값), restart, always입니다.

  • never: 루트 파일시스템은 임시적이며 재시작이나 업데이트에 걸쳐 유지되지 않습니다.
  • restart: 루트 파일시스템은 재시작에는 유지되지만 업데이트에는 유지되지 않습니다.
  • always: 루트 파일시스템은 재시작과 업데이트 모두에 유지됩니다.

processes

선택적으로 프로세스 목록을 지정해 프로세스 그룹별로 제한할 수 있습니다. 심지어 프로세스 그룹마다 다른 컴퓨팅 요구사항을 갖도록 두 개의 다른 [[vm]] 섹션을 지정할 수도 있습니다. 여러 [[vm]] 섹션이 정의된 경우 이중 대괄호를 사용해야 한다는 점에 유의하세요.

processes 키가 없는 [[vm]] 섹션은 다른 [[vm]] 섹션이 특정 프로세스 그룹을 대상으로 하지 않는 한 모든 프로세스 그룹에 적용됩니다. 예를 들어 다음 스니펫은 app 및 other 프로세스 그룹에는 shared-cpu-4x를, worker 그룹에는 performance-1x를 사용합니다.

[processes]
app = "/start-app"
worker = "/start-worker"
other = "/start-other"

[[vm]]
size = "shared-cpu-4x"

[[vm]]
size = "performance-1x"
processes = ["worker"]

restart 섹션

[[restart]]
  policy = "never"
  retries = 10
  processes = ["app"]

머신이 예기치 않게 종료되면 스케줄링 메커니즘이 사용자의 개입 없이 머신의 재시작 정책에 따라 재시작합니다. 이 정책은 Docker의 컨테이너 재시작 정책과 상당히 유사합니다:

  • always: 종료 코드와 관계없이 머신 재시작을 시도합니다.
  • never: 머신이 0이 아닌 종료 코드로 종료되더라도 재시작하지 않습니다.
  • on-failure: 머신이 0이 아닌 종료 코드로(실패나 크래시로 인해) 종료된 경우에만 재시작합니다. 명시적으로 설정하지 않으면 이 정책이 기본입니다.

재시작 정책은 특정 프로세스 그룹을 대상으로 할 수 있습니다. 그룹이 지정되지 않으면 앱의 모든 머신이 동일한 기본 재시작 정책을 갖습니다. 포기하기 전에 머신 재시작을 시도할 횟수도 지정할 수 있습니다.

checks 섹션

앱에 공개 서비스를 향한 서비스가 없거나, 요청 라우팅에 영향을 주지 않는 독립적인 헬스 체크를 원한다면 [[services.checks]] 대신 이 최상위 checks 섹션을 사용하세요.

서비스 수준 체크와 달리 최상위 체크에는 다음이 필요합니다:

  • 포트 번호
  • 고유한 이름
  • 체크 유형(http 또는 tcp)
[checks]
  [checks.name_of_your_http_check]
    grace_period = "30s"
    interval = "15s"
    method = "get"
    path = "/path/to/status"
    port = 5500
    timeout = "10s"
    type = "http"
    [checks.name_of_your_http_check.headers]
      Content-Type = "application/json"
      Authorization = "super-secret"

  [checks.name_of_your_tcp_check]
    grace_period = "30s"
    interval = "15s"
    port = 1234
    timeout = "10s"
    type = "tcp"

필드는 [[services.checks]]와 매우 유사합니다:

  • port: 연결할 내부 포트. 0.0.0.0에서 사용 가능해야 합니다. 필수.
  • type: tcp 또는 http 중 하나. 필수.
  • grace_period: Machine이 시작된 후 헬스 상태를 확인하기 전에 기다리는 시간. 앱이 시작할 충분한 시간을 확실히 주세요. 예를 들어 앱 시작에 2초 걸리면 최소 3초로 설정해 여유를 주세요.
  • interval: 체크 실행 사이의 시간. grace_period가 앱의 시작 시간보다 짧고 interval이 너무 길면 체크가 배포 시간을 늘립니다.
  • processes: 여러 프로세스가 있는 앱의 경우. 헬스 체크를 적용할 프로세스 그룹. processes 섹션에서 프로세스 그룹을 정의하세요.

HTTP 체크에만 해당:

  • method: 체크에 사용할 HTTP 메서드.
  • path: 요청할 URL의 경로.
  • timeout: 연결이 헬스 체크 실패로 보고되기 전에 걸릴 수 있는 최대 시간.
  • headers: 체크 요청에 HTTP 헤더로 전달될 key/value 쌍을 지정합니다.

다시 말하지만, 단위가 지정되지 않으면 시간은 밀리초 단위입니다.

processes 섹션

processes 섹션은 단일 앱 안에서 별도의 Machines에서 실행될 프로세스 그룹을 정의할 수 있게 해 줍니다. 앱에서 여러 프로세스 그룹 실행에 대해 자세히 알아보세요.

각 Machine은 시작 시 서로 다른 명령을 실행할 수 있으므로, 웹 서버, 큐 워커 등 서로 다른 작업에 코드 베이스를 재사용할 수 있습니다.

여러 프로세스를 실행하려면 앱을 시작할 이름과 명령의 맵을 포함한 [processes] 블록이 필요합니다.

[processes]
  web = "bundle exec rails server -b [::] -p 8080"
  worker = "bundle exec sidekiqswarm"

나아가 특정 프로세스(들)을 [http_service] 또는 [[services]] 구성에 "매칭"할 수 있습니다. 예:

[http_service]
  processes = ["web"] # this service only applies to the web process
  internal_port = 8080
  force_https = true

볼륨도 특정 프로세스에 할당할 수 있습니다. 이중 대괄호를 사용해 둘 이상의 [[mounts]] 섹션을 포함하고, 서로 다른 프로세스 그룹의 Machines에 서로 다른 이름의 볼륨을 마운트하세요:

[[mounts]]
  source = "data"
  destination = "/data"
  processes = ["app"]

metrics 섹션

Fly 앱은 사용자 지정 메트릭을 Fly.io 호스팅 Prometheus 서비스로 내보내도록 구성할 수 있습니다.

[metrics]
  port = 9091
  path = "/metrics" # default for most prometheus exporters

사용자 지정 메트릭은 특정 processes에 대해서도 구성할 수 있으며, 여러 [[metrics]] 테이블을 정의하려면 이중 대괄호를 사용합니다:

[[metrics]]
  port = 9394
  path = "/metrics"
  processes = ["web"]

[[metrics]]
  port = 9113
  path = "/metrics"
  processes = ["proxy"]

앱의 메트릭 수집에 대한 자세한 내용은 Metrics on Fly.io를 확인하세요.

statics 섹션

fly.toml에서 [[statics]] 섹션을 사용해 이미지, CSS, JavaScript 같은 정적 파일을 애플리케이션에 제공할 수 있습니다. 정적 파일을 제공하는 두 가지 방법이 있습니다:

  • 실행 중인 Fly Machine에서
  • Tigris 객체 스토리지 버킷에서

Fly Machine에서 정적 파일 제공

fly.toml에 [[statics]] 섹션을 추가하면 Fly Proxy가 url_prefix와 일치하는 요청을 가로챕니다. 요청된 파일이 guest_path에 존재하면 요청이 머신 안에서 실행되는 정적 파일 서버로 라우팅됩니다. 이는 메인 웹 서버 프로세스를 우회합니다. 정적 파일이 제공되려면 머신이 실행 중이어야 합니다.

머신이 중지되면 정적 파일이 제공되지 않습니다. autostart가 활성화되어 있으면 정적 요청 중에도 일반 앱 요청과 마찬가지로 머신이 시작됩니다. 정적 자산은 항상 Fly 엣지나 프록시 호스트가 아니라 VM에서 직접 제공됩니다.

[[statics]]
  guest_path = "/app/public"
  url_prefix = "/public"

이 예시에서 /public/image.png에 대한 요청은 실행 중인 머신 안의 /app/public/image.png에서 제공됩니다. 애플리케이션당 최대 10개의 [[statics]] 매핑을 정의할 수 있습니다.

guest_path는 파일을 제공할 Docker 이미지의 디렉토리입니다. 매핑 간에 겹칠 수 있지만 url_prefix 값은 겹치면 안 됩니다. 주어진 접두사에 대해 하나의 정적 매핑만 인정됩니다. 예를 들어 /public/foo와 /public/bar에 대한 두 매핑은 허용되지만 /public에 대한 두 매핑은 허용되지 않습니다.

Tigris 객체 스토리지에서 정적 파일 제공

Tigris 객체 스토리지 버킷에서 직접 정적 파일을 제공할 수 있습니다. 이를 통해 자산이나 전체 정적 사이트를 Docker 이미지에 넣지 않고 버킷에서 호스팅할 수 있습니다.

Tigris 버킷의 정적 파일은 항상 Fly 엣지가 아니라 애플리케이션의 실행 중인 VM을 통해 제공됩니다. 실행 중인 머신이 없으면 Tigris 정적 파일에 대한 요청은 제공되지 않습니다. 하지만 앱에 대해 autostart가 활성화되어 있으면 정적 자산에 대한 요청이 일반 애플리케이션 트래픽과 마찬가지로 필요에 따라 머신을 자동 시작합니다.

[[statics]]
  guest_path = "/app/public"
  url_prefix = "/public"
  tigris_bucket = "my-bucket"

이 구성에서 /public 아래의 요청은 /app/public 경로 아래 my-bucket에 저장된 파일에서 제공됩니다. 이 파일들이 제공되려면 머신이 실행 중이어야 합니다. 머신이 0으로 스케일링되면 정적 자산에 접근할 수 없습니다.

후행 슬래시를 처리할 때 /public/dir/ 같은 디렉토리 경로에 대한 요청은 지정한 경우 index.html 파일을 찾습니다. /public/dir처럼 후행 슬래시가 없는 요청은 예상대로 제공되지 않을 수 있습니다. 리다이렉트를 사용하거나 사용자에게 이를 문서화하는 것을 고려해 보세요. Tigris 정적 파일은 index_document 키를 지원하며, 이를 통해 디렉토리 경로에 대한 기본 파일을 제공할 수 있습니다.

[[statics]]
  guest_path = "/app/public"
  url_prefix = "/public"
  tigris_bucket = "my-bucket"
  index_document = "index.html"

이 구성에서 https://example.com/public/에 대한 요청은 버킷에서 /app/public/index.html을 제공합니다. 마찬가지로 https://example.com/public/assets/는 /app/public/assets/index.html을 제공합니다.

Tigris 정적 파일은 Tigris 가격으로 청구됩니다. Tigris의 데이터 이그레스는 Tigris와 Fly Proxy 이그레스 요금이 모두 발생할 수 있습니다.

url_prefix 값을 겹치지 마세요. 주어진 접두사에 대해 하나의 정적 매핑만 인정됩니다.

주의사항

이 기능을 CDN과 직접 비교해서는 안 됩니다. 그 이유는 다음과 같습니다:

  • 이 기능은 Machine에서 웹 서비스를 실행해야 하는 의무를 면제하지 않습니다.
  • 정적 파일이 제공되려면 실행 중인 머신이 있어야 합니다. 머신이 중지되면 정적 자산이 제공되지 않습니다. auto_start_machines가 활성화되어 있으면 일반 애플리케이션 요청과 마찬가지로 정적 요청에 응답해 머신이 자동 시작됩니다.
  • Fly Proxy는 일치하는 요청을 머신 안에서 실행되는 정적 파일 서버로 직접 라우팅합니다. 정적 요청은 메인 애플리케이션 프로세스를 거치지 않고 동일한 VM 안의 파일 서버가 처리합니다.
  • 인덱스 문서 제공은 Tigris에서 직접 제공되는 정적 파일에서만 지원됩니다. 인덱스 문서는 Tigris 버킷의 관련 모든 위치에서 동일한 이름을 가져야 합니다.
  • 컨테이너에서 제공되는 정적 파일은 루트에서 index.html을 찾지 못합니다. 전체 경로를 요청해야 합니다.
  • 자산에 Cache-Control이나 다른 헤더를 설정할 수 없습니다. 그런 것이 필요하면 애플리케이션에서 제공하고 관련 헤더를 설정하세요.
  • statics는 심볼릭 링크를 인정하지 않습니다. 예를 들어 컨테이너의 /app/public이 /app-39403/public 같은 심볼릭 링크라면 statics 구성에서 절대 원본 경로를 사용하세요.

files 섹션

files 섹션은 배포 시점에 Machine 안에 파일을 배치할 수 있게 해 줍니다. 이는 구성 파일, 자격 증명, 또는 앱이 알려진 경로에서 필요로 하는 다른 데이터에 유용합니다.

각 [[files]] 항목은 guest_path와 정확히 하나의 소스(raw_value, local_path, secret_name)가 필요합니다:

  • guest_path: Machine 안에 파일이 생성될 절대 경로(예: /app/config.yaml). 앱이 파일을 찾을 것으로 예상하는 곳과 일치해야 합니다. 앱의 작업 디렉토리를 찾으려면 Dockerfile의 WORKDIR을 확인하세요.
  • raw_value: 인라인 파일 내용, base64 인코딩. macOS/Linux에서는 base64 < file.txt, PowerShell에서는 [Convert]::ToBase64String([IO.File]::ReadAllBytes(\"file.txt\"))로 값을 인코딩할 수 있습니다.
  • local_path: 로컬 머신(fly deploy를 실행하는 곳)의 파일 경로, fly.toml 디렉토리 기준 상대 경로 또는 절대 경로. 파일 내용은 base64 인코딩할 필요가 없습니다.
  • secret_name: fly secrets set으로 설정한 앱 시크릿의 이름. 시크릿 값은 설정되기 전에 base64 인코딩되어야 합니다(예: fly secrets set SUPER_SECRET=$(base64 < secret.txt)).

예시

프로젝트에서 구성 파일을 Machine에 배치:

[[files]]
  guest_path = "/app/config.yaml"
  local_path = "config/production.yaml"

예를 들어 프로젝트에 config/production.yaml이 있다면, 이 내용을 각 배포 시 Machine 안의 /app/config.yaml에 복사합니다.

base64 인코딩된 내용으로 작은 파일 인라인:

[[files]]
  guest_path = "/app/hello.txt"
  raw_value = "aGVsbG8gd29ybGQK"

aGVsbG8gd29ybGQK 값은 hello world\n의 base64 인코딩입니다. 이는 hello world를 포함한 /app/hello.txt를 생성합니다.

시크릿을 파일로 작성:

[[files]]
  guest_path = "/app/credentials.json"
  secret_name = "DB_CREDENTIALS"

이것은 DB_CREDENTIALS 시크릿의 (base64 디코딩된) 내용을 /app/credentials.json에 작성합니다. 시크릿은 fly secrets set DB_CREDENTIALS=$(base64 < credentials.json)으로 설정하세요.

선택적으로 processes 필드를 사용해 파일을 포함할 Machine(들)을 제한할 수 있습니다. 예:

[[files]]
  guest_path = "/path/to/config.yaml"
  local_path = "/local/path/config.yaml"
  processes = ["web"]

다음 배포에서 이전에 구성된 파일을 제거하려면 files 항목을 완전히 삭제하거나, 다음과 같이 소스를 빈 문자열로 설정하세요:

[[files]]
  guest_path = "/path/to/config.yaml"
  local_path = ""

experimental 섹션

이 섹션은 아직 메인 구성으로 승격되지 않은 플래그와 기능 설정을 위한 것입니다.

[experimental]
cmd = ["path/to/command", "arg1", "arg2"]
entrypoint = ["path/to/command", "arg1", "arg2"]
exec = ["path/to/command", "arg1", "arg2"]

cmd

Dockerfile이 설정한 CMD를 재정의합니다. 위 예시처럼 문자열 배열로 지정해야 합니다.

entrypoint

Dockerfile이 설정한 ENTRYPOINT를 재정의합니다. 위 예시처럼 문자열 배열로 지정해야 합니다.

exec

Dockerfile이 설정한 CMD와 ENTRYPOINT를 모두 재정의합니다. 위 예시처럼 문자열 배열로 지정해야 합니다.

더 알아보기 (Learn more)