호스팅 동작 구성

Firebase Hosting을 사용하면 사이트 요청에 대한 호스팅 동작을 맞춤설정할 수 있습니다.

Hosting에 무엇을 구성할 수 있나요?

  • 로컬 프로젝트 디렉터리에서 Firebase Hosting에 배포하려는 파일을 지정합니다. 방법 알아보기

  • 맞춤설정된 404/Not Found 페이지를 제공합니다(방법 알아보기).

  • 이동 또는 삭제한 페이지에 redirects를 설정합니다(방법 알아보기).

  • 다음 용도로 rewrites를 설정합니다.

  • headers를 추가하여 브라우저가 페이지 및 해당 콘텐츠(인증, 캐싱, 인코딩 등)를 처리하는 방법 등의 요청 또는 응답에 대한 추가 정보를 전달합니다(방법 알아보기).

  • 국제화(i18n) 재작성을 설정하여 사용자의 언어 설정 또는 국가에 따라 특정 콘텐츠를 제공합니다 (방법 알아보기)(다른 페이지).

Hosting 구성은 어디에서 정의하나요?

firebase.json 파일에서 Firebase Hosting 구성을 정의합니다. firebase init 명령어를 실행하면 Firebase가 프로젝트 디렉터리의 루트에 firebase.json 파일을 자동으로 생성합니다.

이 페이지 하단에 Firebase Hosting만 다루는 전체 firebase.json 구성 예시가 있습니다. firebase.json 파일에는 다른 Firebase 서비스의 구성도 포함될 수 있습니다.

Hosting REST API를 사용하여 배포된 firebase.json 콘텐츠를 확인할 수 있습니다.

Hosting 응답의 우선순위

이 페이지에 설명된 다른 Firebase Hosting 구성 옵션은 겹치는 경우도 있습니다. 충돌이 있으면 다음 우선순위에 따라 Hosting의 응답이 결정됩니다.

  1. /__/* 경로 세그먼트로 시작하는 예약된 네임스페이스
  2. 구성된 리디렉션
  3. 일치검색 정적 콘텐츠
  4. 구성된 재작성
  5. 맞춤 404 페이지
  6. 기본 404 페이지

i18n 재작성을 사용하는 경우 일치검색 및 404 처리 우선순위 순서가 'i18n 콘텐츠'를 수용하도록 확장됩니다.

배포할 파일 지정

기본 firebase.json 파일에 포함된 기본 속성(publicignore)은 Firebase 프로젝트에 배포해야 하는 프로젝트 디렉터리의 파일을 정의합니다.

firebase.json 파일의 기본 hosting 구성은 다음과 같습니다.

"hosting": {
  "public": "public",  // the only required attribute for Hosting
  "ignore": [
    "firebase.json",
    "**/.*",
    "**/node_modules/**"
  ]
}

공개

필수사항
public 속성은 Firebase Hosting에 배포할 디렉터리를 지정합니다. 기본값은 이름이 public인 디렉터리이지만, 프로젝트 디렉터리에 존재하는 한 디렉터리 경로를 임의로 지정할 수 있습니다.

다음은 배포할 디렉터리의 지정된 기본 이름입니다.

"hosting": {
  "public": "public"

  // ...
}

배포할 디렉터리로 기본값을 변경할 수 있습니다.

"hosting": {
  "public": "dist/app"

  // ...
}

ignore

선택사항
ignore 속성은 배포 시 무시할 파일을 지정합니다. Git에서 .gitignore를 처리하는 것과 동일한 방식으로 globs를 사용할 수 있습니다.

무시할 파일의 기본값은 다음과 같습니다.

"hosting": {
  // ...

  "ignore": [
    "firebase.json",  // the Firebase configuration file (the file described on this page)
    "**/.*",  // files with a leading period should be hidden from the system
    "**/node_modules/**"  // contains dependencies used to create your site but not run it
  ]
}

404/Not Found 페이지 맞춤설정

선택사항
사용자가 존재하지 않는 페이지에 액세스하려고 할 때 커스텀 404 Not Found 오류를 표시할 수 있습니다.

프로젝트의 public 디렉터리에 새 파일을 만들고 404.html로 이름을 지정한 다음 이 파일에 커스텀 404 Not Found 콘텐츠를 추가합니다.

브라우저가 도메인 또는 하위 도메인에서 404 Not Found 오류를 트리거하면 Firebase Hosting은 이 커스텀 404.html 페이지의 콘텐츠를 표시합니다.

리디렉션 구성

선택사항
페이지 이동으로 인한 링크 깨짐을 방지하거나 URL을 단축하려면 URL 리디렉션을 사용합니다. 예를 들어 브라우저를 example.com/team에서 example.com/about.html로 리디렉션할 수 있습니다.

객체 배열( '리디렉션 규칙'이라고 함)을 포함하는 redirects 속성을 만들어 URL 리디렉션을 지정합니다. 각 규칙에서 요청 URL 경로와 일치하는 경우 지정된 도착 URL로의 리디렉션에 응답하도록 Hosting을 트리거하는 URL 패턴을 지정합니다.

다음은 redirects 속성의 기본 구조입니다. 이 예시에서는 /bar에 새 요청을 생성하여 요청을 /foo로 리디렉션합니다.

"hosting": {
  // ...

  // Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
  "redirects": [ {
    "source": "/foo",
    "destination": "/bar",
    "type": 301
  } ]
}

redirects 속성에는 리디렉션 규칙 배열이 포함되어 있으며 각 규칙에는 아래 표의 필드가 포함되어야 합니다.

Firebase Hosting은 브라우저가 해당 경로에 파일 또는 폴더가 있는지 확인하기 전에 모든 요청 시작 시 source 또는 regex 값을 모든 URL 경로와 비교합니다. 일치하는 항목이 있으면 Firebase Hosting 원본 서버는 destination URL에서 새 요청을 생성하도록 브라우저에 알리는 HTTPS 리디렉션 응답을 보냅니다.

필드 설명
redirects
source(권장)
또는 regex

초기 요청 URL과 일치하는 경우 리디렉션을 적용하도록 Hosting을 트리거하는 URL 패턴입니다.

  • source를 사용하여 glob를 지정합니다(권장).
  • regex를 사용하여 RE2 정규 표현식을 지정합니다.
destination

브라우저가 새 요청을 생성해야 하는 정적 URL입니다.

이 URL은 상대 또는 절대 경로일 수 있습니다.

type

HTTPS 응답 코드

  • '영구 이전'에 301 유형 사용
  • '발견됨'에 302 유형 사용 (임시 리디렉션)

리디렉션의 URL 세그먼트 캡처

선택사항
리디렉션 규칙의 URL 패턴(source 또는 regex 값)에 해당하는 특정 세그먼트를 캡처한 다음 규칙의 destination 경로에서 이 세그먼트를 재사용해야 할 수도 있습니다.

재작성 구성

선택사항
여러 URL에서 동일한 콘텐츠를 표시하려면 재작성을 사용하세요. 재작성은 특히 패턴 일치와 함께 사용하면 유용합니다. 이러한 경우 패턴과 일치하는 모든 URL을 수용하고 클라이언트 측 코드에서 표시할 내용을 결정할 수 있습니다.

탐색에 HTML5 pushState를 사용하는 앱을 지원하도록 재작성을 사용할 수도 있습니다. 브라우저에서 지정된 source 또는 regex URL 패턴과 일치하는 URL 경로를 열려고 하면 브라우저에 destination URL의 파일 콘텐츠가 대신 제공됩니다.

객체 배열('재작성 규칙'이라고 함)을 포함하는 rewrites 속성을 만들어 URL 재작성을 지정합니다. 각 규칙에서 요청 URL 경로와 일치하는 경우 서비스가 지정된 도착 URL에 제공된 것처럼 응답하도록 Hosting을 트리거하는 URL 패턴을 지정합니다.

다음은 rewrites 속성의 기본 구조입니다. 이 예시에서는 존재하지 않는 파일 또는 디렉터리에 대한 요청의 index.html을 제공합니다.

"hosting": {
  // ...

  // Serves index.html for requests to files or directories that do not exist
  "rewrites": [ {
    "source": "**",
    "destination": "/index.html"
  } ]
}

rewrites 속성에는 재작성 규칙 배열이 포함되어 있으며 각 규칙에는 아래 표의 필드가 포함되어야 합니다.

Firebase Hosting은 지정된 source 또는 regex URL 패턴과 일치하는 URL 경로에 파일 또는 디렉터리가 없는 경우에만 재작성 규칙을 적용합니다. 요청이 재작성 규칙을 트리거하면 브라우저는 HTTP 리디렉션 대신 지정된 destination 파일의 실제 콘텐츠를 반환합니다.

필드 설명
rewrites
source(권장)
또는 regex

초기 요청 URL과 일치하는 경우 재작성을 적용하도록 Hosting을 트리거하는 URL 패턴입니다.

  • source를 사용하여 glob를 지정합니다(권장).
  • regex를 사용하여 RE2 정규 표현식을 지정합니다.
destination

존재해야 하는 로컬 파일

이 URL은 상대 또는 절대 경로일 수 있습니다.

함수에 요청 전달

rewrites를 사용하여 Firebase Hosting URL의 함수를 제공할 수 있습니다. 다음 예시는 Cloud Functions를 사용하여 동적 콘텐츠를 제공하는 내용의 일부입니다.

예를 들어 bigben 함수를 실행하기 위해 Hosting 사이트에서 /bigben 페이지의 모든 요청을 전달할 수 있습니다.

"hosting": {
  // ...

  // Directs all requests from the page `/bigben` to execute the `bigben` function
  "rewrites": [ {
    "source": "/bigben",
    "function": {
      "functionId": "bigben",
      "region": "us-central1"  // optional (see note below)
      "pinTag": true           // optional (see note below)
    }
  } ]
}

이 재작성 규칙을 추가하고 firebase deploy를 사용하여 Firebase에 배포한 후 다음 URL을 통해 함수에 연결할 수 있습니다.

  • Firebase 하위 도메인:
    PROJECT_ID.web.app/bigbenPROJECT_ID.firebaseapp.com/bigben

  • 연결된 모든 커스텀 도메인:
    CUSTOM_DOMAIN/bigben

Hosting을 사용하여 함수로 요청을 리디렉션할 때 지원되는 HTTP 요청 메서드는 GET, POST, HEAD, PUT, DELETE, PATCH, OPTIONS입니다. REPORT 또는 PROFIND와 같은 다른 메서드는 지원되지 않습니다.

Cloud Run 컨테이너에 요청 전달

rewrites를 사용하여 Firebase Hosting URL에서 Cloud Run 컨테이너에 액세스할 수 있습니다. 다음 예시는 Cloud Run을 사용하여 동적 콘텐츠를 제공하는 내용의 일부입니다.

예를 들어 Hosting 사이트의 /helloworld 페이지에서 보내는 모든 요청을 전달하여 helloworld 컨테이너 인스턴스의 시작 및 실행을 트리거하려면 다음 코드를 실행합니다.

"hosting": {
 // ...

 // Directs all requests from the page `/helloworld` to trigger and run a `helloworld` container
 "rewrites": [ {
   "source": "/helloworld",
   "run": {
     "serviceId": "helloworld",  // "service name" (from when you deployed the container image)
     "region": "us-central1"  // optional (if omitted, default is us-central1)
   }
 } ]
}

이 재작성 규칙을 추가하고 firebase deploy를 사용하여 Firebase에 배포한 후 다음 URL을 통해 컨테이너 이미지에 연결할 수 있습니다.

  • Firebase 하위 도메인:
    PROJECT_ID.web.app/helloworldPROJECT_ID.firebaseapp.com/helloworld

  • 연결된 모든 커스텀 도메인:
    CUSTOM_DOMAIN/helloworld

Hosting을 사용하여 Cloud Run 컨테이너로 요청을 리디렉션할 때 지원되는 HTTP 요청 메서드는 GET, POST, HEAD, PUT, DELETE, PATCH, OPTIONS입니다. REPORT 또는 PROFIND와 같은 다른 메서드는 지원되지 않습니다.

최상의 성능을 얻으려면 다음 리전을 사용하여 Cloud Run 서비스를 Hosting과 같은 위치에 배치합니다.

  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

Hosting에서 Cloud Run으로의 재작성은 다음 리전에서 지원됩니다.

  • asia-east1
  • asia-east2
  • asia-northeast1
  • asia-northeast2
  • asia-northeast3
  • asia-south1
  • asia-south2
  • asia-southeast1
  • asia-southeast2
  • australia-southeast1
  • australia-southeast2
  • europe-central2
  • europe-north1
  • europe-southwest1
  • europe-west1
  • europe-west12
  • europe-west2
  • europe-west3
  • europe-west4
  • europe-west6
  • europe-west8
  • europe-west9
  • me-central1
  • me-west1
  • northamerica-northeast1
  • northamerica-northeast2
  • southamerica-east1
  • southamerica-west1
  • us-central1
  • us-east1
  • us-east4
  • us-east5
  • us-south1
  • us-west1
  • us-west2
  • us-west3
  • us-west4
  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

rewrites를 사용하여 커스텀 도메인 Dynamic Links를 만들 수 있습니다. Dynamic Links의 커스텀 도메인 설정에 대한 자세한 내용은 Dynamic Links 문서를 참조하세요.

  • Dynamic Links 커스텀 도메인을 사용합니다.

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/"
        "dynamicLinks": true
      } ]
    }
  • Dynamic Links에 사용할 커스텀 도메인 경로 프리픽스를 지정합니다.

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/promos/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/promos/"
        "dynamicLinks": true
      }, {
        "source": "/links/share/**",  // the Dynamic Links start with "https://CUSTOM_DOMAIN/links/share/"
        "dynamicLinks": true
      } ]
    }

firebase.json 파일에서 Dynamic Links를 구성하려면 다음이 필요합니다.

필드 설명
appAssociation

AUTO로 설정해야 합니다.

  • 구성에 이 속성을 포함하지 않으면 appAssociation의 기본값은 AUTO입니다.
  • 이 속성을 AUTO로 설정하면 Hostingassetlinks.jsonapple-app-site-association 파일이 요청될 때 이러한 파일을 동적으로 생성할 수 있습니다.
rewrites
source

Dynamic Links에 사용할 경로

경로를 URL에 재작성하는 규칙과 달리 Dynamic Links 재작성 규칙에는 정규 표현식이 포함될 수 없습니다.

dynamicLinks true로 설정해야 합니다.

헤더 구성

선택사항
헤더를 사용하면 클라이언트 및 서버에서 요청 또는 응답과 함께 추가 정보를 전달할 수 있습니다. 일부 헤더 모음은 액세스 제어, 인증, 캐싱, 인코딩 등 브라우저가 페이지 및 콘텐츠를 처리하는 방식에 영향을 미칠 수 있습니다.

헤더 객체의 배열을 포함하는 headers 속성을 만들어 파일별 커스텀 응답 헤더를 지정합니다. 각 객체에서 요청 URL 경로와 일치하는 경우 지정된 커스텀 응답 헤더를 적용하도록 Hosting을 트리거하는 URL 패턴을 지정합니다.

다음은 headers 속성의 기본 구조입니다. 이 예시에서는 모든 글꼴 파일에 CORS 헤더를 적용합니다.

"hosting": {
  // ...

  // Applies a CORS header for all font files
  "headers": [ {
    "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
    "headers": [ {
      "key": "Access-Control-Allow-Origin",
      "value": "*"
    } ]
  } ]
}

headers 속성에는 정의 배열이 포함되어 있으며 각 정의에는 아래 표의 필드가 포함되어야 합니다.

필드 설명
headers
source(권장)
또는 regex

초기 요청 URL과 일치하는 경우 커스텀 헤더를 적용하도록 Hosting을 트리거하는 URL 패턴입니다.

  • source를 사용하여 glob를 지정합니다(권장).
  • regex를 사용하여 RE2 정규 표현식을 지정합니다.

커스텀 404 페이지와 일치할 헤더를 만들려면 404.htmlsource 또는 regex 값으로 사용합니다.

(하위) headers 배열

Hosting이 요청 경로에 적용하는 커스텀 헤더입니다.

각 하위 헤더에는 keyvalue이 포함되어야 합니다(다음 두 행 참조).

key 헤더 이름(예: Cache-Control)
value 헤더 값(예: max-age=7200)

Cache-Control에 대한 자세한 내용은 동적 콘텐츠 제공 및 마이크로서비스 호스팅을 설명하는 Hosting 섹션을 참조하세요. CORS 헤더에 대해서도 자세히 알아볼 수 있습니다.

.html 확장자 제어

선택사항
cleanUrls 속성을 사용하면 URL에 .html 확장자를 포함할지 여부를 제어할 수 있습니다.

true로 설정하면 Hosting은 업로드된 파일 URL에서 자동으로 .html 확장자를 삭제합니다. .html 확장자가 요청에 추가되면 Hosting은 동일한 경로로 301 리디렉션을 수행하지만 .html 확장자를 없앱니다.

cleanUrls 속성을 포함하여 URL에 .html이 포함되는 것을 제어하는 방법은 다음과 같습니다.

"hosting": {
  // ...

  // Drops `.html` from uploaded URLs
  "cleanUrls": true
}

후행 슬래시 제어

선택사항
trailingSlash 속성을 사용하면 정적 콘텐츠 URL에 후행 슬래시 포함 여부를 제어할 수 있습니다.

  • true로 지정하면 Hosting은 URL을 리디렉션하여 후행 슬래시를 추가합니다.
  • false로 지정하면 Hosting은 URL을 리디렉션하여 후행 슬래시를 삭제합니다.
  • 아무것도 지정하지 않으면 Hosting은 디렉터리 색인 파일(예: about/index.html)에만 후행 슬래시를 사용합니다.

trailingSlash 속성을 추가하여 후행 슬래시를 제어하는 방법은 다음과 같습니다.

"hosting": {
  // ...

  // Removes trailing slashes from URLs
  "trailingSlash": false
}

trailingSlash 속성은 Cloud Functions 또는 Cloud Run에서 제공하는 동적 콘텐츠에 대한 재작성에 영향을 미치지 않습니다.

Glob 패턴 일치

Firebase Hosting 구성 옵션은 Git이 gitignore 규칙을 처리하는 방법과 Bowerignore 규칙을 처리하는 방법과 비슷하게 extglob의 glob 패턴 일치 표기법을 광범위하게 사용합니다. 이 위키 페이지에서 더 자세한 내용을 확인할 수 있으며 다음은 이 페이지에 사용한 예시에 대한 설명입니다.

  • firebase.jsonpublic 디렉터리 루트의 firebase.json 파일과만 일치합니다.

  • ** — 임의 하위 디렉터리의 모든 파일 또는 폴더와 일치합니다.

  • *public 디렉터리 루트의 파일 및 폴더와만 일치합니다.

  • **/.* — 임의 하위 디렉터리에서 .로 시작하는 모든 파일(일반적으로 .git과 같은 폴더에 있는 숨김 파일)과 일치합니다.

  • **/node_modules/**node_modules 폴더의 임의 하위 디렉터리에 있는 모든 파일 또는 폴더와 일치합니다. 'node_modules' 폴더는 public 디렉터리의 임의 하위 디렉터리에 있을 수 있습니다.

  • **/*.@(jpg|jpeg|gif|png) — 임의 하위 디렉터리에서 정확히 .jpg, .jpeg, .gif 또는 .png 중 하나로 끝나는 모든 파일과 일치합니다.

전체 Hosting 구성 예시

다음은 Firebase Hosting의 전체 firebase.json 구성 예시입니다. firebase.json 파일에는 다른 Firebase 서비스의 구성도 포함될 수 있습니다.

{
  "hosting": {

    "public": "dist/app",  // "public" is the only required attribute for Hosting

    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],

    "redirects": [ {
      "source": "/foo",
      "destination": "/bar",
      "type": 301
    }, {
      "source": "/firebase/**",
      "destination": "https://www.firebase.com",
      "type": 302
    } ],

    "rewrites": [ {
      // Shows the same content for multiple URLs
      "source": "/app/**",
      "destination": "/app/index.html"
    }, {
      // Configures a custom domain for Dynamic Links
      "source": "/promos/**",
      "dynamicLinks": true
    }, {
      // Directs a request to Cloud Functions
      "source": "/bigben",
      "function": "bigben"
    }, {
      // Directs a request to a Cloud Run containerized app
      "source": "/helloworld",
      "run": {
        "serviceId": "helloworld",
        "region": "us-central1"
      }
    } ],

    "headers": [ {
      "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
      "headers": [ {
        "key": "Access-Control-Allow-Origin",
        "value": "*"
      } ]
    }, {
      "source": "**/*.@(jpg|jpeg|gif|png)",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=7200"
      } ]
    }, {
      "source": "404.html",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=300"
      } ]
    } ],

    "cleanUrls": true,

    "trailingSlash": false,

    // Required to configure custom domains for Dynamic Links
    "appAssociation": "AUTO",

  }
}