JetBrains Space Help

Containers

Space Automation lets you run job steps in Docker containers inside Space Automation Cloud or self-hosted workers.

How does it work

  • To run a step in a container, use the container block:

    job("Example"){ // displayName is optional // it will be shown in the job run results container(displayName = "Say Hello", image = "alpine") { shellScript { content = "echo Hello" } } }
  • You can use container images from various sources: Docker Hub, Space Packages registries, remote registries, or even use an image that was built in a previous job step.

  • Depending on your task, in a container, you can run a shell script, arbitrary Kotlin code, or a container image command.

    All these three options are mutually exclusive.

  • During the run, the container has access to the project repository.

  • You can adjust container resources for resource-consuming steps.

  • If your job requires additional network-accessible services like MySQL or Redis, you can run them in service containers.

  • The environment where a job will eventually run (cloud or self-hosted workers) depends on the Default worker pool parameter and job requirements. Learn more about how to specify job run environment.

  • Containers are billed for each minute of work based on the run environment. Learn more

Container image sources

Docker Hub

To use an image from Docker Hub, specify the image name:

job("Use Docker Hub") { container(image = "hello-world") { // ... } }

Note that Space caches the images downloaded from Docker Hub. The cache lifetime is no longer than three hours. The disk space required for storing cached images is provided free of charge.

Space Packages registry

To use an image from Space Packages, specify the full image URL:

job("Use Space Packages") { container(image = "mycompany.registry.jetbrains.space/p/projectkey/mydocker/hello-world") { // ... } }

Important: If you want to use an image from a private registry created in another project, you must first attach this private registry to the current project.

Remote private registry

To use an image from a remote registry that requires authorization, you must first create a connection to that registry and then use this connection in a job.

  1. In the remote registry, issue a token with the read permission.

  2. Open the desired project.

  3. On the project sidebar menu, choose Settings, then Docker Registry Connections.

  4. Click New connection and specify connection settings:

    • Key: a unique connection name that you will use to reference this connection in jobs, e.g., docker_hub or some_registry

    • Docker registry server: a URL of the remote Docker registry. For Docker Hub, it's index.docker.io

    • Username and Password: the username and the password (token) created previously.

  5. Specify the connection and the image in the container:

    job("Use remote registry") { container(image = "some.registry.com/image:1.2.3") { dockerRegistryConnections { +"some_registry" } // ... } }
Image created in the same job

A job lets you build a Docker image in one step and then use it for running the next steps. See an example

Directory structure and working directory

Before running user jobs, Automation runs a hidden "bootstrap" job that

  1. creates a disk volume,

  2. clones the project sources from the Git server to the volume,

  3. mounts the volume to the container. By default, the volume is mounted to /mnt/space.

/ ├─── mnt │ └─── space // step data directory │ ├─── share // file share │ ├─── system // non-user system files │ └─── work │ ├─── {git-repo-name} // cloned git repository (working directory) │ ├─── ... // other project repos (only if specified in the script) │ └─── ... ...

Here:

  • /mnt/space is the parent directory for step data.

    To change the default path, use the job.container.mountDir parameter.

    To get this path in a shellScript or kotlinScript, use the JB_SPACE_STEP_DATA_PATH environment variable.

  • /mnt/space/work/{git-repo-name} is the default project source code location. Here {git-repo-name} stands for the project's Git repository name. It is also the container's default working directory. For details on how to check out additional project repositories, refer to Check out Source Code.

    To change the default path, use the job.container.workDir parameter.

    To get this path in a shellScript or kotlinScript, use the JB_SPACE_WORK_DIR_PATH environment variable.

  • /mnt/space/share is the external storage used for file sharing.

    To get this path in a shellScript or kotlinScript, use the JB_SPACE_FILE_SHARE_PATH environment variable.

What can you run in a container

Shell scripts
job("Run shell script") { container(displayName = "Show dir contents", image = "ubuntu") { shellScript { interpreter = "/bin/bash" content = """ echo Working dir contents ls /mnt/space/work """ } } }

Learn more

Arbitrary Kotlin code
job("Run Kotlin code") { container(displayName = "Say Hello", image = "amazoncorretto:17-alpine") { kotlinScript { api -> println("Hello world!") } } }

Learn more

Container image commands
job("Run container command") { container(displayName = "Say Hello", image = "alpine") { args("echo", "Hello World!") } }

Learn more

Is it possible to run several kotlinScript, shellScript, and entrypoint in the same container?

No, it's not possible. A container step can run only one item: kotlinScript, shellScript, or args | entrypoint. If you specify more than one inside a container, the job will fail.

Wrong

Correct

job("This job fails") { container(image = "amazoncorretto:17-alpine") { kotlinScript { api -> // Do smth. } shellScript { content = """ echo Do smth. """ } } }
job("This job works") { container(image = "amazoncorretto:17-alpine") { kotlinScript { api -> // Do smth. } } container(image = "alpine") { shellScript { content = """ echo Do smth. """ } } }

Alternatively, you can use a host step instead of container:

job("This job works") { host { kotlinScript { api -> // Do smth. } shellScript { content = """ echo Do smth. """ } } }

Container resources

A job can contain not more than 50 containers (steps). Each container has the following resources constraints:

Default

Max

Min

Virtual CPUs

2 vCPU

8 vCPU, 4 vCPU for the Free plan

0.5 vCPU

Memory

7800 MB

31200 MB, 15600 MB for the Free plan

All containers within a job use the same disk volume (it contains the project repository). The default volume size is 5 GB and the maximum allowed size is 30 GB. To specify resources and volume size, use the job.container.resources and job.volumeSize parameters. All parameters support corresponding units:

  • job.container.resources.cpu: You can set a value in .cpu or .mcpu (millicpu), for example, cpu = 250.mcpu is the same as cpu = 0.25.cpu.

  • job.container.resources.memory and job.volumeSize: You can set their values in .mb (MB) and .gb (GB), for example, volumeSize = 10.gb.

job("Example") { // 10 GB volumeSize = 10.gb container(image = "alpine") { resources { // 500.mcpu = 0.5.cpu cpu = 0.5.cpu // 2000 MB memory = 2000.mb } } }

Destination ports for outbound connections

Allowed

Blocked

  • All types of ICMP

  • 0 – 1024/UDP and TCP

  • 9418/UDP and TCP (Git pack transfer service)

  • 1025 – 65535/UDP and TCP

  • Any kind of SMTP and IMAP: 25/TCP, 25/UDP, 587/TCP, 465/TCP, 993/TCP, 993/UDP, 143/TCP, 143/UDP

Last modified: 15 December 2023