Yandex Cloud
Search
Contact UsGet started
  • Pricing
  • Customer Stories
  • Documentation
  • Blog
  • All Services
  • System Status
    • Featured
    • Infrastructure & Network
    • Data Platform
    • Containers
    • Developer tools
    • Serverless
    • Security
    • Monitoring & Resources
    • AI for business
    • Business tools
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Start testing with double trial credits
    • Cloud credits to scale your IT product
    • Gateway to Russia
    • Cloud for Startups
    • Center for Technologies and Society
    • Yandex Cloud Partner program
  • Pricing
  • Customer Stories
  • Documentation
  • Blog
© 2025 Direct Cursus Technology L.L.C.
Tutorials
    • All tutorials
    • URL shortener
    • Ingesting 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 Telegram bot with AI agent support
    • Developing a custom integration in API Gateway
    • Developing CRUD APIs for movie services
    • Building a CI/CD pipeline in GitLab
    • GitLab Runner execution in Serverless Containers
    • Configuring CI/CD between Cloud Functions and SourceCraft
    • Configuring CI/CD between Cloud Functions and GitHub
    • Setting up CI/CD in SourceCraft to deploy an application in Serverless Containers using GitHub Actions
    • Working with an API gateway via WebSocket
    • Building 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 Cloud Functions
    • Interactive debugging of Cloud 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 with 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
    • Creating a Yandex Cloud Postbox address and checking domain ownership with Terraform
    • Creating an AI agent with Yandex Cloud Functions
    • Configuring Postfix to send emails via Yandex Cloud Postbox
    • Yandex Cloud Postbox integration with external systems via webhooks

In this article:

  • How it works
  • Get your cloud ready
  • Required paid resources
  • Create GitLab Runner and get a token
  • Create a secret
  • Create service accounts
  • Create the service account API key
  • Create a container
  • Set up a webhook in GitLab
  • How to delete the resources you created
  1. Serverless technologies
  2. GitLab Runner execution in Serverless Containers

Starting GitLab Runner in Yandex Serverless Containers

Written by
Yandex Cloud
Updated at November 10, 2025
  • How it works
  • Get your cloud ready
    • Required paid resources
  • Create GitLab Runner and get a token
  • Create a secret
  • Create service accounts
  • Create the service account API key
  • Create a container
  • Set up a webhook in GitLab
  • How to delete the resources you created

In this tutorial, you will learn to start GitLab Runner in Yandex Cloud using Yandex Serverless Containers.

To start GitLab Runner in Serverless Containers:

  1. Get your cloud ready.
  2. Create GitLab Runner and get a token.
  3. Create a secret.
  4. Create service accounts.
  5. Create the service account API key.
  6. Create a container.
  7. Set up a webhook in GitLab.

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

How it worksHow it works

Once a job is created, GitLab sends a webhook request to the new Serverless Containers container. The container runs based on a public image from Yandex Container Registry and gets the necessary secrets from Yandex Lockbox. GitLab Runner deploys inside the container, connects to GitLab and takes the job for execution, runs it in an isolated Docker container, and shuts down when done. This approach eliminates the need to keep VMs running continuously: you pay only for actual job execution time.

You can check the source code in the SourceCraft repository.

Key steps

  • The service receives HTTP requests on port PORT (8080 by default) and at WEBHOOK_PATH (/ by default).

  • If necessary, it checks the secret in the X-Gitlab-Token header using the GITLAB_SECRET environment variable.

  • The only requests that are processed are those headed X-Gitlab-Event: Job Hook.

  • The build_status field is extracted from the request body. If it is set to pending, the service runs this command:

    gitlab-runner run-single \
      --url CI_SERVER_URL \
      --token RUNNER_TOKEN \
      --wait-timeout WAIT_TIMEOUT \
      --executor docker \
      --docker-privileged \
      --max-builds MAX_BUILDS
    
  • When running a container, the service also does the following:

    • If needed, mounts cgroup v2.
    • Prepares the /run and /var/lib/docker folders.
    • Starts the built-in dockerd and waits till it is ready (DOCKERD_READY_TIMEOUT).

How it works inside the container

Inside the container, the service starts an HTTP server and a GitLab Runner process, which then takes a new CI/CD job from GitLab and executes it in separate isolated docker containers.

Environment variables

The service uses the following environment variables:

Variable By default Required Description
RUNNER_TOKEN — Yes GitLab Runner token (project/group/instance)
CI_SERVER_URL https://gitlab.com No GitLab CI address
PORT 8080 No HTTP port
WEBHOOK_PATH / No Webhook endpoint path
GITLAB_SECRET — No Secret for checking the X-Gitlab-Token header
WAIT_TIMEOUT 10 No Value for gitlab-runner --wait-timeout, in seconds
MAX_BUILDS 1 No Value for gitlab-runner --max-builds
DOCKERD_READY_TIMEOUT 5s No Timeout until dockerd is ready (time.Duration)

Restrictions

  • This tutorial uses the Docker executor only. You can build a container yourself with required dependencies and use the Shell executor in it.
  • Each webhook request starts a separate ephemeral runner. The state between runners is not retained.
  • Jobs should have tags that match the runner’s tags. If a job in .gitlab-ci.yml has no matching tags, the runner will not take it. Use the Run untagged jobs option when creating a runner for it to take all jobs.

Get your cloud readyGet your cloud ready

Sign up for Yandex Cloud and create a billing account:

  1. Navigate to the management console and log in to Yandex Cloud or create 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.

Learn more about clouds and folders here.

Required paid resourcesRequired paid resources

The infrastructure support cost includes:

  • Fee for container invocation count, computing resources allocated to run the application, and outbound traffic (see Serverless Containers pricing).
  • Fee for storing secrets (see Yandex Lockbox pricing).

Create GitLab Runner and get a tokenCreate GitLab Runner and get a token

  1. Create a project in GitLab and open it.
  2. In the left-hand panel, select Settings → CI/CD.
  3. Open the Runners section and click Create project runner.
  4. In the Tags field, specify tags for the jobs for this runner to process.
  5. Click Create runner.
  6. Under Step 1, copy the runner authentication token and save it.

Create a secretCreate a secret

Create a Yandex Lockbox secret with the runner authentication token.

Management console
Yandex Cloud CLI
API
  1. In the management console, select the folder where you are going to create your infrastructure.

  2. In the list of services, select Lockbox.

  3. Click Create secret.

  4. In the Name field, specify the secret name: gitlab-runner-token.

  5. Under Secret data:

    1. Select the Custom secret type.

    2. Add the GitLab Runner token value:

      • In the Key field, specify gitlab_runner_token.
      • In the Value field, specify the runner authentication token you got earlier.
  6. Click Create.

If you do not have the Yandex Cloud CLI installed yet, install and initialize it.

By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the yc config set folder-id <folder_ID> command. You can also set a different folder for any specific command using the --folder-name or --folder-id parameter.

To create a secret, run this command:

yc lockbox secret create \
  --name gitlab-runner-token \
  --payload '[{"key": "gitlab_runner_token", "text_value": "<runner_token>"}]'

Where:

  • --name: Secret name.
  • --payload: Contents of the secret provided as a YAML or JSON array.
  • <runner_token>: Runner authentication token you got earlier.

Result:

id: e6qdur7h55vd********
folder_id: b1g681qpemb4********
created_at: "2025-09-16T06:04:12.604Z"
name: gitlab-runner-token
status: ACTIVE
current_version:
  id: e6qbaf927irb********
  secret_id: e6qdur7h55vd********
  created_at: "2025-09-16T06:04:12.604Z"
  status: ACTIVE
  payload_entry_keys:
    - gitlab_runner_token

To create a secret, use the create REST API method for the Secret resource or the SecretService/Create gRPC API call.

Create service accountsCreate service accounts

Create two service accounts:

  • gitlab-runner-lockbox-payload-viewer with the lockbox.payloadViewer role for access to the Lockbox secret.

  • gitlab-runner-caller with the serverless-containers.containerInvoker role for the folder. This service account will perform these two functions:

    • GitLab will use it to invoke the container. The API key will be specified in the Authorization header.
    • GitLab will use its ID to set jobs for the runner for the container to be invoked asynchronously. The ID will be provided when creating a container revision.

    You can split these two functions between two different service accounts as needed.

Management console
Yandex Cloud CLI
API
  1. In the management console, select Identity and Access Management.

  2. Click Create service account.

  3. Enter a name for the service account: gitlab-runner-caller.

  4. Click Add role and select serverless-containers.containerInvoker.

  5. Click Create.

  6. Similarly, create the gitlab-runner-lockbox-payload-viewer service account without assigning a role to it.

  7. Assign a role for the secret to the gitlab-runner-lockbox-payload-viewer service account:

    1. In the management console, select Lockbox.
    2. Select the gitlab-runner-token secret.
    3. In the left-hand panel, select Access bindings.
    4. Click Assign roles.
    5. Find and select the gitlab-runner-lockbox-payload-viewer service account.
    6. Click Add role and select lockbox.payloadViewer.
    7. Click Save.
  1. Create these service accounts:

    yc iam service-account create --name gitlab-runner-lockbox-payload-viewer
    yc iam service-account create --name gitlab-runner-caller
    

    Result:

    id: ajenprbpf1s3********
    folder_id: b1g681qpemb4********
    created_at: "2025-09-16T06:06:13.092790480Z"
    name: gitlab-runner-lockbox-payload-viewer
    
    id: ajetqjm00ji8********
    folder_id: b1g681qpemb4********
    created_at: "2025-09-16T06:06:15.661704808Z"
    name: gitlab-runner-caller
    
  2. Assign roles to the service accounts:

    yc lockbox secret add-access-binding \
      --name gitlab-runner-token \
      --role lockbox.payloadViewer \
      --service-account-name gitlab-runner-lockbox-payload-viewer
    
    yc resource-manager folder add-access-binding \
      --id <folder_ID> \
      --role serverless-containers.containerInvoker \
      --service-account-name gitlab-runner-caller
    

    Where:

    • --name: Secret name.
    • --id: Folder ID.
    • --role: Role being assigned.
    • --service-account-name: Service account name.

    Result:

    ...1s...done (4s)
    ...1s...done (2s)
    effective_deltas:
      - action: ADD
        access_binding:
          role_id: serverless-containers.containerInvoker
          subject:
            id: ajetqjm00ji8********
            type: serviceAccount
    

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 lockbox.payloadViewer role for a secret to the service account, use the updateAccessBindings REST API method for the Secret resource or the SecretService/UpdateAccessBindings gRPC API call.

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

Create the service account API keyCreate the service account API key

Create an API key for the service account you are going to use to invoke the container. You will need this API key to set up a webhook in GitLab.

Management console
CLI
API
  1. In the management console, select Identity and Access Management.
  2. Select the gitlab-runner-caller service account you created earlier.
  3. In the top panel, click Create new key and select Create API key.
  4. In the Scope field, select the yc.serverless.containers.invoke scope.
  5. Click Create.
  1. Create an API key for the gitlab-runner-caller service account:

    yc iam api-key create \
      --service-account-name gitlab-runner-caller \
      --scopes yc.serverless.containers.invoke
    

    Where:

    • --service-account-name: Service account name.
    • --scopes: Key scope.

    Result:

    api_key:
      id: aje3oa26mt52********
      service_account_id: ajetqjm00ji8********
      created_at: "2025-09-16T06:08:47.018697312Z"
      scope: yc.serverless.containers.invoke
      scopes:
        - yc.serverless.containers.invoke
    secret: AQVNw8KEa3SiA8vlpXEhfl9k-uYT22Ws********
    

To create an API key, use the create REST API method for the ApiKey resource or the ApiKeyService/Create gRPC API call.

Save the secret key you got: you will not be able to get it a second time.

Create a containerCreate a container

Create a container and a container revision with a Docker image to start GitLab Runner.

Note

In our example, we mount an ephemeral disk at /mnt to expand the available space in the root file system for the period of executing the container. Docker stores data in /var/lib/docker: this location becomes available thanks to the root file system expansion.

Management console
CLI
API
  1. In the management console, select Serverless Containers from the list of services.

  2. Click Create container.

  3. Enter a name for the container: serverless-gitlab-runner.

  4. Click Create.

  5. Navigate to the Editor tab.

    1. Under Resources, specify the required RAM, e.g., 1024 MB.

    2. Under Image settings:

      1. Click Enter link, and specify cr.yandex/yc/serverless/gitlab-runner in the Image URL field.

      2. In the Environment variables field, add the following variables:

        • CI_SERVER_URL: https://gitlab.com
        • WEBHOOK_PATH: /webhook
      3. In the Lockbox secrets field, specify:

        • Environment variable: RUNNER_TOKEN.
        • Secret ID: gitlab-runner-token.
        • Version ID: Current version ID.
        • Secret key: gitlab_runner_token.
    3. Under Settings:

      1. In the Service account field, specify gitlab-runner-lockbox-payload-viewer.
      2. In the Timeout field, specify the required value, e.g., 600 seconds.
    4. Under Mounted ephemeral disk:

      1. Click Add ephemeral disk.
      2. In the Mount path field, specify /mnt.
      3. In the Disk size field, specify the required value, e.g., 10 GB.
    5. Under Asynchronous call:

      1. Click Enable.
      2. In the Service account field, select gitlab-runner-caller.
  6. Click Create revision.

  1. Create a container:

    yc serverless container create --name serverless-gitlab-runner
    

    Result:

    id: bba83i1mrb5s********
    folder_id: b1g681qpemb4********
    created_at: "2025-09-16T06:10:03.153Z"
    name: serverless-gitlab-runner
    url: https://bba83i1mrb5s********.containers.yandexcloud.net/
    status: ACTIVE
    
  2. Create a container revision:

    yc serverless container revision deploy \
      --container-name serverless-gitlab-runner \
      --runtime=http \
      --cores <number_of_cores> \
      --memory <RAM_size> \
      --image cr.yandex/yc/serverless/gitlab-runner \
      --environment CI_SERVER_URL=https://gitlab.com \
      --environment WEBHOOK_PATH=/webhook \
      --secret id=<secret_ID>,version-id=<secret_version_ID>,key=gitlab_runner_token,environment-variable=RUNNER_TOKEN \
      --service-account-id <service_account_1_ID> \
      --execution-timeout <timeout> \
      --mount type=ephemeral-disk,mount-point=/mnt,size=<disk_size>\
      --async-service-account-id <service_account_2_ID>
    

    Where:

    • --container-name: Container name.

    • --runtime: Operating mode.

    • --cores: Number of cores available to the container, e.g., 1.

    • --memory: Required memory, e.g., 1GB.

    • --image: gitlab-runner Docker image URL.

    • --environment: Environment variables:

      • CI_SERVER_URL: GitLab CI address.
      • WEBHOOK_PATH: Webhook endpoint path.
    • --secret: Lockbox secret.

    • --service-account-id: gitlab-runner-lockbox-payload-viewer service account ID.

    • --execution-timeout: Timeout, e.g., 600s.

    • --mount: Ephemeral disk mounting parameters:

      • type=ephemeral-disk: Type of the file system being mounted.
      • mount-point: Name of the mount point. The directory the disk will be mounted to will be available at /mnt.
      • size: Ephemeral disk size in GB, e.g., 10GB.
    • --async-service-account-id: gitlab-runner-caller service account ID.

    Result:

    id: bba27hejd69a********
    container_id: bba83i1mrb5s********
    created_at: "2025-09-18T09:38:14.528Z"
    image:
      image_url: cr.yandex/yc/serverless/gitlab-runner
      image_digest: sha256:ac62...
      environment:
        CI_SERVER_URL: https://gitlab.com
        WEBHOOK_PATH: C:/Program Files/Git/webhook
    resources:
      memory: "1073741824"
      cores: "1"
      core_fraction: "100"
    execution_timeout: 600s
    concurrency: "1"
    service_account_id: ajenprbpf1s3********
    status: ACTIVE
    secrets:
      - id: e6qdur7h55vd********
        version_id: e6qbaf927irb********
        key: gitlab_runner_token
        environment_variable: RUNNER_TOKEN
    log_options:
      folder_id: b1g681qpemb4********
    mounts:
      - mount_point_path: /mnt
        ephemeral_disk_spec:
          size: "10737418240"
          block_size: "4096"
    runtime:
      http: {}
    async_invocation_config:
      service_account_id: ajetqjm00ji8********
    

    Tip

    In case of the mounts[0].mount_point_path: Field does not match the pattern /[-_0-9a-zA-Z/]*/ error, escape the mount point name:

    mount-point=//mnt
    

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.

Set up a webhook in GitLabSet up a webhook in GitLab

  1. Open your project in GitLab.

  2. In the left-hand panel, select Settings → Webhooks.

  3. Click Add new webhook.

  4. In the URL field, specify the Serverless Containers public endpoint: https://<container_ID>.containers.yandexcloud.net/webhook.

  5. Under Custom headers, click Add custom header and add the following ones:

    Header name Header value Description
    Authorization Api-Key <API_key> gitlab-runner-caller service account API key. Required if the container is private; otherwise, the request will be denied. Learn more in Authenticating when invoking a private container via HTTPS.
    X-Ycf-Container-Integration-Type async Asynchronous container invocation. The platform will immediately return respond to the invocation with 202.
  6. Under Trigger, make sure the Job events option is enabled.

  7. Click Add webhook.

After that, you will be able to use serverless GitLab Runners.

Tip

You can additionally configure GitLab Runner using environment variables and flags.

View the available options by running the gitlab-runner run-single -h command. You can also look up the guide section on the GitLab Runner commands.

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

To stop paying for the resources you created:

  1. Delete the container.
  2. Delete the secret.

Was the article helpful?

Previous
Building a CI/CD pipeline in GitLab
Next
Configuring CI/CD between Cloud Functions and SourceCraft
© 2025 Direct Cursus Technology L.L.C.