Most of the time, we recommend using
[automatic rollouts](https://firebase.google.com/docs/app-hosting/rollouts.md.txt) or
[manually-triggered rollouts](https://firebase.google.com/docs/app-hosting/rollouts.md.txt#manually-trigger)
from the Firebase console. However, you may have a use for a more customized
deployment flow. App Hosting has multiple options for custom deployment.

## Deploy from source

Deploying from source lets you push your application's source code and
configuration directly to App Hosting without requiring a persistent GitHub
connection.

When deploying from source, App Hosting uploads your source code to a
Google Cloud Storage bucket, runs your framework's build command in
Cloud Build, and deploys the compiled artifacts to Cloud Run and
Cloud CDN. The same [build process](https://firebase.google.com/docs/app-hosting/build.md.txt) is used for local
source deployments as GitHub deployments. If a `.gitignore` file is present in
your project, the files and folders listed inside it are excluded from your
deployment.

You can deploy from a local source using either the **Firebase CLI** or the
**Firebase console**.

### Required IAM Permissions and Infrastructure Setup

Because both the Firebase CLI and the Firebase console use the same
backend infrastructure to store and build your source archives, the **same IAM
permission requirements apply to both deployment methods**.

The exact requirements depend on whether or not you are deploying to a specific
location (region) for the first time. For more information on permissions, see
the [overview of Firebase
IAM](https://firebase.google.com/docs/projects/iam/overview#overview_of_firebase_iam) and specific
[Firebase App Hosting permissions](https://firebase.google.com/docs/projects/iam/permissions.md.txt#app-hosting).

#### Permissions for Initial Onboarding (First deployment to a location)

When local source deployment is initiated in a project location for the first
time, App Hosting must provision a GCS bucket to store your archives and
grant the App Hosting Service Agent access to reach them. **Because these
are project-level administrative tasks, they require Project Owner or IAM Admin
permissions**. A user with a basic Editor or Viewer role can't perform this
initial setup and will be blocked.

Prerequisite setup permissions include:

- **Enable Storage API** : `serviceusage.services.enable`
- **Create source bucket** : `storage.buckets.create` and `storage.buckets.list`
- **Configure Service Agent** : `resourcemanager.projects.setIamPolicy` to grant App Hosting read access (`roles/storage.objectViewer`) so it can fetch the uploaded code during builds.

For initial deployment, the GCS bucket is created with a 30-day lifecycle, after
which the bucket is deleted. However, you can manage this timeframe in the Cloud
console in **Cloud Storage** -\> **Buckets** -\> **Lifecycle** -\> **Rules** . See
[manage object
lifecycles](https://docs.cloud.google.com/storage/docs/managing-lifecycles).

#### Permissions for Subsequent Deployments (After location is initialized)

Once the source bucket and role bindings have been initialized for a location
(by either an initial CLI deployment or console setup), **regular Developers,
Editors, or App Hosting Admins** can deploy updates. Project-level
administration permissions aren't required for routine deployments.

Active deployment permissions include:

- **Verify bucket** : `storage.buckets.list`
- **Upload source archive** : `storage.objects.create`
- **Trigger build \& rollout** : Standard App Hosting permissions (`apphosting.builds.create` and `apphosting.rollouts.create`)

### Deploy from source with the Firebase CLI

Firebase CLI v14.4.0 and higher
lets you push your app's source code and configurations directly from your local
machine to Firebase. This is convenient if you already manage other Firebase
deployments (such as security rules or functions) and want to deploy your web
app and backend services together with a single CLI command.

#### Prerequisites

- Your projects must be on the **Blaze plan**.
- You must be running **firebase-tools version 14.4.0** or higher.

#### Deployment Steps

1. Run `firebase init apphosting` in your local project directory.
2. When prompted, select **Use an existing project** and choose your target Firebase project.
3. Select either a new or existing backend to deploy to; this step sets up App Hosting deployments for your local directory and prompts you for configuration details:
   - The ID of the backend to deploy to
   - The region to deploy to, if creating a new backend
   - The path to the root directory of your application code
   - Your preferred **Node.js runtime** . Selecting a versioned runtime enables [**Automatic Base Image Updates (ABIU)**](https://firebase.google.com/docs/app-hosting/frameworks-tooling.md.txt#abiu) to automatically apply security patches to your underlying environment.
4. App Hosting saves your deployment preferences in `firebase.json`, creating the file in your local project if it doesn't already exist. Once initialization completes successfully, run `firebase deploy` to deploy your source code.

> [!NOTE]
> **Note:** If you're bypassing interactive prompts (for example, in CI/CD scripts), you can manage your ABIU and runtime settings using the command-line flag `--runtime` (for example, `--runtime nodejs22`). If you have local source deployments set up for multiple backends (meaning there are multiple `backendId` entries in `firebase.json`), `firebase deploy` deploys to each of those backends. To deploy to a specific backend, use `firebase deploy
> --only apphosting:backendId`.

#### Example firebase.json

```json
{
  "apphosting": [
    {
      "backendId": "my-backend",
      // rootDir specifies the directory containing the app to deploy, but the entire
      // parent directory of firebase.json will be zipped and uploaded to ensure that
      // dependencies outside of the app directory will be available at build time.
      "rootDir": "./my-app",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log",
        "functions"
      ]
    }
  ]
}
```

### Deploy with the Firebase Console (Zip Upload)

The **Firebase console** provides a graphical interface to deploy
applications by uploading a compressed source archive directly. This serves as
an alternative to the GitHub connection flow, for cases where you prefer not to
use GitHub or prefer a different CI/CD setup.

Archive uploads can be performed during **initial backend creation** or when
**creating a manual rollout** on an existing backend, including backends
originally deployed using the Firebase CLI.

#### Supported Formats

The console uploader natively validates and accepts two compressed archive
formats:

- `.zip`
- `.tgz`

These formats are explicitly displayed in the file uploader's description text.

#### Deployment Steps

##### Option A: During Initial Backend Onboarding

1. **Select Source** : In the backend creation wizard, select **Upload a zip** during the "How do you want to import your app?" step.
2. **Onboarding Preparation** : Clicking "Next" triggers the background preparation flow, which sequentially enables the Storage API, ensures the correct roles are set up, and upserts the bucket. The UI displays a loading spinner with dynamic status messages: *"Enabling API...",* *"Checking
   permissions...",* and *"Preparing bucket..."* .
   - *Error Handling \& Guardrails* : If any preparation step fails (such as a non-Owner receiving a `403 PERMISSION_DENIED` due to insufficient IAM permissions), the UI displays a dedicated warning instructing you to contact a Project Owner. Stepper navigation is strictly locked, and the "Next" button and final "Finish and Deploy" remain disabled until the issue is resolved.
3. **Upload Files**: Once preparation completes successfully, select or drag your archive file into the file uploader component.
4. **Configure Settings** : Specify your **App root directory** (defaults to
   `/`).

   > [!NOTE]
   > **Note:** The value you enter specifies the directory containing the app to deploy. Make sure to zip and upload the entire project root directory (including any shared dependencies or configuration files outside the app directory) to ensure they will be available at build time.

5. Click **Finish and Deploy**: The standalone "Finish" button is disabled for
   zip uploads because uploading an archive is a one-time action and must be
   immediately followed by a deployment to ensure a functional backend.

##### Option B: Creating a Manual rollout

1. **Open Dialog** : In the App Hosting dashboard, click **Create rollout**.
2. **Select Source** : Select **Upload a zip** in the dialog's stepper. If the backend doesn't have an existing GitHub connection, the "GitHub" option is disabled.
3. **Preparation \& Upload** : The selection triggers the same background preparation flow (*"Enabling API..."* , *"Checking permissions..."* , and *"Preparing bucket..."* ). Once successful, drag or select your archive file using the uploader, specify the **App root directory** , and click **Deploy** to trigger the build and rollout.

## Deploy using Terraform

If you need greater control over the build process and deployed environment, you
can deploy using Terraform. Terraform lets you define and manage your
App Hosting resources using declarative configuration files, and provides
the ability to deploy your own prebuilt container image directly to
App Hosting instead of relying on App Hosting to build from your source
code.

If you're new to Terraform, see
[Get started with Terraform and Firebase](https://firebase.google.com/docs/projects/terraform/get-started.md.txt).
If you're already familiar with
Terraform, you can get started with sample configuration files and other
[App Hosting resources](https://firebase.google.com/docs/projects/terraform/get-started.md.txt#resources-app-hosting).

## Set up a GitHub connection for CI/CD

You have the option
to connect a GitHub repository at any time in the **Deployment** tab of a
backend's settings in the Firebase console. This lets you
deploy an app prototype from a local environment
and then transition to an automated CI/CD pipeline when you're ready.

## Deploy using AI tools

**We're sunsetting Firebase Studio on March 22, 2027** .
While your
App Hosting backends aren't affected, the *Publish* button in
Firebase Studio will be retired. To continue publishing updates without
changing your URL, migrate your project.
[Learn how to migrate](https://firebase.google.com/docs/studio/migrating-project.md.txt).