Yandex Cloud
Search
Contact UsGet started
  • Blog
  • Pricing
  • Documentation
  • All Services
  • System Status
    • Featured
    • Infrastructure & Network
    • Data Platform
    • Containers
    • Developer tools
    • Serverless
    • Security
    • Monitoring & Resources
    • ML & AI
    • Business tools
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Customer Stories
    • Gateway to Russia
    • Cloud for Startups
    • Education and Science
  • Blog
  • Pricing
  • Documentation
Yandex project
© 2025 Yandex.Cloud LLC
Tutorials
    • All tutorials
    • URL shortener
    • Entering data into storage systems
    • Storing application runtime logs
    • Deploying a web application using the Java Servlet API
    • Developing a Slack bot
    • Developing a Telegram bot
    • Developing a custom integration in API Gateway
    • Developing CRUD APIs for movie services
    • Building a CI/CD pipeline in GitLab
    • Working with an API gateway via WebSocket
    • Creating an interactive serverless application using WebSocket
    • Automatically copying objects from one Object Storage bucket to another
    • Visualizing logs in Grafana using the Cloud Logging plugin
    • Canary release of a Cloud Functions function
    • Interactive debugging of Cloud Functions functions
    • Creating a Node.js function using TypeScript
    • Running a containerized app in Serverless Containers
    • Streaming Yandex Cloud Postbox events to Data Streams and analyzing them using DataLens
    • Using API Gateway to set up speech synthesis in SpeechKit
    • Connecting to YDB from a Cloud Functions function in Python
    • Connecting to a YDB database from a Cloud Functions function in Node.js
    • API Gateway protection with Smart Web Security
    • Deploying a web app with JWT authorization in API Gateway and authentication in Firebase
    • Automatic data upload to Yandex SpeechSense using Yandex Workflows
    • Configuring responses in Cloud Logging and Yandex Cloud Functions
    • Setting up Workflows integration with Tracker, YandexGPT, and Yandex Cloud Postbox
    • Developing functions in Functions Framework and deploying them to Yandex Serverless Containers

In this article:

  • Getting started
  • Required paid resources
  • Set up your environment
  • Create a service account
  • Create a registry in Container Registry
  • Create a function
  • Create a Docker image and push it to the registry in Container Registry
  • Create a container in Serverless Containers from the uploaded Docker image
  • Test the function in the container
  • How to delete the resources you created
  1. Serverless technologies
  2. Developing functions in Functions Framework and deploying them to Yandex Serverless Containers

Developing functions in Functions Framework and deploying them in Yandex Serverless Containers

Written by
Yandex Cloud
Updated at May 7, 2025
  • Getting started
    • Required paid resources
    • Set up your environment
  • Create a service account
  • Create a registry in Container Registry
  • Create a function
  • Create a Docker image and push it to the registry in Container Registry
  • Create a container in Serverless Containers from the uploaded Docker image
  • Test the function in the container
  • How to delete the resources you created

The Google Cloud Functions Framework is an open contract implemented as open-source libraries for multiple programming languages. The framework allows you to develop functions under the FaaS (Funciton as a service) model, capable of processing HTTP requests or CloudEvents.

With the Functions Framework, you can write and run functions in Yandex Serverless Containers containers without using Yandex Cloud Functions. Functions written this way can be migrated across different platforms, such as Cloud Run, Cloud Run functions, Knative, and Yandex Serverless Containers, as well as between these platforms and your local development machine.

This tutorial presents a use case where you will locally create a function using the Functions Framework. You will then build a Docker image from this function and upload it to a registry in Yandex Container Registry. Using the Docker image stored in the registry, you will create a container in Serverless Containers that will run your function code when invoked.

This solution enables you to:

  • Build and distribute functions as OCI-compatible Docker images and deploy them on various cloud and on-premises platforms, such as Kubernetes, Cloud Run, Knative, etc.
  • Develop, run locally, debug, and test functions as standard web applications using modern IDEs.
  • Migrate your functions from Cloud Run functions or Knative while maintaining compatibility with these platforms.
  • Create functions in Dart, C++, or Ruby, which are currently not supported in Cloud Functions.

In this tutorial, you will create a test function. For the complete list of supported programming languages, see the Functions Framework GitHub repository.

To deploy a function in Serverless Containers:

  1. Get your cloud ready.
  2. Create a service account.
  3. Create a registry in Container Registry.
  4. Create a function.
  5. Create a Docker image and push it to the registry in Container Registry.
  6. Create a container in Serverless Containers from the uploaded Docker image.
  7. Test the function in the container.

If you no longer need the resources you created, delete them.

Getting startedGetting started

Sign up in Yandex Cloud and create a billing account:

  1. Navigate to the management console and log in to Yandex Cloud or register a new account.
  2. On the Yandex Cloud Billing page, make sure you have a billing account linked and it has the ACTIVE or TRIAL_ACTIVE status. If you do not have a billing account, create one and link a cloud to it.

If you have an active billing account, you can navigate to the cloud page to create or select a folder for your infrastructure to operate in.

Learn more about clouds and folders.

Required paid resourcesRequired paid resources

The cost of the web service infrastructure support includes:

  • Fee for using the storage, amount of outgoing traffic, and using the Container Registry vulnerability scanner (see the Yandex Container Registry pricing).
  • Fee for using Serverless Containers (see Yandex Serverless Containers pricing).

Set up your environmentSet up your environment

  1. Install cURL.

  2. Install and configure the Yandex Cloud CLI.

  3. Install and configure Docker.

  4. Get authenticated in Container Registry.

  5. Install Pack. To do this, run these commands in the terminal and wait for the installation to complete:

    sudo add-apt-repository ppa:cncf-buildpacks/pack-cli -y
    sudo apt install pack-cli -y
    

    Here we provide the Pack installation guide for Linux Ubuntu. If you are using a different OS, see the Pack tutorials with installation instructions.

Create a service accountCreate a service account

Management console
CLI
API
  1. In the management console, select the folder where you are going to create your infrastructure.
  2. From the list of services, select Identity and Access Management.
  3. Click Create service account, and in the window that opens:
    1. Enter a name for the service account: serverless-containers-sa.
    2. Click Add role and select the container-registry.images.puller role.
    3. Click Create.

The folder specified when creating the CLI profile is used by default. To change the default folder, use the yc config set folder-id <folder_ID> command. You can specify a different folder using the --folder-name or --folder-id parameter.

  1. Create a service account named serverless-containers-sa:

    yc iam service-account create \
      --name serverless-containers-sa
    

    Result:

    done (1s)
    id: aje7tnmd885t********
    folder_id: b1gt6g8ht345********
    created_at: "2025-02-14T11:09:54.376880905Z"
    name: serverless-containers-sa
    

    Save the service account ID (the id field value) and the folder ID (the folder_id field value), you will need them in the next step.

    For more information about the yc iam service-account create command, see the CLI reference.

  2. Assign the container-registry.images.puller role for the folder to the created service account by specifying the folder and service account IDs you saved in the previous step:

    yc resource-manager folder add-access-binding <folder_ID> \
      --role container-registry.images.puller \
      --subject serviceAccount:<service_account_ID>
    

    Result:

    done (2s)
    effective_deltas:
      - action: ADD
        access_binding:
         role_id: container-registry.images.puller
          subject:
            id: aje7tnmd885t********
            type: serviceAccount
    

    For more information about the yc resource-manager folder add-access-binding command, see the CLI reference.

To create a service account, use the create REST API method for the ServiceAccount resource or the ServiceAccountService/Create gRPC API call.

To assign the service account a role for the folder, use the updateAccessBindings REST API method for the Folder resource or the FolderService/UpdateAccessBindings gRPC API call.

Create a registry in Container RegistryCreate a registry in Container Registry

Management console
CLI
API
  1. In the management console, select the folder you used to create the service account in.
  2. From the list of services, select Container Registry.
  3. Click Create registry.
  4. In the Name field, enter the registry name: functions-framework-registry.
  5. Click Create registry.
  6. On the page that opens, copy the ID of the created registry, you will need it later.

Create the functions-framework-registry registry:

yc container registry create \
  --name functions-framework-registry

Result:

done (1s)
id: crpfn9p374a3********
folder_id: b1gt6g8ht345********
name: functions-framework-registry
status: ACTIVE
created_at: "2025-02-14T11:44:23.698Z"

Save the ID (the id field value) of the created registry, you will need it later.

For more information about the yc container registry create command, see the CLI reference.

To create a registry, use the create method for the Registry resource or the RegistryService/Create gRPC API call.

Create a functionCreate a function

At this stage, you will locally create a function using the Functions Framework. Here we provide the package installation commands for Linux Ubuntu. If you are using a different OS, see the relevant tutorials for installation instructions.

Node.js
Python
Go

To create a function in Node.js:

  1. Install the npm package manager:

    sudo apt update && \
    sudo apt install npm -y
    
  2. Create a directory for the new project:

    mkdir my-first-function && \
    cd my-first-function
    
  3. Initialize your project:

    npm init
    

    During initialization, leave all requested values at their defaults by pressing ENTER. At the end, when you get the Is this OK? promt, type yes and press Enter. This will create the package.json project file in your project directory.

    {
      "name": "my-first-function",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC"
    }
    
  4. Create a new index.js file by opening it in the text editor:

    nano index.js
    
  5. Add this code to the index.js file:

    const functions = require('@google-cloud/functions-framework');
    
    functions.http('helloWorld', (req, res) => {
      res.send('Hello, World!');
    });
    
  6. Install the Functions Framework in your project:

    npm install @google-cloud/functions-framework
    
  7. Add this code to the package.json file:

    "scripts": {
      "start": "functions-framework --target=helloWorld"
    }
    

    Example of the final package.json contents:

    {
      "name": "my-first-function",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "@google-cloud/functions-framework": "^3.4.5"
      },
      "scripts": {
        "start": "functions-framework --target=helloWorld"
      }
    }
    
  8. Run your function locally to make sure everything works correctly:

    1. Run the function:

      npm start
      

      Result:

      > my-first-function@1.0.0 start
      > functions-framework --target=helloWorld
      
      Serving function...
      Function: helloWorld
      Signature type: http
      URL: http://localhost:8080/
      
    2. Open an additional terminal window and run the following command in it:

      curl http://localhost:8080/
      

      Result:

      Hello, World!
      

    This way, you can also run a function in debug mode and use breakpoints with modern IDEs.

To create a function in Python:

  1. Install Python and pip:

    sudo apt update && \
    sudo apt install python3 python3-pip -y
    
  2. Create a directory for the new project:

    mkdir my-first-function && \
    cd my-first-function
    
  3. Install the Functions Framework:

    sudo pip install functions-framework
    
  4. Create the main.py file with the function code by opening it in the text editor:

    nano main.py
    
  5. Add this code to the main.py file:

    import flask
    import functions_framework
    
    @functions_framework.http
    def helloWorld(request: flask.Request) -> flask.typing.ResponseReturnValue:
        return "Hello, World!"
    
  6. Run your function locally to make sure everything works correctly:

    1. Run the function:

      functions-framework --target helloWorld --debug
      

      Result:

      * Serving Flask app 'hello'
      * Debug mode: on
      WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
      * Running on all addresses (0.0.0.0)
      * Running on http://127.0.0.1:8080
      * Running on http://192.168.1.15:8080
      Press CTRL+C to quit
      * Restarting with watchdog (inotify)
      * Debugger is active!
      * Debugger PIN: 817-187-***
      
    2. Open an additional terminal window and run the following command in it:

      curl http://localhost:8080/
      

      Result:

      Hello, World!
      

    This way, you can also run a function in debug mode and use breakpoints with modern IDEs.

To create a function in Go:

  1. Install Go 1.18 or higher.

  2. Create a directory for the new project:

    mkdir my-first-function && \
    cd my-first-function
    
  3. Create a new module:

    go mod init example.com/helloWorld
    
  4. Create the function.go file with the function code by opening it in the text editor:

    nano function.go
    
  5. Add this code to the function.go file:

    package function
    
    import (
      "fmt"
      "net/http"
    
      "github.com/GoogleCloudPlatform/functions-framework-go/functions"
    )
    
    func init() {
      functions.HTTP("helloWorld", helloWorld)
    }
    
    // helloWorld writes "Hello, World!" to the HTTP response.
    func helloWorld(w http.ResponseWriter, r *http.Request) {
      fmt.Fprintln(w, "Hello, World!")
    }
    
  6. Run your function locally to make sure everything works correctly:

    1. Create a directory named cmd:

      mkdir cmd
      
    2. In the cmd directory, create a file named main.go:

      nano cmd/main.go
      
    3. Add this code to the main.go file:

      package main
      
      import (
        "log"
        "os"
      
        // Blank-import the function package so the init() runs
        _ "example.com/helloWorld"
        "github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
      )
      
      func main() {
        // Use PORT environment variable, or default to 8080.
        port := "8080"
        if envPort := os.Getenv("PORT"); envPort != "" {
          port = envPort
        }
        
        // By default, listen on all interfaces. If testing locally, run with 
        // LOCAL_ONLY=true to avoid triggering firewall warnings and 
        // exposing the server outside of your own machine.
        hostname := ""
        if localOnly := os.Getenv("LOCAL_ONLY"); localOnly == "true" {
          hostname = "127.0.0.1"
        } 
        if err := funcframework.StartHostPort(hostname, port); err != nil {
          log.Fatalf("funcframework.StartHostPort: %v\n", err)
        }
      }
      
    4. Update the dependencies:

      go mod tidy
      
    5. Start your local server:

      FUNCTION_TARGET=helloWorld \
      LOCAL_ONLY=true \
      go run cmd/main.go
      
    6. Open an additional terminal window and run the following command in it:

      curl http://localhost:8080/
      

      Result:

      Hello, World!
      

    This way, you can also run a function in debug mode and use breakpoints with modern IDEs.

Create a Docker image and push it to the registry in Container RegistryCreate a Docker image and push it to the registry in Container Registry

The function is built using Buildpacks and builders provided by GCP. You can also use builders provided by Heroku.

  1. Use Pack, which you installed earlier, to build a Docker image with your app:

    sudo pack build \
     --builder gcr.io/buildpacks/builder:google-22 \
     --env GOOGLE\_FUNCTION\_SIGNATURE\_TYPE=http \
     --env GOOGLE\_FUNCTION\_TARGET=helloWorld \
     my-first-function
    

    To additionally configure the container build, e.g., add other packages or dependencies, use this guide.

    Result:

    ...
    Successfully built image my-first-function
    

    You can use the above build command for functions written in different programming languages. The builder will automatically detect the project's language and runtime environment and then build the application into an OCI-compatible Docker image. This way, developers do not need to create a Dockerfile manually.

  2. Run the container locally from the Docker image to make sure everything works correctly:

    1. Run this command:

      docker run --rm -p 8080:8080 my-first-function
      
    2. Open an additional terminal window and run the following command in it:

      curl http://localhost:8080/
      

      Result:

      Hello, World!
      

      The function code is running in the locally launched Docker container.

    3. Close the additional terminal window. Stop the running Docker container from the main terminal window by pressing Ctrl + C.

  3. Assign an URL to the Docker image in the cr.yandex/<registry_ID>/<Docker_image_name>:<tag> format and specify the previously saved ID of the registry from Container Registry.

    docker tag my-first-function \
      cr.yandex/<registry_ID>/my-first-function:some-tag
    

    Note

    To push Docker images to Container Registry, you need to assign them URLs in this format: cr.yandex/<registry_ID>/<Docker_image_name>:<tag>.

  4. Push the Docker image to the registry:

    docker push \
      cr.yandex/<registry_ID>/my-first-function:some-tag
    

    Result:

    The push refers to repository [cr.yandex/crpfn9p374a3********/my-first-function]
    ...
    14f9fd9947d2: Pushed
    2573e0d81582: Pushed
    some-tag: digest: sha256:1b8bac8da5e64dd4359f81d71a7803f212af385f9718a7a4f9a40bca******** size: 2830
    

Create a container in Serverless Containers from the uploaded Docker imageCreate a container in Serverless Containers from the uploaded Docker image

Use the Docker image uploaded to Container Registry to create a Serverless Containers container revision.

Management console
CLI
API
  1. In the management console, select the folder containing the resources you created previously.

  2. From the list of services, select Serverless Containers.

  3. Click Create container.

  4. In the Name field, specify the container name: my-first-function.

  5. Click Create.

  6. Under Image settings, in the Image URL field, select the previously uploaded Docker image, cr.yandex/<registry_ID>/my-first-function:some-tag.

  7. Under Settings, in the Service account field, select the previously created service account. serverless-containers-sa.

  8. Under Logging, disable Write logs to opt out of writing logs to the log group.

    You can leave this option enabled if you prefer to write container execution logs. You will be charged for writing and storing logs.

  9. Click Create revision.

  10. In the window that opens, under General information, copy the Link to invoke value; you will need this URL to test function in the container.

  1. Create a my-first-function container:

    yc serverless container create \
      --name my-first-function
    

    Result:

    done (1s)
    id: bba0tc5nv6j0********
    folder_id: b1gt6g8ht345********
    created_at: "2025-02-14T15:26:04.744Z"
    name: my-first-function
    url: https://bba0tc5nv6j0********.containers.yandexcloud.net/
    status: ACTIVE
    

    Save the container invocation url, you will need it to test function in the container.

    For more information about the yc serverless container create command, see the CLI reference.

  2. Create a revision of the container you created previously:

    yc serverless container revision deploy \
      --container-name my-first-function \
      --image "cr.yandex/<registry_ID>/my-first-function:some-tag" \
      --service-account-id <service_account_ID> \
      --no-logging
    

    Where:

    • <registry_ID>: ID of the Container Registry registry you saved in the previous step.
    • <service_account_ID>: ID of the serverless-containers-sa service account you saved in the previous step.
    • --no-logging: Disables writing logs to the log group. Remove this parameter from the command to write container execution logs. You will be charged for writing and storing logs.

    Result:

    done (16s)
    id: bba6f1jllc3t********
    container_id: bbakbil5lg7j********
    created_at: "2025-02-14T20:48:06.424Z"
    image:
      image_url: cr.yandex/crpfn9p374a3********/my-first-function:some-tag
      image_digest: sha256:1b8bac8da5e64dd4359f81d71a7803f212af385f9718a7a4f9a40bca********
    resources:
      memory: "134217728"
      cores: "1"
      core_fraction: "100"
    execution_timeout: 3s
    concurrency: "1"
    service_account_id: aje7tnmd885t********
    status: ACTIVE
    log_options:
      disabled: true
      folder_id: b1gt6g8ht345********
    runtime:
      http: {}
    

    For more information about the yc serverless container revision deploy command, see the CLI reference.

To create a container, use the create REST API method for the Container resource or the ContainerService/Create gRPC API call.

To create a container revision, use the deployRevision REST API method for the Container resource or the ContainerService/DeployRevision gRPC API call.

Test the function in the containerTest the function in the container

After creating the container, you got the invocation link. To test the function in the container, use this link in the following request:

curl \
  --request GET \
  --header "Authorization: Bearer $(yc iam create-token)" \
  <container_invocation_link>

Result:

Hello, World%

By invoking the container, you ran the code of my-first-function you created earlier with the Functions Framework.

How to delete the resources you createdHow to delete the resources you created

To stop paying for the resources you created:

  1. Delete the Serverless Containers container.
  2. Delete the Docker image from the registry in Container Registry and then delete the registry.
  3. If you did not disable writing container execution logs, delete the log group.

Was the article helpful?

Previous
Setting up Workflows integration with Tracker, YandexGPT, and Yandex Cloud Postbox
Next
Overview
Yandex project
© 2025 Yandex.Cloud LLC