콘솔로 이동

호스팅 동작 구성

Firebase 호스팅을 사용하면 커스텀 오류 페이지, 리디렉션, 재작성, 헤더를 포함한 호스팅 동작을 맞춤설정할 수 있습니다. 또한 프로젝트 디렉터리에서 Firebase 프로젝트로 배포할 파일도 지정할 수 있습니다.

firebase.json 파일에 Firebase 호스팅 구성을 정의합니다.

프로젝트 디렉터리의 루트에서 firebase.json 파일을 찾습니다. firebase init 명령어를 실행하면 Firebase에 firebase.json 파일이 자동으로 생성됩니다.

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

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

호스팅 응답의 우선순위

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

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

배포할 파일 지정

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

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

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

public

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

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

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

  // ...
}

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

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

  // ...
}

ignore

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

다음은 무시할 파일의 기본값입니다.

"hosting": {
  // ...

  "ignore": [
    "firebase.json",  // the Firebase configuration file (this file)
    "**/.*",  // 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 호스팅은 이 커스텀 404.html 페이지의 콘텐츠를 표시합니다.

리디렉션 구성

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

firebase.json 파일의 hosting 내에서 redirects 속성을 포함하여 URL 리디렉션을 지정합니다. 예를 들면 다음과 같습니다.

"hosting": {
  // ...

  // Add the "redirects" attribute within "hosting"
  "redirects": [ {
    // Returns a permanent redirect to "/bar" for requests to "/foo" (but not "/foo/**")
    "source": "/foo",
    "destination": "/bar",
    "type": 301
  }, {
    // Returns a permanent redirect to "/bar" for requests to both "/foo" and "/foo/**"
    "source": "/foo{,/**}"
    "destination": "/bar"
    "type": 301
  }, {
    // Returns a temporary redirect for all requests to files or directories in the "firebase" directory
    "source": "/firebase/**",
    "destination": "https://firebase.google.com/",
    "type": 302
  } ]
}

redirects 속성은 리디렉션 규칙 배열을 포함합니다. 각 규칙에는 다음이 포함되어야 합니다.

  • glob 패턴을 지정하는 source

  • 상대 또는 절대 경로가 될 수 있는 정적 URL인 destination

  • HTTP 응답 코드를 지정하는 type

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

마지막으로 type 값은 제공된 특정 HTTP 응답 코드를 지정하며 '영구 이동'을 나타내는 301 또는 '발견됨'(임시 리디렉션)을 나타내는 302일 수 있습니다.

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

선택사항
경우에 따라 리디렉션 source URL의 특정 세그먼트를 캡처한 후 리디렉션 destination URL에서 이 세그먼트를 다시 사용해야 할 수도 있습니다.

이 세그먼트를 식별하기 위해 : 프리픽스를 포함하여 이 세그먼트를 캡처할 수 있습니다. 이 세그먼트 뒤의 나머지 URL 경로도 캡처해야 하는 경우 세그먼트 바로 뒤에 *를 포함합니다. 예를 들면 다음과 같습니다.

"hosting": {
  // ...

  "redirects": [ {
    "source": "/blog/:post*",  // captures the entire URL segment beginning at "post"
    "destination": "https://blog.myapp.com/:post", // includes the entire URL segment identified and captured by the "source" value
    "type": 301
  }, {
    "source": "/users/:id/profile",  // captures only the URL segment "id", but nothing following
    "destination": "/users/:id/newProfile",  // includes the URL segment identified and caputured by the "source" value
    "type": 301
  } ]
}

재작성 구성

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

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

firebase.json 파일의 hosting 내에 rewrites 속성을 포함하여 URL 재작성을 지정합니다. 예를 들면 다음과 같습니다.

"hosting": {
  // ...

  // Add the "rewrites" attribute within "hosting"
  "rewrites": [ {
    // Serves index.html for requests to files or directories that do not exist
    "source": "**",
    "destination": "/index.html"
  }, {
    // Serves index.html for requests to both "/foo" and "/foo/**"
    // Using "/foo/**" only matches paths like "/foo/xyz", but not "/foo"
    "source": "/foo{,/**}",
    "destination": "/index.html"
  }, {
    // Excludes specified pathways from rewrites
    "source": "!/@(js|css)/**",
    "destination": "/index.html"
  } ]
}

rewrites 속성은 재작성 규칙 배열을 포함합니다. 각 규칙에는 다음이 포함되어야 합니다.

  • glob 패턴을 지정하는 source

  • 반드시 있어야 하는 로컬 파일인 destination

Firebase 호스팅은 지정된 source에 파일 또는 디렉터리가 없는 경우에만 재작성 규칙을 적용합니다. 규칙을 트리거하면 브라우저는 HTTP 리디렉션 대신 지정된 destination 파일의 실제 콘텐츠를 반환합니다.

함수에 요청 전달

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

예를 들어 bigben 함수를 실행하기 위해 호스팅 사이트에서 /bigben 페이지의 모든 요청을 전달하려면 다음 명령어를 실행합니다.

"hosting": {
  // ...

  // Add the "rewrites" attribute within "hosting"
  "rewrites": [ {
    "source": "/bigben",
    "function": "bigben"
  } ]
}

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

  • Firebase 하위 도메인: projectID.web.app/bigben, projectID.firebaseapp.com/bigben

  • 연결된 모든 커스텀 도메인: custom-domain/bigben

Cloud Run 컨테이너에 요청 전달

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

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

"hosting": {
 // ...

 // Add the "rewrites" attribute within "hosting"
 "rewrites": [ {
   "source": "/helloworld",
   "run": {
     "serviceId": "helloworld",  // "service name" (from when you <a href="#deploy">deployed the container image)</a>
     "region": "us-central1"     // optional (if omitted, default is us-central1)
   }
 } ]
}

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

  • Firebase 하위 도메인: projectID.web.app/helloworld, projectID.firebaseapp.com/helloworld

  • 연결된 모든 커스텀 도메인: custom-domain/helloworld

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

예를 들어 다음과 같이 할 수 있습니다.

  • 동적 링크에 도메인을 사용합니다.

    "hosting": {
      // ...
    
      "appAssociation": "AUTO",  // required for Dynamic Links (default is AUTO if not specified)
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/**",  // Dynamic Links start with "https://<your-domain>/"
        "dynamicLinks": true
      } ]
    }
    
  • 동적 링크에 사용할 경로 프리픽스를 지정합니다.

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

firebase.json 파일에서 동적 링크를 구성하려면 필요한 사항입니다.

  • AUTO로 설정된 appAssociation 속성

    • 구성에 속성을 포함하지 않으면 appAssociation의 기본값은 AUTO입니다.
    • 이 속성을 AUTO로 설정하면 호스팅은 assetlinks.jsonapple-app-site-association 파일이 요청될 때 이러한 파일을 동적으로 생성합니다.
  • 재작성 규칙의 배열을 포함하는 동적 링크의 rewrites 속성. 각 규칙에는 다음이 포함되어야 합니다.

    • 동적 링크에 사용할 경로를 지정하는 source

      • 경로를 URL에 재작성하는 규칙과 달리 동적 링크 재작성 규칙에는 정규 표현식을 포함할 수 없습니다.
    • true로 설정된 dynamicLinks 속성

헤더 구성

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

firebase.json 파일의 hosting 내에 headers 속성을 포함하여 파일별 커스텀 응답 헤더를 지정합니다. 예를 들면 다음과 같습니다.

"hosting": {
  // ...

  // Add the "headers" attribute within "hosting"
  "headers": [ {
    // Specifies a CORS header for all font files
    "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
    "headers": [ {
      "key": "Access-Control-Allow-Origin",
      "value": "*"
    } ]
  }, {
    // Overrides the default 1 hour browser cache with a 2 hour cache for all image files
    "source": "**/*.@(jpg|jpeg|gif|png)",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=7200"
    } ]
  }, {
    // Sets the cache header for 404 pages to cache for 5 minutes
    "source": "404.html",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=300"
    } ]
  } ]
}

headers 속성은 정의 배열을 포함합니다. 각 정의에는 다음 사항이 포함되어야 합니다.

  • 재작성 규칙에 관계없이 호스팅이 원래 요청 경로와 비교하는 source

  • 호스팅이 요청 경로에 적용하는 (하위) headers 배열. 각 하위 헤더 배열에는 지정된 keyvalue가 포함되어야 합니다.

Cache-Control에 대한 자세한 내용은 동적 콘텐츠 제공 및 마이크로서비스 호스팅을 설명하는 호스팅 섹션을 참조하세요.

CORS 헤더에 대해서도 자세히 알아볼 수 있습니다.

.html 확장자 제어

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

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

firebase.json 파일의 hosting 내에 cleanUrls 속성을 포함하여 .html 확장자 포함 여부를 지정합니다. 예를 들면 다음과 같습니다.

"hosting": {
  // ...

  // Add the "cleanUrls" attribute within "hosting"
  "cleanUrls": true
}

후행 슬래시 제어

선택사항
trailingSlash 속성을 사용하면 URL 맨 뒤에 슬래시를 붙일지 여부를 제어할 수 있습니다.

  • true로 지정하면 호스팅은 URL을 리디렉션하여 맨 뒤에 슬래시를 추가합니다.
  • false로 지정하면 호스팅은 URL을 리디렉션하여 맨 뒤에 슬래시를 삭제합니다.
  • 지정하지 않으면 호스팅은 디렉터리 색인 파일(예: about/index.html)에만 맨 뒤에 슬래시를 사용합니다.

firebase.json 파일의 hosting 내에 trailingSlash 속성을 포함하여 맨 뒤에 슬래시를 추가하도록 지정합니다. 예를 들면 다음과 같습니다.

"hosting": {
  // ...

  // Add the "trailingSlash" attribute within "hosting"
  "trailingSlash": false
}

Glob 패턴 일치

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

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

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

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

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

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

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

전체 호스팅 구성 예

다음은 Firebase 호스팅의 전체 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",

  }
}