This guide shows you how to use buildpacks with your function source code to create a container image. For example, use buildpacks to build a Cloud Run function that you want to deploy on [Cloud Run](https://docs.cloud.google.com/run/docs/deploying).

<br />

There are two methods for building container images with buildpacks:

- **Build locally** with the `pack` CLI to locally test your function and rapidly prototype changes before deployment.
- **Build remotely** with [Cloud Build](https://docs.cloud.google.com/build/docs/overview). Building with Cloud Build is useful for functions that have a resource-intensive build processes and can also help [protect your software supply chain](https://docs.cloud.google.com/build/docs/view-build-security-insights).

## Configure your project to build functions

To build functions with buildpacks:

- Include the [Functions Framework](https://docs.cloud.google.com/functions/docs/functions-framework) library.

- Set the `GOOGLE_FUNCTION_TARGET` environment variable to the name
  of the function that you use as the entrypoint. You can do this by including
  a `project.toml` in the same folder as your source code. The `project.toml`
  file must have the following configuration:

    [[build.env]]
        name = "GOOGLE_FUNCTION_TARGET"
        value =  "ENTRY_POINT"

Replace <var translate="no">ENTRY_POINT</var> with the function method.

For details about how to
use environment variables with Cloud Run functions, see
[Configure Cloud Run functions services](https://docs.cloud.google.com/docs/buildpacks/service-specific-configs#additional_environment_variables).

## Local builds

[Pack](https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/)
is a CLI tool maintained by the CNB project to support the use of buildpacks. Use
the `pack` CLI to locally build your functions into a container image.

### Before you begin

1. Install [Docker Community Edition (CE)](https://docs.docker.com/engine/installation/) on your workstation. Docker is used by `pack` as an OCI image builder.
2. Install [Pack CLI](https://buildpacks.io/docs/tools/pack/).
3. Install the [Git source control](https://git-scm.com/downloads) tool to fetch the sample application from GitHub.

### Build a function locally

You use the `pack build` command and specify the default builder
`--builder=gcr.io/buildpacks/builder` to build your container images locally.

    pack build --builder=gcr.io/buildpacks/builder IMAGE_NAME

Replace <var translate="no">IMAGE_NAME</var> with the name of your container image.

You can also customize your container image by
[extending the build and run images](https://docs.cloud.google.com/docs/buildpacks/build-run-image).

#### Build a sample function locally

The following examples demonstrate how to build a sample locally.

1. Clone the sample repository to your local machine:

   ```bash
   git clone https://github.com/GoogleCloudPlatform/buildpack-samples.git
   ```
2. Change to the directory that contains the application sample code:

   ### Go

   ```sh
   cd buildpack-samples/sample-functions-framework-go
   ```

   ### Java

   ```sh
   cd buildpack-samples/sample-functions-framework-java-mvn
   ```

   ### Node.js

   ```sh
   cd buildpack-samples/sample-functions-framework-node
   ```

   ### Python

   ```sh
   cd buildpack-samples/sample-functions-framework-python
   ```

   ### Ruby

   ```sh
   cd buildpack-samples/sample-functions-framework-ruby
   ```
3. Use `pack` to build the sample function:

   ### Go

   ```sh
   pack build --builder=gcr.io/buildpacks/builder sample-functions-framework-go
   ```

   ### Java

   ```sh
   pack build --builder gcr.io/buildpacks/builder:v1 sample-functions-java-mvn
   ```

   ### Node.js

   ```sh
   pack build --builder=gcr.io/buildpacks/builder sample-functions-framework-node
   ```

   ### Python

   ```sh
   pack build --builder=gcr.io/buildpacks/builder sample-functions-framework-python
   ```

   ### Ruby

   ```sh
   pack build --builder=gcr.io/buildpacks/builder sample-functions-framework-ruby
   ```
4. Run the image using `docker`:

   ### Go

   ```sh
   docker run -p8080:8080 sample-functions-framework-go
   ```

   ### Java

   ```sh
   docker run -it -ePORT=8080 -p8080:8080 sample-functions-java-mvn
   ```

   ### Node.js

   ```sh
   docker run -it -ePORT=8080 -p8080:8080 sample-functions-framework-node
   ```

   ### Python

   ```sh
   docker run -it -ePORT=8080 -p8080:8080 sample-functions-framework-python
   ```

   ### Ruby

   ```sh
   docker run -it -ePORT=8080 -p8080:8080 sample-functions-framework-ruby
   ```
5. Visit the running function by browsing to <localhost:8080>.

## Remote builds

Use [Cloud Build](https://docs.cloud.google.com/build) to build your function into a container
image, and [Artifact Registry](https://docs.cloud.google.com/artifact-registry) as the container repository to
store and deploy each image.

### Before you begin

> [!NOTE]
> If you've already installed Google Cloud CLI previously, make sure you have the
> latest available version by running `gcloud components update`.

1. Ensure that your Google Cloud project has access to a container image repository. To configure access to a
   [Docker repository in
   Artifact Registry](https://docs.cloud.google.com/artifact-registry/docs/docker/store-docker-container-images):

   1. Create a new Docker repository in the same location of your Google Cloud project.

      ```bash
      gcloud artifacts repositories create REPO_NAME \
      --repository-format=docker \
      --location=REGION --description="DESCRIPTION"
      ```
      Replace:
      - `REPO_NAME` with the name that you choose for your Docker repository.
      - `REGION` with the [location](https://docs.cloud.google.com/artifact-registry/docs/repositories/repo-locations) in or nearest to the location of your Google Cloud project.
      - `DESCRIPTION` with a description of your choice.

      For example, to create a `docker` repository in
      `us-west2` with the description "Docker repository", you run:

      ```bash
      gcloud artifacts repositories create buildpacks-docker-repo --repository-format=docker \
      --location=us-west2 --description="Docker repository"
      ```
   2. Verify that your repository was created:

      ```bash
      gcloud artifacts repositories list
      ```

      You should see name that you choose for your Docker repository in the list.

### Build a function remotely

You use the [`gcloud builds submit`](https://docs.cloud.google.com/sdk/gcloud/reference/builds/submit)
command to build and upload your container image to your repository.

You can choose to specify your container image in the command itself or use
a configuration file.

#### Build with command

To build without a configuration file, specify the `image` flag:

```bash
gcloud builds submit --pack image=LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/IMAGE_NAME
```

Replace:

- `LOCATION` with the region name of your container repository, for example, `us-west2`
- `PROJECT_ID` with the ID of your Google Cloud project.
- `REPO_NAME` with the name of your Docker repository.
- `IMAGE_NAME` with the name of your container image.

Example:

`gcloud builds submit --pack image=us-west2-docker.pkg.dev/my-project-id/my-buildpacks-docker-repo`

#### Build with configuration files

You can use a
[configuration file](https://docs.cloud.google.com/build/docs/configuring-builds/create-basic-configuration)
to define your image repository configuration
details. The configuration file uses the YAML file
format and must include a build step that uses the `pack` CLI.

1. Create a YAML file name `cloudbuild.yaml` that includes the URI of your
   container image repository.

        options:
          logging: CLOUD_LOGGING_ONLY
          pool: {}
        projectId: PROJECT_ID
        steps:
        - name: gcr.io/k8s-skaffold/pack
          entrypoint: pack
          args:
          - build
          - LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/IMAGE_NAME
          - --builder
          - gcr.io/buildpacks/builder:latest
          - --network
          - cloudbuild
          - --publish
        - name: gcr.io/cloud-builders/docker
          entrypoint: pack
          args:
          - pull
          - LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/IMAGE_NAME
        images:
        - LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/IMAGE_NAME

   Replace:
   - `LOCATION` with the region name of your container repository, for example, `us-west2`.
   - `PROJECT_ID` with the ID of your Google Cloud project.
   - `REPO_NAME` with the name of your Docker repository.
   - `IMAGE_NAME` with the name of your container image.
2. Build the application.

   If you named your configuration file `cloudbuild.yaml`, run
   the following command:

       gcloud builds submit .

   > [!TIP]
   > **Tip:** If you use a unique name for your configuration file, use the [`--config`](https://docs.cloud.google.com/sdk/gcloud/reference/builds/submit#--config) flag.

### Example: Build a sample function remotely

The following examples demonstrate how to build a sample remotely, and
verify that the container image was pushed to your repository in Artifact Registry.

1. Clone the sample repository to your local machine:

   ```bash
   git clone https://github.com/GoogleCloudPlatform/buildpack-samples.git
   ```
2. Change to the directory that contains the application sample code:

   ### Go

   ```sh
   cd buildpack-samples/sample-functions-framework-go
   ```

   ### Java

   ```sh
   cd buildpack-samples/sample-functions-framework-java-mvn
   ```

   ### Node.js

   ```sh
   cd buildpack-samples/sample-functions-framework-node
   ```

   ### Python

   ```sh
   cd buildpack-samples/sample-functions-framework-python
   ```

   ### Ruby

   ```sh
   cd buildpack-samples/sample-functions-framework-ruby
   ```
3. Use `gcloud` to submit the application source code to Cloud Build:

   ### Go

   ```sh
   gcloud builds submit --pack image=LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/sample-functions-framework-go
   ```

   ### Java

   ```sh
   gcloud builds submit --pack image=LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/sample-functions-framework-gradle
   ```

   ### Node.js

   ```sh
   gcloud builds submit --pack image=LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/sample-functions-framework-node
   ```

   ### Python

   ```sh
   gcloud builds submit --pack image=LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/sample-functions-framework-python
   ```

   ### Ruby

   ```sh
   gcloud builds submit --pack image=LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/sample-functions-framework-ruby
   ```

   Replace:
   - `LOCATION` with the region name of your container repository. Example: `us-west2-docker.pkg.dev`
   - `PROJECT_ID` with the ID of your Google Cloud project.
   - `REPO_NAME` with the name of your Docker repository.

   <br />

4. Verify that the sample function was successfully published into `REPO_NAME`:

   ```bash
   gcloud artifacts docker images list LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME
   ```

   Replace:
   - `LOCATION` with the region name of your container repository, for example, `us-west2`.
   - `PROJECT_ID` with the ID of your Google Cloud project.
   - `REPO_NAME` with the name of your Docker repository.

## What's Next

- Deploy your function image to [Cloud Run](https://docs.cloud.google.com/run/docs/deploying).
- [Set environment variables](https://docs.cloud.google.com/docs/buildpacks/set-environment-variables).
- [Configure build images](https://docs.cloud.google.com/docs/buildpacks/build-run-image).
- [Speed up builds with cache images](https://docs.cloud.google.com/docs/buildpacks/cache-images).