> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nebius.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Molecular dynamics simulations with OpenMM in Serverless AI

[Molecular dynamics](https://en.wikipedia.org/wiki/Molecular_dynamics) simulations help you study how atoms and molecules move over time. They are commonly used to explore protein stability, conformational changes and ligand binding. You can run these simulations on Nebius AI Cloud using [OpenMM](https://openmm.org), a Python-based simulation engine with GPU acceleration. By packaging OpenMM in a Docker image and running it as a Serverless AI job, you only pay for the seconds the GPU is in use and avoid keeping infrastructure running between simulations.

In this tutorial, you will run a protein simulation and inspect its results. The tutorial walks you through the following steps:

1. Build the simulation image locally with Docker and push it to [Container Registry](/container-registry/index).
2. Configure an [Object Storage](/object-storage/overview) bucket for storing simulation results.
3. Run a CUDA®-accelerated protein simulation as a Serverless AI job that reads a protein structure and writes the simulation results to the Object Storage bucket.

## Costs

Nebius AI Cloud charges you for the following billing items:

* [Compute virtual machines](/compute/resources/pricing#virtual-machines-gpus-vcpus-ram) (VMs)
* [Boot disks](/compute/resources/pricing#disks) attached to the VMs
* Used space in Standard storage in an [Object Storage bucket](/object-storage/resources/pricing#storing-data)

[Container Registry](/container-registry/resources/pricing) is provided free of charge.

## Prerequisites

<Tabs group="interfaces">
  <Tab title="Web console">
    1. Make sure you are in a [group](/iam/authorization/groups/index) that has at least the `editor` role within your tenant or project; for example, the default `editors` group. You can check this in the [Administration → IAM](https://console.nebius.com/iam) section of the web console.

    2. Install Docker on your local machine. To do so, you can install [Docker Desktop](https://docs.docker.com/get-started/get-docker/).

       If your local machine uses a different CPU architecture than AMD64 — for example, an Apple Silicon Mac or a Windows-on-ARM device — Docker Desktop builds the AMD64 image under emulation.

    3. [Install the Nebius AI Cloud CLI](/cli/install). It is required to authenticate against Container Registry and to push the Docker image to it.
  </Tab>

  <Tab title="CLI">
    1. Make sure you are in a [group](/iam/authorization/groups/index) that has at least the `editor` role within your tenant or project; for example, the default `editors` group. You can check this in the [Administration → IAM](https://console.nebius.com/iam) section of the web console.

    2. Install and configure the Nebius AI Cloud CLI and the AWS CLI. Here are the instructions, depending on what tools you have already installed:

       * [How to install both CLIs](/object-storage/quickstart#prepare-your-environment)
       * [How to install the Nebius AI Cloud CLI only](/cli/install)
       * How to [install](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions) and [configure](/object-storage/interfaces/aws-cli#configuring-aws-cli) the AWS CLI only

       When configuring the AWS CLI, make sure to create a service account and its access key. The Serverless AI job uses these credentials to write results to Object Storage.

    3. Install Docker on your local machine. To do so, you can install [Docker Desktop](https://docs.docker.com/get-started/get-docker/).

       If your local machine uses a different CPU architecture than AMD64 — for example, an Apple Silicon Mac or a Windows-on-ARM device — Docker Desktop builds the AMD64 image under emulation.
  </Tab>
</Tabs>

## Steps

### Prepare infrastructure

<Note>
  Locate all resources in the same project.
</Note>

1. Create an Object Storage bucket to store simulation results.

   Serverless AI deletes the container disk after the job completes. The bucket preserves the simulation artifacts generated by the job: the processed structure, trajectory, logs, metadata and plots.

   <Tabs group="interfaces">
     <Tab title="Web console">
       1. In the [web console](https://console.nebius.com), go to <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/sidebar/storage.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=0a2dad6b48aea10e85f6f3e2343aee26" width="16" height="16" data-path="_assets/sidebar/storage.svg" /> **Storage** → **Object Storage**.
       2. Click <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/plus.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=7c9efc69d65fc58db0eb73702fd81aa1" width="16" height="16" data-path="_assets/plus.svg" /> **Create bucket**.
       3. Specify the `openmm-simulation` name for the bucket.
       4. In the **Bucket size** field, select **Unlimited**.
       5. Click **Create bucket**.
     </Tab>

     <Tab title="CLI">
       ```bash theme={null}
       nebius storage bucket create --name openmm-simulation
       ```
     </Tab>
   </Tabs>

2. In Container Registry, create a registry to host the Docker image with OpenMM.

   Hosting the image in Container Registry keeps image pulls inside the same region as your Serverless AI job, which reduces the image pull latency and improves the job start time. Serverless AI doesn't bill for start time, so you can use Docker Hub or configure a private registry if the added pull latency doesn't matter for your workflow.

   <Tabs group="interfaces">
     <Tab title="Web console">
       1. In the web console, go to <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/sidebar/storage.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=0a2dad6b48aea10e85f6f3e2343aee26" width="16" height="16" data-path="_assets/sidebar/storage.svg" /> **Storage** → **Container Registry**.
       2. Click <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/plus.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=7c9efc69d65fc58db0eb73702fd81aa1" width="16" height="16" data-path="_assets/plus.svg" /> **Create registry**.
       3. Specify the `openmm` name for the registry.
       4. Click **Create registry**.
     </Tab>

     <Tab title="CLI">
       Create the registry:

       ```bash theme={null}
       nebius registry create --name openmm
       ```
     </Tab>
   </Tabs>

### Build and push the image

1. Configure the Docker credential helper for Container Registry so that `docker push` can authenticate through the Nebius AI Cloud CLI:

   ```bash theme={null}
   nebius registry configure-helper
   ```

2. Clone the [Serverless AI Cookbook](https://github.com/nebius/serverless-ai-cookbook) repository and switch to the `openmm-simulation` directory:

   ```bash theme={null}
   git clone https://github.com/nebius/serverless-ai-cookbook.git && \
   cd serverless-ai-cookbook/life-science/openmm-simulation
   ```

   The `sim/` folder contains Python code with the OpenMM simulation settings. This tutorial uses the code as-is and lets you adjust the target protein and the simulation step count when you create the Serverless AI job.

   <Tip>
     You can explore the code and change the simulation settings — for example, by editing the OpenMM classes in `sim/utils.py` and `sim/run.py`. For more details, see [OpenMM Python API](https://docs.openmm.org/latest/api-python/index.html).
   </Tip>

3. Export the region and the registry path to environment variables:

   ```bash theme={null}
   export NB_REGION_ID=<region_ID>
   export NB_REGISTRY_PATH=$(nebius registry list \
     --format json \
     | jq -r '.items[] | select(.metadata.name=="openmm") | .metadata.id' \
     | cut -d- -f2)
   ```

   For the list of regions, see [Regions](/overview/regions).

4. Verify that Docker is available and the daemon is running:

   ```bash theme={null}
   docker version
   docker ps
   ```

   If `docker ps` returns a table of containers (can be empty), the daemon is running. If the daemon is not running, [launch it](https://docs.docker.com/engine/daemon/start/).

5. Build the image, targeting `linux/amd64`:

   ```bash theme={null}
   docker build --platform linux/amd64 \
     -t cr.$NB_REGION_ID.nebius.cloud/$NB_REGISTRY_PATH/openmm-serverless:v1 .
   ```

   <Note>
     Serverless AI runs Docker images on the `linux/amd64` architecture. Using the `--platform linux/amd64` parameter produces an AMD64 image regardless of the host architecture of your local machine. The resulting image runs natively in Serverless AI with no runtime penalty. For more information, see [Docker official documentation](https://docs.docker.com/build/building/multi-platform/) on multi-platform builds.
   </Note>

6. Push the image to the registry:

   ```bash theme={null}
   docker push cr.$NB_REGION_ID.nebius.cloud/$NB_REGISTRY_PATH/openmm-serverless:v1
   ```

### Run the simulation as a Serverless AI job

Create a CUDA-accelerated job that runs a short simulation on the `1UBQ` protein structure:

<Tabs group="interfaces">
  <Tab title="Web console">
    1. In the web console, go to <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/sidebar/storage.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=0a2dad6b48aea10e85f6f3e2343aee26" width="16" height="16" data-path="_assets/sidebar/storage.svg" /> **Storage** → **Container Registry**, then open the `openmm` registry and the `openmm-serverless` image.

    2. In the `v1` tag row, click <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/button-vellipsis.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=e80b8e57c43bfd117679262e6a1334ad" width="12" height="24" data-path="_assets/button-vellipsis.svg" /> → **Deploy as job**. The **Create job** page opens with **Image path** already filled in.

    3. Specify the remaining job parameters:

       * **Name**: `openmm-1ubq`.
       * **Entrypoint command**: `bash -c "python -m sim.run --protein-id 1UBQ --steps 1000 && cp -r /openmm/results/. /mnt/data/"`.
       * **Job timeout in hours**: `4`.
       * **Computing resources**: With GPU.
       * **Available platform**: NVIDIA® L40S PCIe with Intel Ice Lake.
       * **Preset**: 1 GPU — 8 CPUs — 32 GiB RAM.
       * **Mount volumes**: Bucket.
       * **Mount path**: `/mnt/data`. After that, click <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/plus.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=7c9efc69d65fc58db0eb73702fd81aa1" width="16" height="16" data-path="_assets/plus.svg" /> **Attach bucket** and then select the `openmm-simulation` bucket.

       In the entrypoint command, `/openmm/results/` is the location of simulation results inside the Docker container. The command runs the simulation and copies the results to the mounted bucket at `/mnt/data`. You can adjust `--protein-id` and `--steps` to target a different protein or change the simulation length.

    4. Click **Create**.

    5. Follow the job logs to watch the simulation progress:

       1. In the sidebar, go to <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/sidebar/ai-services.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=ab4ff229f7690c99deb1dc52d3daf987" width="16" height="16" data-path="_assets/sidebar/ai-services.svg" /> **AI Services** → **Jobs**.
       2. Next to the job, click **View logs**. Alternatively, select the job that you want to view the logs for and switch to the **Logs** tab.
  </Tab>

  <Tab title="CLI">
    1. Create the environment variables with your AWS CLI credentials and the Object Storage bucket settings. The Serverless AI job reads these and uploads the results to the bucket through the AWS API:

       ```bash theme={null}
       export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id)
       export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key)
       export AWS_DEFAULT_REGION=$NB_REGION_ID
       export S3_ENDPOINT_URL=https://storage.${NB_REGION_ID}.nebius.cloud
       export S3_BUCKET=openmm-simulation
       export S3_PREFIX=openmm
       ```

    2. Set the subnet ID where the job will run:

       ```bash theme={null}
       export NB_SUBNET_ID=<subnet_ID>
       ```

       See [How to get a subnet ID](/vpc/networking/resources#how-to-get-a-subnet-id).

    3. Create the job.

       ```bash theme={null}
       nebius ai job create \
         --name openmm-1ubq \
         --image cr.$NB_REGION_ID.nebius.cloud/$NB_REGISTRY_PATH/openmm-serverless:v1 \
         --platform gpu-l40s-a \
         --preset 1gpu-8vcpu-32gb \
         --timeout 4h \
         --args "--protein-id 1UBQ --steps 1000" \
         --env "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" \
         --env "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" \
         --env "AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" \
         --env "S3_ENDPOINT_URL=$S3_ENDPOINT_URL" \
         --env "S3_BUCKET=$S3_BUCKET" \
         --env "S3_PREFIX=$S3_PREFIX" \
         --subnet-id $NB_SUBNET_ID
       ```

       You can reuse this command to start several simulation jobs in parallel: for each job, change the `--name` and `--args` values — for example, `--protein-id 2PTC --steps 2000`.

    4. Follow the job logs to watch the simulation progress:

       ```bash theme={null}
       nebius ai job logs <job_ID> --follow
       ```
  </Tab>
</Tabs>

A healthy CUDA-accelerated job prints the following line near the start of the logs:

```text theme={null}
Using OpenMM platform: CUDA
```

If the line shows `CPU` or `Reference` instead, the GPU runtime didn't initialize and the simulation will be far slower than expected.

### View results in the bucket

<Tabs group="interfaces">
  <Tab title="Web console">
    The job uploads the simulation results to the bucket in the folder named `<protein_id>_<timestamp>/` — for example, `1UBQ_20260512_192514/`.

    To view results:

    1. In the web console, go to <Icon icon="https://mintcdn.com/nebius-ai-cloud/1Ha0sWR6e1mnIaHS/_assets/sidebar/storage.svg?fit=max&auto=format&n=1Ha0sWR6e1mnIaHS&q=85&s=0a2dad6b48aea10e85f6f3e2343aee26" width="16" height="16" data-path="_assets/sidebar/storage.svg" /> **Storage** → **Object Storage**.
    2. Open the `openmm-simulation` bucket.
    3. Open the output folder of the latest job.
  </Tab>

  <Tab title="CLI">
    The job uploads the simulation results to the bucket through the [AWS S3-compatible API](/object-storage/interfaces/s3-api-compatibility) at `s3://<bucket>/<prefix>/<protein_id>_<timestamp>/` — for example, `s3://openmm-simulation/openmm/1UBQ_20260512_192514/`.

    To view results:

    1. List the job outputs in the bucket:

       ```bash theme={null}
       aws s3 ls "s3://$S3_BUCKET/$S3_PREFIX/" \
         --endpoint-url "$S3_ENDPOINT_URL"
       ```

    2. Download a specific job output locally:

       ```bash theme={null}
       aws s3 sync "s3://$S3_BUCKET/$S3_PREFIX/<output>/" "./results/<output>/" \
         --endpoint-url "$S3_ENDPOINT_URL"
       ```
  </Tab>
</Tabs>

A completed simulation contains the following artifacts:

* `<protein>_processed.pdb` — the processed input structure.
* `<protein>_trajectory.dcd` — the trajectory of the simulation.
* `<protein>_simulation.log` — the simulation log.
* `<protein>_metadata.txt` — the simulation metadata.
* `plots/` — visualizations generated from the trajectory.

To inspect the simulation locally, open the downloaded `<protein_id>_processed.pdb` and `<protein_id>_trajectory.dcd` files in a molecular visualization tool of your choice, for example, [PyMOL](https://www.pymol.org/).

<Frame caption="Generated in PyMOL from `1UBQ_processed.pdb`">
  <img src="https://mintcdn.com/nebius-ai-cloud/GJF9LhwGqChu49Y0/_assets/serverless/openmm-pymol-visualization.png?fit=max&auto=format&n=GJF9LhwGqChu49Y0&q=85&s=9e1e81809d1cd342de36cf617650145b" alt="PyMOL rendering of the 1UBQ protein structure" width="871" height="291" data-path="_assets/serverless/openmm-pymol-visualization.png" />
</Frame>

## How to delete the created resources

A Serverless AI job stops billing the moment it completes, but the bucket keeps accruing charges until you remove it. The container registry is free of charge; delete it if you no longer need the image. The service account and its access key live at the tenant level, don't accrue charges and can be reused for future workloads.

If you don't need the bucket, [delete it](/object-storage/buckets/manage#how-to-delete-buckets), so Nebius AI Cloud doesn't charge for it.
