[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Serverless technologies](index.md) > Serverless-based workflows and automation > Setting up CI/CD in SourceCraft to deploy an application in Serverless Containers using GitHub Actions

# Setting up CI/CD in SourceCraft to deploy an application in Yandex Serverless Containers using GitHub Actions

# Setting up CI/CD to deploy an application to Yandex Serverless Containers using GitHub Actions


In this tutorial, you will set up a [CI/CD process](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/ci-cd) to deploy a containerized application to [Serverless Containers](../../serverless-containers/concepts/index.md) from a SourceCraft [repository](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/#repos) using [GitHub Actions](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/gh-actions). The integration between SourceCraft and Yandex Cloud will be implemented using a [service connection](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/service-connections).

{% note warning %}

To create a service connection, you need the `Organization owner` (`organization-manager.organizations.owner`) [role](https://sourcecraft.dev/portal/docs/en/sourcecraft/security/#organization-manager-organizations-owner).

{% endnote %}

To set up CI/CD to deploy an application to Serverless Containers from aSourceCraft repository using GitHub Actions:
1. [Create a service account](#create-sa).
1. [Create a registry](#create-registry).
1. [Create a repository](#create-repository-sc).
1. [Create a service connection](#create-service-connection).
1. [Configure CI/CD](#config-ci-cd).
1. [Test CI/CD](#check-ci-cd).
1. [Make sure the container has been created](#check-result).

If you no longer need the resources you created, [delete them](#clear-out).

### Required paid resources {#paid-resources}

The infrastructure support cost includes:
* Fee for storing the created Docker images (see [Container Registry pricing](../../container-registry/pricing.md).
* Fee for the container invocation count, computing resources allocated for the application, and outgoing traffic (see [Serverless Containers pricing](../../serverless-containers/pricing.md).

## Create a service account {#create-sa}

You will use this [service account](../../iam/concepts/users/service-accounts.md) to push Docker images to [registries](../../container-registry/concepts/registry.md) in Yandex Container Registry and deploy [containers](../../serverless-containers/concepts/container.md) to Serverless Containers.

{% list tabs group=instructions %}

- Management console {#console}

  1. Log in to the Yandex Cloud [management console](https://console.yandex.cloud).
  1. On the left side of the screen, click the line with the name of the folder where you want to deploy your container.
  1. [Navigate](../../console/operations/select-service.md#select-service) to **Identity and Access Management**.
  1. Click **Create service account**.
  1. In the **Name** field, specify `github-action`.
  1. Click ![image](../../_assets/console-icons/plus.svg) **Add role** and select these roles:

      * `container-registry.images.pusher`: To work with Docker images in the registry.
      * `serverless-containers.editor`: To manage the container.
      * `iam.serviceAccounts.user`: To enable specifying a service account when creating a container revision. This account will be used to pull the Docker image from the registry.

  1. Click **Create**.

- CLI {#cli}

  1. Create a service account:

      ```bash
      yc iam service-account create \
        --name github-action
        --folder-name <folder_name>
      ```

      Result:

      ```yaml
      id: ajeab0cnib1p********
      folder_id: b0g12ga82bcv********
      created_at: "2025-10-03T09:44:35.989446Z"
      name: github-action
      ```

  1. Assign the service account the following [roles](../../iam/concepts/access-control/roles.md) for the folder:

      * `iam.serviceAccounts.user`: To enable specifying a service account when creating a container revision. This account will be used to pull the Docker image from the registry:

        ```bash
        yc resource-manager folder add-access-binding <folder_name> \
          --service-account-name github-action \
          --role iam.serviceAccounts.user \
          --folder-name <folder_name>
        ```

      * `serverless-containers.editor`: To manage the container:

        ```bash
        yc resource-manager folder add-access-binding <folder_name> \
          --service-account-name github-action \
          --role serverless-containers.editor \
          --folder-name <folder_name>
        ```

      * `container-registry.images.pusher`: To work with Docker images in the registry:

        ```bash
        yc resource-manager folder add-access-binding <folder_name> \
          --service-account-name github-action \
          --role container-registry.images.pusher \
          --folder-name <folder_name>
        ```

- API {#api}

  1. Create a service account named `github-action`. Do it by using the [create](../../iam/api-ref/ServiceAccount/create.md) REST API method for the [ServiceAccount](../../iam/api-ref/ServiceAccount/index.md) resource or the [ServiceAccountService/Create](../../iam/api-ref/grpc/ServiceAccount/create.md) gRPC API call.
  1. Assign the service account these [roles](../../iam/concepts/access-control/roles.md) for the current folder:

      * `iam.serviceAccounts.user`: To enable specifying a service account when creating a container revision. This account will be used to pull the Docker image from the registry.
      * `serverless-containers.editor`: To manage the container.
      * `container-registry.images.pusher`: To work with Docker images in the registry.

      Do it by using the [setAccessBindings](../../resource-manager/api-ref/Folder/setAccessBindings.md) REST API method for the [Folder](../../resource-manager/api-ref/Folder/index.md) resource or the [FolderService/SetAccessBindings](../../resource-manager/api-ref/grpc/Folder/setAccessBindings.md) gRPC API call.

{% endlist %}

## Create a registry {#create-registry}

The registry in Container Registry will house the application’s Docker image.

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select **Container Registry**.
  1. Click **Create registry**.
  1. Specify `github-action` as the registry name.
  1. Click **Create registry**.
  1. Save the new registry’s ID, as you will need it later.

- CLI {#cli}

  Create a registry named `github-action`:

  ```bash
  yc container registry create --name github-action
  ```

  Result:

  ```text
  id: crpd50616s9a********
  folder_id: b1g88tflru0e********
  name: github-action
  status: ACTIVE
  created_at: "2025-10-03T10:34:06.601Z"
  ```

  Save the new registry’s ID, as you will need it later.

- API {#api}

  Use the [create](../../container-registry/api-ref/Registry/create.md) REST API method for the [Registry](../../container-registry/api-ref/Registry/index.md) resource or the [RegistryService/CreateRegistryRequest](../../container-registry/api-ref/grpc/Registry/create.md) gRPC API call.

  Save the new registry’s ID, as you will need it later.

{% endlist %}

## Create a repository {#create-repository-sc}

The repository will be created from the [yc-ci-cd-serverless](https://sourcecraft.dev/sourcecraft/yc-ci-cd-serverless) template and store the `Dockerfile`, auxiliary files for creating the Docker image, and the CI/CD process settings.

{% list tabs group=instructions %}

- SourceCraft UI {#src}

  1. Open the [service home page](https://sourcecraft.dev).
  1. In the left-hand panel, click ![image](../../_assets/console-icons/plus.svg) **Create repository**.
  1. In the window that opens, select **Blank repository**.
  1. Under **Your new repository details**:
      * In the **Owner** field, select the [organization](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/#org) in which you created the Yandex Cloud service account.
      * In the **Name** field, specify a name for the repository. 

        The name must be unique within the organization and can include the following [ASCII characters](https://ru.wikipedia.org/wiki/ASCII): lowercase and uppercase Latin letters, numbers, commas, hyphens, and underscores.

        The repository’s address is displayed below its name.

      * Optionally, in the **Description** field, enter a description for the repository.

  1. Under **Repository template**, click **Browse templates**, select the [yc-ci-cd-serverless](https://sourcecraft.dev/sourcecraft/yc-ci-cd-serverless) template, and click **Use template**.

      To view the template contents, click **Preview**.

      The template contains:
      * [.sourcecraft/ci.yaml](https://sourcecraft.dev/sourcecraft/yc-ci-cd-serverless/browse/.sourcecraft/ci.yaml) file with a pre-installed configuration of the CI/CD process that runs when a commit is created and does the following:
        * Obtains a Yandex Cloud IAM token using a service connection named `default-service-connection`.
        * Installs [Docker Buildx](https://github.com/docker/buildx) in the [worker](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/ci-cd#workers) environment using the [Docker Setup Buildx](https://github.com/marketplace/actions/docker-setup-buildx) GitHub Action.
        * Authenticates with Container Registry using the [Docker Login](https://github.com/marketplace/actions/docker-login) GitHub Action and the Yandex Cloud IAM token.
        * Builds a Docker image from the `Dockerfile` located at the repository root and pushes it to Container Registry using the [Build and Push Docker images](https://github.com/marketplace/actions/build-and-push-docker-images) GitHub Action.
        * Deploys a container in Serverless Containers from the built Docker image.
      * [Dockerfile](https://sourcecraft.dev/sourcecraft/yc-ci-cd-serverless/browse/Dockerfile), [index.html](https://sourcecraft.dev/sourcecraft/yc-ci-cd-serverless/browse/index.html), and [docker/nginx/conf.d/default.conf](https://sourcecraft.dev/sourcecraft/yc-ci-cd-serverless/browse/docker/nginx/conf.d/default.conf) with the configuration of a container with a static web app based on [Nginx](https://nginx.org/en/).

  1. Click **Create repository**.

{% endlist %}

## Create a service connection {#create-service-connection}

{% list tabs group=instructions %}

- SourceCraft UI {#src}

  1. Open the SourceCraft [home page](https://sourcecraft.dev).
  1. Navigate to the ![image](../../_assets/console-icons/briefcase.svg) **Organizations** tab.
  1. Select the organization where you created the Yandex Cloud service account.
  1. On the organization page, under ![image](../../_assets/console-icons/gear.svg) **Settings**, go to the ![image](../../_assets/console-icons/cloud-nut-hex.svg) **Service connections** section.
  1. Click **New service connection**.
  1. Under **Basic information**, specify the service connection name: `default-service-connection`.
  1. Under **Scope**, select the repository you created earlier.
  1. Under **Yandex Cloud settings**, select:

      * Folder where you previously deployed the cloud infrastructure and assigned a role to the service account.
      * `github-action` service account.

        {% note tip %}
        
        To re-request the list of clouds, folders, and service accounts from Yandex Cloud, click ![image](../../_assets/console-icons/arrow-rotate-right.svg) **Synchronize**. This can be of use if alongside creating a service connection you also created a folder or service account.
        
        {% endnote %}

  1. Click **Create service connection**.

{% endlist %}

Wait for the operation to complete. The page that opens will display the service connection details.

A Yandex Identity and Access Management [workload identity federation](../../iam/concepts/workload-identity.md) will be automatically created in Yandex Cloud.

To view the parameters of the new OIDC provider, click the federation name under ![image](../../_assets/console-icons/cpus.svg) **Workload identity federation**.

{% note info %}

You can also create a service connection at the repository level. In this case, it will be available for that repository only. For more information, see [{#T}](https://sourcecraft.dev/portal/docs/en/sourcecraft/operations/service-connections#create-service-connection).

{% endnote %}

## Configure CI/CD {#config-ci-cd}

{% list tabs group=instructions %}

- SourceCraft UI {#src}

  1. Open the SourceCraft [home page](https://sourcecraft.dev).
  1. On the ![image](../../_assets/console-icons/house.svg) **Home** tab, under ![image](../../_assets/console-icons/layout-tabs.svg) **Your craftspace**, navigate to ![image](../../_assets/console-icons/archive.svg) **Repositories**.
  1. Select the repository you created earlier.
  1. Select `.sourcecraft/ci.yaml`.
  1. In the top-right corner, click ![image](../../_assets/console-icons/pencil.svg) **Edit**.
  1. In the `YC_DOCKER_REGISTRY_URI` parameter, specify the ID of the registry you [previously](#create-registry) created:

      ```yaml
      YC_DOCKER_REGISTRY_URI: cr.yandex/<registry_ID>
      ```

  1. In the top-right corner, click **Commit changes**.
  1. Make a commit:

      1. Enter a commit message.
      1. Under **Commit branch**, select **Commit directly to the branch: main**.
      1. Under **After commit action**, select **Just commit**.
      1. Click **Commit changes**.

{% endlist %}

After saving the changes, `demo-service-connection-workflow` will start.

## Test CI/CD {#check-ci-cd}

{% list tabs group=instructions %}

- SourceCraft UI {#src}

  1. Open the SourceCraft [home page](https://sourcecraft.dev).
  1. On the ![image](../../_assets/console-icons/house.svg) **Home** tab, under ![image](../../_assets/console-icons/layout-tabs.svg) **Your craftspace**, navigate to ![image](../../_assets/console-icons/archive.svg) **Repositories**.
  1. Select the repository you created earlier.
  1. Under ![image](../../_assets/console-icons/code.svg) **Code** on the repository page, go to ![image](../../_assets/console-icons/arrows-3-rotate-right.svg) **CI/CD**.
  1. In the list of automation executions, you will see a new execution. Wait for the status to change to ![image](../../_assets/console-icons/circle-check.svg) **Success**.

{% endlist %}

## Make sure the container has been created {#check-result}

{% list tabs group=instructions %}

- Management console {#console}

  1. Open the [management console](https://console.yandex.cloud).
  1. [Navigate](../../console/operations/select-service.md#select-service) to **Serverless Containers**.
  1. In the list, you should see `demo-serverless-container1`; select it.

      Under **Revisions**, you should now see the container revision with the same timestamp as the [CI/CD process execution](#check-ci-cd).

- CLI {#cli}

  Run this command:

  ```bash
  yc serverless container revision list \
    --container-name demo-serverless-container1
  ```

  Where `--container-name` is the container name specified in `.sourcecraft/ci.yaml`.

  Result:

  ```text
  +----------------------+----------------------+--------------------------------------------------------+---------------------+
  |          ID          |     CONTAINER ID     |                 IMAGE                                  |     CREATED AT      |
  +----------------------+----------------------+--------------------------------------------------------+---------------------+
  | bba27hejd69a******** | bba83i1mrb5s******** | cr.yandex/yc/serverless/demo-serverless-container1     | 2025-10-04 09:38:14 |
  +----------------------+----------------------+--------------------------------------------------------+---------------------+
  ```

- API {#api}

  Use the [listRevisions](../../serverless-containers/containers/api-ref/Container/listRevisions.md) REST API method for the [Container](../../serverless-containers/containers/api-ref/Container/index.md) resource or the [RegistryService/CreateRegistryRequest](../../serverless-containers/containers/api-ref/grpc/Container/listRevisions.md) gRPC API call.

{% endlist %}

## Delete the resources you created {#clear-out}

To stop paying for the resources you created:
1. [Delete](../../serverless-containers/operations/delete.md) the container.
1. [Delete](../../container-registry/operations/docker-image/docker-image-delete.md) the Docker image.
1. [Delete](../../container-registry/operations/registry/registry-delete.md) the registry.

## Useful links {#see-also}

* [Configuring CI/CD between SourceCraft and Yandex Cloud Functions](ci-cd-sourcecraft-functions.md)
* [Service connections](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/service-connections)
* [Configuring a service connection to Yandex Cloud](https://sourcecraft.dev/portal/docs/en/sourcecraft/operations/service-connections) in SourceCraft
* [Integration with GitHub Actions in SourceCraft](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/gh-actions)
* [Using GitHub Actions in SourceCraft CI/CD](https://sourcecraft.dev/portal/docs/en/sourcecraft/operations/gh-actions)
* [GitLab pipelines in SourceCraft CI/CD](https://sourcecraft.dev/portal/docs/en/sourcecraft/concepts/gl-pipelines)
* [Using a GitLab pipeline in the SourceCraft](https://sourcecraft.dev/portal/docs/en/sourcecraft/operations/gl-pipelines) CI/CD
* [serverless-functions repository in SourceCraft](https://sourcecraft.dev/yandex-cloud-examples/serverless-functions)
* [yc-ci-cd-serverless repository in SourceCraft](https://sourcecraft.dev/sourcecraft/yc-ci-cd-serverless)