# Welcome to TensorDock

Your new cloud.

## We are TensorDock.

We're democratizing the cloud by aggregating together a global network of hosts.

Hosts get to monetize their servers, and customers get to access a wider range of compute than you would at any single cloud provider. Our marketplace structure guarantees the industry's best value.

## Quick, reliable GPU deployments.

By building our entire stack in-house, we've optimized our product from the ground up. Virtual machine deployments take 20 seconds, not 20 minutes.&#x20;

## Integrate one platform, deploy anywhere

We epitomize multi-cloud. We partner with hosts all around the world so that you can build one API integration with us and move on.  From Joplin, Missouri to Germany, we've got you covered.&#x20;

## Right size. Right now.

With the industry's widest availability of GPU models at over 100 locations worldwide, we have the GPUs you need, where you need them.

## Support

We're always available at <support@tensordock.com>. If you have a favorite team member, you can reach out to them directly. We're all ready to serve!&#x20;


# Our Ethos and Commitment

With AI startups burning up to 80% of their funding on infrastructure, compute poses an unreasonable barrier to innovation. We refuse to let infrastructure be the bottleneck of progress. That's why we've come together as a team of visionaries driven by a common goal: to empower the builders of tomorrow.\
\
Our mission is nothing short of revolutionizing the cloud landscape. We're uniting a network of independent hosts with the power to challenge the hyperscalers. But we're not stopping there - We're crafting cutting-edge software that's redefining how AI training and inference workloads are deployed globally.\
\
**Let's build the future of AI, together.**

![](/files/0sQn586yB9amklcNdBHg)

### Engineering First

We know infrastructure - because we've run it ourselves. Before we started TensorDock, we hosted servers for other marketplaces. We understand what to look for in hosts, and how to get them to meet the high standards of our customers.

Optimizing performance is in our DNA. When we hosted servers, we compromised at nothing to tinker and deliver the best experience possible for our customers, We played around with open-air chassis, natural airflow, and immersion cooling. Now that we're TensorDock, we continue to focus on slashing costs without ever compromising quality.\
\
In fact, after years of deploying Proxmox and OpenStack clusters, we built our own Libvirt-based hypervisor. We've improved reliability by 90% while providing the flexibility for storage-only billing, fast VM modifications, and Instant Deploy VMs.

### Relationships above all

We're here to serve you. You matter, regardless of how much you spend, or how many GPUs you host with us. Our staff are available 24/7 to help. We have a 24-hour response time standard, but we often respond even quicker!

Our philosophy is that it costs us nothing to be helpful and responsive - if we have to get back to you eventually, it might as well be ASAP.

### Relationships above all

We're committed to building the best platform for developers, and we know from personal experience that quotas and hidden pricing suck for users. TensorDock is built from the ground up to be truly on-demand.\
\
As part of our commitment to delivering the highest possible value for customers and hosts, we don't offer a referral program, so that we can maintain the thinnest margins possible. We want our product to be so great that our users will tell their friends regardless!\
\
All TensorDock policies, including our [downtime compensation](https://docs.tensordock.com/legal-information/downtime-compensation) and [hosting agreement](https://docs.tensordock.com/legal-information/supplier-hosting-agreement), are posted publicly. And for equality, we maintain the same on-demand pricing for all customers: no negotiation needed.


# Introduction to Core Compute VMs

## What is Core Compute?

Core Compute VMs are our latest addition to TensorDock, and are our flagship product in our latest offering to customers. It offers several new features that are intended to enhance customer experience and usability on TensorDock!

\
Our Core Compute providers consist of hosts that have demonstrated consistent reliability in terms of uptime and operational excellence.&#x20;

### &#x20;What does Core Compute offer?

All Core Compute locations include several features, including network storage. For instance, a VM deployed in our Manassas, Virginia location once stopped, will be available to deploy on any Manassas, Virginia servers that have that GPU available rather than being able to start on one server as in Distributed Compute VMs. \
\
Core Compute locations also now enjoy the addition of Static IPs, with each VM getting their own static IP.  This means that TensorDock users, for the first time, will have access to the full range of ports available on their given IP. This also eliminates the need for customers to utilize the dashboard to configure port forwards; please visit our [Opening Port Forwards on Core Compute VMs](/virtual-machines/opening-ports-on-core-compute-vms) article for more information!\
\
Finally, all core compute VMs now feature TensorDocks newest high-performance hypervisor, optimized with low-overhead virtualization in mind. Core Compute VMs enjoy up to a 20% boost in single-core performance and up to a 10% boost in multi-core performance compared to prior generations, depending on certain CPUs and workloads!\ <br>

## How to deploy a Core Compute VM

1. Navigate to <https://dashboard.tensordock.com/deploy>
2. Select a desired GPU model and VM specs (vCPU/RAM/Storage sizes)
3. Look for the available "Core Compute" label in the location section as pictured:

<figure><img src="/files/14GgIVOg5m4WiRIem2n1" alt=""><figcaption></figcaption></figure>

4. Select your desired operating system image, and confirm that Dedicated IP and Network Storage is enabled just below.&#x20;
5. Select your SSH Key on the right hand side (see [How to add your SSH Key](/virtual-machines/how-to-add-your-ssh-key) for help)

\
![](/files/cqaK2ezoVRuSbafgfWSN)

6. Select Deploy Instance, and enjoy!


# How to add your SSH Key

A brief walkthrough of how to add your SSH Key to your TensorDock account! This tutorial assumes that you already have an SSH Keypair generated.

1. Navigate to the TensorDock website, and to the "Secrets" Tab.  (<https://dashboard.tensordock.com/secrets>) and select "Add Secret" on the top right

<figure><img src="/files/7tOxIkxcA7v0BsLLgWxA" alt=""><figcaption></figcaption></figure>

2. Name your new key, and select "SSH Key" on the **Type** dropdown. \
   ![](/files/pvmRpEhkxFVjap518buf)
3. Copy your **Public Key** and paste it into the Value field. \
   ![](/files/3ZFGAIOD7B7H6TsUDhJx)
4. Click Create Secret. Congratulations, your key has been added to TensorDock! All future Linux-based deployments will now have your SSH Key automatically added for your convenience. <img src="/files/1DwzXvzxpAK0v5b4jLFl" alt="" data-size="original">

&#x20;


# Opening Ports on Core Compute VMs

This tutorial will walk you through how to open ports on Core Compute VMs, and assumes you already have a Core Compute VM deployed.

All TensorDock Core Compute VMs enjoy per-VM dedicated IPs. This allows your machine to enjoy a full range of ports, further streamlining your workflow.

## For Linux-based VMs (Optional):

**By default, all ports on your Linux VMs are open, and UFW is disabled.** \
The following steps are for securing your VM with the UFW firewall, to help protect your VM. \
\
If you choose to use UFW to whitelist ports, **please always ensure you forward port 22**. Failure to do so can lock you out of your VM with no access back in.&#x20;

1. Log into your VM (ssh user\@ip)
2. ```
   sudo ufw enable
   ```
3. ```
   sudo ufw allow <port_number>
   ```

Ensure you replace \<port\_number> with the port you want to open. For example, `80` for HTTP, `443` for HTTPS, `22` for SSH.&#x20;

4. ```
   sudo ufw status verbose
   ```

The final step will show you a list of all your existing rules, including your newly added port forward. \ <br>

### Additional optional commands for Linux:

#### Opening a port using a specific protocol:

```
sudo ufw allow <port_number>/<protocol>
```

Replace \<protocol> with TCP or UDP. \
Syntax:

```
sudo ufw allow 22/tcp
```

#### Opening a range of ports using a specific protocol:

```
sudo ufw allow <start_port>:<end_port>/<protocol>
```

Replace \<protocol> with TCP or UDP, and replace the \<start\_port> and \<end\_port> with your appropriate port range. \
Syntax:&#x20;

```
sudo ufw allow 50000:50010/udp
```

## For Windows-based VMs:

Opening ports on your Windows-based VMs requires the use of Windows Firewall.

1. Search for "Windows Firewall" and open **Windows Defender Firewall with Advanced Security.**&#x20;

<figure><img src="/files/EzPq9qt5ZVu41ZzpAGZG" alt=""><figcaption></figcaption></figure>

2. On the left-hand bar, click "**Inbound Rule**" and then click "**New Rule..."** on the right-hand bar side. You should get a window pop-up as shown.&#x20;

<figure><img src="/files/USnH8UuYEnrAhpk27iDQ" alt=""><figcaption></figcaption></figure>

3. Select "**Port**" on the pop-up menu, and click "**Next >**". Next, select the desired protocol (only one can be selected at a time, a duplicate rule must be created if both protocols are desired), and then select "**Specific local ports**" and enter the port you'd like to open. Click "**Next >**".<br>

<figure><img src="/files/QKheEuGWFrzXVXaO2fNz" alt=""><figcaption></figcaption></figure>

4. Select **"Allow the Connection**" on the next menu, and click "**Next >**".&#x20;

<figure><img src="/files/qmnZYzvrKUXx3gE0orZL" alt=""><figcaption></figcaption></figure>

5. Ensure all boxes are checked in the preceding menu and click "**Next >**".

<figure><img src="/files/vJn7JR68v48iKsYJSJd7" alt=""><figcaption></figcaption></figure>

6. Add a name for your new rule and a description if you wish. Click "**Finish**" and verify that the rule has been added to your firewall.&#x20;

<figure><img src="/files/pGKngzHofnvTP0RtcQRU" alt=""><figcaption></figcaption></figure>


# How to SSH into your instance

Connect to an instance on Ubuntu through a remote secure shell.

## 1. Deploy a Cloud GPU

Configure a GPU on our [Marketplace](https://marketplace.tensordock.com/order_list) based on cost, RAM, storage, and vCPUs. To use SSH, ensure that you have a port forwarded to port 22. To use Ubuntu, select your version for your installation. Make sure your storage matches your operating system's requirements.

<figure><img src="/files/roWFZBMC43vX8h69qu6G" alt=""><figcaption><p>You need to forward to port 22 to SSH into your instance</p></figcaption></figure>

## 2. Set up your machine for SSH

We auto generate the command line for you.

<figure><img src="/files/2EtySAC51a1IwL8YeAk1" alt=""><figcaption><p>Use the networking section your SSH information</p></figcaption></figure>

Run the generated command in your operating system's terminal software to access your instance:&#x20;

* Windows: Powershell
* Linux: Terminal
* MacOS: Terminal

<figure><img src="/files/CDgNiVX3THYZD6c92T0z" alt=""><figcaption><p>Example for Windows Powershell</p></figcaption></figure>

Congratulations! You have now SSHed into your server and have access to the power needed for your own usage. At any time, you can quit your connection with the command `exit`.


# How to RDP into your instance

This tutorial helps users on the TensorDock Marketplace connect to an instance on Windows through a Remote Desktop Protocol.

## Step 1: Deploy a Cloud GPU

You can deploy a GPU on our [Marketplace](https://marketplace.tensordock.com/order_list) to your specific configurations based on cost, RAM, storage, and vCPUs. To use SSH, ensure that you have a port forwarded to port 22 and port 3389. Select Windows 10 as your installation. Note that you will need at least 80 GB disk space.

<figure><img src="/files/bLUN60OoTt5WuZjsGsES" alt=""><figcaption><p>Ensure that you have a port forwarded to port 22 and port 3389</p></figcaption></figure>

<figure><img src="/files/yv12kuArdeG1CQiEdh7T" alt=""><figcaption><p>Select Windows 10 and include at least 80 GB disk space</p></figcaption></figure>

## Step 2: Open Microsoft Remote Desktop

If you are using a Windows PC, you can open the taskbar, type `Remote Desktop Connection`, and then select `Remote Desktop Connection`.

If you are on a Mac, iOS, Android, or other Windows device, you can download the `Remote Desktop` app, available for free on the Microsoft Store, Google Play, and the Mac App Store.

<figure><img src="/files/Jv2X9FMEItqVoGDrB63u" alt=""><figcaption><p>Micrsoft Remote Desktop app on the Mac app store</p></figcaption></figure>

## Step 3: RDP into your instance

Note: Once your server is deployed, you'll need to wait up to 10 minutes for Windows to get ready before you can RDP into it.

Use the IPv4 Address of your instance, found in the Networking section of your server followed by the Port used for 3389. In this case, you would add the name `123.123.123.123:10498` into your Remote Desktop client. When prompted, use the username `user` and the password that you set up to log into the remote desktop.

<figure><img src="/files/8bQvZlZkukVUaZASh06G" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ooekuy8dFutyS6Grbx1z" alt=""><figcaption><p>Use the IPv4 Address followed by the port for 3389</p></figcaption></figure>

<figure><img src="/files/5NfDzglJXyvz9kSX42rs" alt=""><figcaption><p>Use the username <code>user</code> and the password you created when prompted</p></figcaption></figure>


# Installing NVIDIA Drivers on Windows 10

Identifying your NVIDIA GPU using Device Manager and installing the appropriate drivers

### Identifying Your NVIDIA Graphics Card

#### Step 1: Open Device Manager

1. Press `Windows + X` on your keyboard.
2. From the menu, select **Device Manager**.

#### Step 2: Locate the Display Adapters Section

1. Find and expand the **Display adapters** section.
2. You'll see your GPUs listed here. Note the exact name.

### Installing the Driver

**Step 1: Download the Driver**

* [ADA 6000](https://us.download.nvidia.com/Windows/Quadro_Certified/528.02/528.02-quadro-rtx-desktop-notebook-win10-win11-64bit-international-dch-whql.exe)
* [RTX 4090](https://us.download.nvidia.com/Windows/556.12/556.12-notebook-win10-win11-64bit-international-dch-whql.exe)
* [RTX 3080](https://us.download.nvidia.com/Windows/556.12/556.12-desktop-win10-win11-64bit-international-dch-whql.exe)

#### Step 2: Run the Installer

1. Once the download is complete, locate the file in your downloads folder.
2. Double-click the file to run the installer.

#### Step 3: Follow the Installation Wizard

1. Follow the on-screen instructions in the installation wizard.
2. When prompted, choose **Express Installation** for a quick setup.
3. Wait for the installation to complete. This may take a few minutes.

#### Step 4: Restart Your Computer

1. After the installation is complete, restart your computer to apply the changes.


# Linux & NVIDIA Drivers

This tutorial assumes that you have already deployed a GPU server on the TensorDock platform:

{% embed url="<https://marketplace.tensordock.com/order_list>" fullWidth="false" %}

## Important Note - Holding & Unholding NVIDIA driver versions

NVIDIA drivers automatically update. Once the drivers update, they require a reboot for the GPUs to become usable again. By default, our templates lock your driver image to the version they were built with so that the GPUs never become unusable.&#x20;

<figure><img src="/files/T6OAHKg8dz6khaUuiong" alt=""><figcaption><p>When NVIDIA drivers automatically update, the GPUs becomes unusable. Thus, you should always lock a working driver version</p></figcaption></figure>

To unlock the driver version, run the following command:

```
sudo apt-mark unhold nvidia* libnvidia*
```

Once you upgrade to a new driver version, you can lock the new driver version to prevent the driver from updating automatically in the future. Run the following command as the `root` user to do this.&#x20;

<pre><code><strong>dpkg-query -W --showformat='${Package} ${Status}\n' | grep -v deinstall | awk '{ print $1 }' | grep -E 'nvidia.*-[0-9]+$' | xargs -r -L 1 apt-mark hold
</strong></code></pre>

## Important Note - NVIDIA H100 SXM5

Our NVIDIA H100 SXM5 servers require the installation of the `nvidia-fabricmanager-535` driver for the GPU driver to properly use the NVSwitch fabric installed. **NVLink is only enabled for 8x H100 VMs. If you do not install this package, CUDA will NOT work properly.**&#x20;

Our TensorML operating system packages include this package, but our base templates do not.&#x20;

First, we'll need to unhold the default drivers included with our operating system templates:

```
sudo apt-mark unhold nvidia* libnvidia*
```

Then, we'll need to install the NVSwitch FabricManager package:

```
sudo apt update
sudo apt install nvidia-fabricmanager-535
```

Finally, we'll upgrade all of our packages before rebooting, which will bring the GPU driver up to date with the FabricManager package.&#x20;

```
sudo apt upgrade -y 
sudo reboot
```

<figure><img src="/files/FETYarcOsyrGfT2KzMhd" alt=""><figcaption></figcaption></figure>

As pictured, `nvidia-smi -q` should show Fabric State = Completed after the reboot. This indicates the GPUs are ready for usage!&#x20;

## Installing a new driver

### 1. Search for your NVIDIA driver

First, search for your GPU through the link below and copy the link to the NVIDIA driver.&#x20;

For instance, for a GeForce 4090:

* Product Type: GeForce
* Product Series: GeForce RTX 40 Series
* Product: NVIDIA GeForce RTX 4090
* Operating System: Linux 64-bit
* Download Type: Production Branch
* Language: English (US)

{% embed url="<https://www.nvidia.com/download/index.aspx>" %}
Click on this link to search for the NVIDIA driver for your graphics card
{% endembed %}

### 2. Visit the downloads page

Once you get redirected to the driver, click on the "Download" button. Don't worry; it won't actually initiate a download. It will simply redirect you to a page where you'll confirm NVIDIA's EULA.&#x20;

<figure><img src="/files/iXzTFRnqHn8b9lHoPBX9" alt=""><figcaption></figcaption></figure>

### 3. Copy the driver download link

Now, you can copy the link to the actual driver.&#x20;

<figure><img src="/files/8hDQ3AveACcKWGB0nFwP" alt=""><figcaption></figcaption></figure>

### 4. SSH onto your TensorDock instance

Use the port forwarded into port 22 as your SSH port. You should see something like the following:

<figure><img src="/files/GYZz39SnNYCXnehekqFy" alt=""><figcaption><p>Whoops, nvidia-smi doesn't work! Downloading new drivers will fix that...</p></figcaption></figure>

### 5. Download the driver onto your VM

Use `wget` and then append the driver's URL. This will save the driver in whatever directory you're in.&#x20;

<figure><img src="/files/oaJ6liSumqG7ezoBzLDW" alt=""><figcaption></figcaption></figure>

### 6. Enable execution permissions for the driver installer you just downloaded

Run `chmod +x`  and then append the file name

<figure><img src="/files/Ka475lAjb5IxJMtReXUI" alt=""><figcaption></figcaption></figure>

### 7. Run the driver installer

Run `sudo ./[DRIVER_FILENAME]`

<figure><img src="/files/CHj1NtjLrcqWOi8mHEqQ" alt=""><figcaption></figcaption></figure>

### 8. Reboot!

Complete the questionarie, and then run `sudo reboot` to reboot your virtual machine!

### 9. Confirm everything is working

Now, `nvidia-smi` should work!&#x20;

<figure><img src="/files/sElvEA3G44HYxtoomhdj" alt=""><figcaption></figcaption></figure>

### Issues

If you're still facing issues, come email us at <support@tensordock.com>. For reference, these were the commands we ran while making this tutorial:

```
wget https://us.download.nvidia.com/XFree86/Linux-x86_64/525.60.11/NVIDIA-Linux-x86_64-525.60.11.run
chmod +x NVIDIA-Linux-x86_64-525.60.11.run
sudo ./NVIDIA-Linux-x86_64-525.60.11.run
sudo reboot
```


# Cloud-init

Cloud-init scripts let you optionally automate the initialization of virtual machines.

## Setting a cloud-init script

To set a cloud-init script, click on the "Click for more advanced options" green link when deploying your virtual machine.

<figure><img src="/files/WLJ7JN8X92s41N7i4z6z" alt=""><figcaption><p>Click on the "Click for more advanced options" green link to show this textarea</p></figcaption></figure>

This is the default cloudinit configuration we pass to the hypervisor:&#x20;

```bash
#cloud-config
user: user
password: [your defined password]
chpasswd: {expire: False}
ssh_pwauth: True
package_update: True
package_upgrade: False
```

The script that you provide simply gets appended to the end of this file.&#x20;

## Examples

### Example 1: Preventing the automatic update of NVIDIA drivers

{% hint style="info" %}
NVIDIA drivers autoupdate on the first boot. Once this happens, they become unusable. By including this cloud-init script, you'll lock the NVIDIA driver versions so that they do not autoupdate&#x20;
{% endhint %}

#### Objectives

* Write a file using cloud-init `write_files` in base64 encoding that uses `apt-mark` to hold NVIDIA packages from being automatically updated
  * The file will have the following contents: \
    `dpkg-query -W --showformat='${Package} ${Status}\n' | grep -v deinstall | awk '{ print $1 }' | grep -E 'nvidia.*-[0-9]+$' | xargs -r -L 1 apt-mark hold`
* Run a file

{% embed url="<https://forums.developer.nvidia.com/t/nvidia-smi-has-failed-because-it-couldnt-communicate-with-the-nvidia-driver-make-sure-that-the-latest-nvidia-driver-is-installed-and-running/197141/2?u=jonathan62>" %}
This is the source of the script included
{% endembed %}

#### Process

&#x20;We'll set this as our cloud-init script:

```bash
write_files:
  - encoding: b64
    path: /home/user/tensordock_scripts/prevent_update.sh
    permissions: '0644'
    content: ZHBrZy1xdWVyeSAtVyAtLXNob3dmb3JtYXQ9JyR7UGFja2FnZX0gJHtTdGF0dXN9XG4nIHwgZ3JlcCAtdiBkZWluc3RhbGwgfCBhd2sgJ3sgcHJpbnQgJDEgfScgfCBncmVwIC1FICdudmlkaWEuKi1bMC05XSskJyB8IHhhcmdzIC1yIC1MIDEgc3VkbyBhcHQtbWFyayBob2xk
    owner: user:user
runcmd:
  - bash /home/user/tensordock_scripts/prevent_update.sh
```

#### Debrief

Explanation:

* First, our server will write the new file, `prevent_update.sh`, in the user's new `tensordock_scripts` directory
* Then, our server run this file, locking in our NVIDIA driver versions to prevent autoupdates

<figure><img src="/files/teE0NP3Y20VEynHDoifk" alt=""><figcaption></figcaption></figure>

### Example 2: Hosting a website with Apache2

#### Objectives

* Install a package through cloud-init `packages`
* Write a file using cloud-init `write_files` in plaintext

#### Process

By default, the Apache2 webserver listens on port 80. As such, we'll first forward an external port into that internal port.&#x20;

<figure><img src="/files/gvUXX0twtXBBYSlx9Ig8" alt=""><figcaption><p>Because Apache listens on port 80, you'll want to forward an external port into that internal port</p></figcaption></figure>

Then, we'll set this as our cloud-init script:

```bash
packages:
  - apache2
write_files:
  - path: /var/www/html/index.html
    permissions: '0644'
    content: |
      <html>
      <head>
        <title> TensorDock Marketplace VM </title>
      </head>
      <body style="font-family: 'Courier New', monospace;">
        <p> You've reached your <span style="color: green;">TensorDock</span> virtual machine!</p>
      </body>
      </html>
    owner: www-data:www-data
```

{% hint style="warning" %}
Note the indentation of the custom HTML we've defined above! When writing files, we must append four (4) spaces in front of each text block.
{% endhint %}

#### Debrief

Explanation:

* First, our server will install the `apache2` package
* Then, our server will overwrite the we create an index.html file with the custom HTML we've defined

Now, let's try accessing our web server!

<figure><img src="/files/dN4DOe9EeOZtm3PUaccM" alt=""><figcaption><p>Woohoo! It works!</p></figcaption></figure>

### Example 3: Hosting a simple Docker container

#### Objectives

* Host a simple Docker container through the Docker CLI

{% hint style="success" %}
TensorDock operating system templates come preinstalled with Docker
{% endhint %}

#### Process

For networking, we forward an external port into an internal port in the virtual machine. Then, a Docker container forwards a virtual machine's port into its own internal network.&#x20;

By default, the NGINX webserver listens on port 80 within the Docker container, but we can have the Docker container listen on any port. As such, we'll first forward an external port (e.g. 20018) into itself.&#x20;

<figure><img src="/files/cENDR6qbIb7QpfUARVia" alt=""><figcaption><p>We'll forward an external port into an internal port on the virtual machine</p></figcaption></figure>

Then, we'll set this as our cloud-init script:

```bash
write_files:
  - path: /home/user/cloudinit_website/index.html
    permissions: '0644'
    content: |
      <html>
      <head>
        <title> TensorDock Marketplace VM </title>
      </head>
      <body style="font-family: 'Courier New', monospace;">
        <p> You've reached your <span style="color: green;">TensorDock</span> virtual machine!</p>
      </body>
      </html>
    owner: www-data:www-data
runcmd:
  - docker run -d --restart unless-stopped --stop-timeout 300 -v /home/user/cloudinit_website:/usr/share/nginx/html:ro -p 20018:80 --name default_container nginx
```

{% hint style="warning" %}
Note that we have our Docker container listen on port 20018 because we forwarded external port 20018 into the virtual machine on port 20018
{% endhint %}

#### Debrief

Explanation:

* First, our server will write a file to a new directory containing our custom HTML
* Then, our server will run a Docker container that passes through the directory of our HTML page into the NGINX contiainer
* When users access the external port 20018, our hypervisor forwards that to the virtual machine's port 20018, and then Docker forwards that to the NGINX container on port 80

Now, let's try accessing our web server!

<figure><img src="/files/BcHC3FIweiMz0sV7lxUG" alt=""><figcaption><p>Woohoo! It works!</p></figcaption></figure>


# File transferring with SCP and Rclone

Learn how to transfer files from your local computer to your remote computer using SCP and Rsync

SCP (secure copy) and rsync are popular ways to transfer files between different computers, such as from your local computer to your Tensordock instance or vice versa.

## Method 1: SCP

SCP (secure copy) is a command-line utility that allows you to securely copy files and directories between two locations.

With `scp`, you can copy a file or directory:

* From your local system to a remote system.
* From a remote system to your local system.
* Between two remote systems from your local system.

When transferring data with `scp`, both the files and password are encrypted so that anyone snooping on the traffic doesn’t get anything sensitive.

### SCP General Syntax

Before going into how to use the `scp` command, let’s start by reviewing the basic syntax.

The `scp` command syntax take the following form:

```sh
scp [OPTION] [user@]SRC_HOST:]file1 [user@]DEST_HOST:]file2
```

Copy

* `OPTION` - [scp options](https://linux.die.net/man/1/scp) such as cipher, ssh configuration, ssh port, limit, recursive copy …etc.
* `[user@]SRC_HOST:]file1` - Source file.
* `[user@]DEST_HOST:]file2` - Destination file

Local files should be specified using an absolute or relative path, while remote file names should include a user and host specification.

`scp` provides a number of options that control every aspect of its behavior. The most widely used options are:

* `-P` - Specifies the remote host ssh port.
* `-p` - Preserves files' modification and access times.
* `-q` - Use this option if you want to suppress the progress meter and non-error messages.
* `-C` - This option forces `scp` to compresses the data as it is sent to the destination machine.
* `-r` - This option tells `scp` to copy directories recursively.

### Before you begin

The `scp` command relies on `ssh` for data transfer, so it requires an ssh key or password to authenticate on the remote systems.

The colon (`:`) is how `scp` distinguish between local and remote locations.

To be able to copy files, you must have at least read permissions on the source file and write permissions on the target system.

{% hint style="danger" %}
**Warning:** Be careful when copying files that share the same name and location on both systems, `scp` will overwrite files without warning.
{% endhint %}

When transferring large files, it is recommended to run the `scp` command inside a [screen](https://linuxize.com/post/how-to-use-linux-screen/) or [tmux](https://linuxize.com/post/getting-started-with-tmux/) session.

#### Copy a Local File to a TensorDock instance <a href="#copy-a-local-file-to-a-remote-system-with-the-scp-command" id="copy-a-local-file-to-a-remote-system-with-the-scp-command"></a>

To copy a file from a local to a TensorDock instance run the following command:

```bash
$ scp -P 12345 file.txt remote_username@10.10.0.2:/remote/directoryCopy
```

Where `file.txt` is the name of the file we want to copy, `remote_username` is the user on the remote server (likely `user`), `10.10.0.2` is the server IP address. The `/remote/directory` is the path to the directory you want to copy the file to. If you don’t specify a remote directory, the file will be copied to the remote user home directory.

Omitting the filename from the destination location copies the file with the original name. If you want to save the file under a different name, you need to specify the new file name:

Because TesnorDock's SSH is listening on a forwarded port (rather than the default 22) we will have to specify the port using the `-P` argument. You can see in Figure 1 that port `20496` forwards to `22`, so we will include `-P 20496` in our scp command, as seen in Figure 2.

You will be prompted to enter the user password, and the transfer process will start.

<figure><img src="/files/nTUoZtKW2uIHcgIe8k5e" alt=""><figcaption><p>Figure 1: We can see that port 20496 forwards to 22</p></figcaption></figure>

<figure><img src="/files/LtA42LL2slEUl93DjBzF" alt=""><figcaption><p>Figure 2: Here we copy a secret file onto a TensorDock instance using the forwarded port 20496</p></figcaption></figure>

<figure><img src="/files/jVUlidlFsQzBysDQ1Mcq" alt=""><figcaption><p>Figure 3: Our TensorDock instance has received the secret file</p></figcaption></figure>

The command to copy a directory is similar to copying files. The only difference is that you need to use the `-r` flag for recursive.

To copy a directory from a local to remote system, use the `-r` option:

```bash
$ scp -P 12345 -r /local/projects remote_username@10.10.0.2:/remote/projects
```

#### Copy a TensorDock instance file to your local system

To copy a file from a TensorDock instance to a local system, use the remote location as the source and local location as the destination.

For example to copy a file named `file.txt` from a remote server with IP `10.10.0.2` run the following command:

<pre class="language-bash"><code class="lang-bash"><strong>$ scp -P 12345 remote_username@10.10.0.2:/remote/file.txt /local/directoryCopy
</strong></code></pre>

Don't forget to include the `-P` option for port forwarding like in the previous section

You will again be asked to enter your password.

<figure><img src="/files/wF5so4bgeO2RYtd4E1Yt" alt=""><figcaption><p>Example of copying a file from the TensorDock instance to your local computer</p></figcaption></figure>

## Method 2: Rclone

Rclone is a command-line program to manage files on cloud storage. It is a feature-rich alternative to cloud vendors' web storage interfaces. [Over 70 cloud storage products](https://rclone.org/#providers) support rclone including S3 object stores, business & consumer file storage services, as well as standard transfer protocols.

In this tutorial we will teach you how to use rclone on your Google Drive to transfer/sync files to your TensorDock instance.

### Installing Rclone

Install rclone on your local computer.

To install rclone on Linux/macOS/BSD systems, run:

```bash
sudo -v ; curl https://rclone.org/install.sh | sudo bash
```

For beta installation, run:

```bash
sudo -v ; curl https://rclone.org/install.sh | sudo bash -s beta
```

Note that this script checks the version of rclone installed first and won't re-download if not needed.

<figure><img src="/files/FsViEHafSwvSGyhriExx" alt=""><figcaption></figcaption></figure>

If this does not work for you, refer to <https://rclone.org/install/> for more information on installation.

### Configuring rclone

To configure rclone, we will first configure it on our local computer and then transfer the configuration file to our TensorDock instance.

Once installed, enter `rclone config`to configure a new remote. Enter "n" to create a new remote and follow the prompts.

<figure><img src="/files/62TdZUqERTu6XcXmMG9l" alt=""><figcaption></figcaption></figure>

`name`: Name the remote something informative, e.g., "google-drive".

`Storage`: After choosing a name, the next prompt should be a long numbered menu with different storage solutions. Look for Google Drive and enter the associated number.

`client_id`and `client_secret`: The next prompts are Google Application Client ID `client_id`and Google Application Client Secret `client_secret`. Leave both prompts blank by pressing "Enter" to accept the default values. Rclone's default client ID is shared by all users of rclone, possibly resulting in slow performance. It is recommended to create your own client ID instead. Instructions for this can be found [here](https://rclone.org/drive/#making-your-own-client-id).

`scope`: Choose "1" to allow access to all files.

`service_account_file`: Leave this blank by pressing "Enter" to use interactive login.

`Edit advanced config? (y\n)`: Enter "n".

`Use auto config?`: Enter "y".

Your browser should then open a new page. Log in to your Google Account if needed and authorize the rclone app for access.

`Configure this as a Shared Drive (Team Drive)?`: Enter "n" if it is a personal drive. Enter "y" if it is a shared drive.

You should then see a configuration complete message and a copy of the configuration settings.

`Keep this "google-drive" remote?`: Enter "y" if all the information was entered correctly.

Enter "q" to exit the main `rclone config`menu.

<figure><img src="/files/kxOJSsIHOanQ5K5mFKmV" alt=""><figcaption></figcaption></figure>

#### Copying config file to TensorDock instance

First, make sure you have rclone installed on your TensorDock instance, and if it is not, use the above instructions to install rclone on your TensorDock instance

Find the config file by running `rclone config file`, for example

<figure><img src="/files/Ctpg7ll7lhKgHdbUKUq9" alt=""><figcaption></figcaption></figure>

Run the `rclone config file` on the TensorDock instance to find out where to transfer your config.

<figure><img src="/files/LAi2kmJ7dUs3458Khdei" alt=""><figcaption></figcaption></figure>

Now transfer it to the remote box (scp, cut paste, ftp, sftp, etc.) and place it in the correct place (use rclone config file on the TensorDock instance to find out where). For example:

```
$ scp -P 12345 /home/user/.rclone.conf user@tensordock.com:/home/user/.config/rclone/rclone.conf
```

Once copied to the correct location, you can then test the connection by listing files in the remote. For example:

```
rclone lsd "google-drive:"
```

Be sure to include the `:` in the directory name, as this indicates that you are using a remote box.

Once copied to the correct location, you can then test the connection by listing files in the remote. For example:

```
rclone lsd "google-drive:"
```

![](/files/gaqv4offfZ9YDagUFMxl)

### Using Rclone

You have now set up rclone on your TensorDock instance!

You can now treat your remote box similar to how you would a virtual machine.

You can also copy files very similar to scp, with instructions here: <https://rclone.org/commands/rclone_copy/>


# Running Jupyter Notebook

Learn how to run Jupyter Notebook using TensorDock ML

## Deploy your Cloud GPU

You can deploy a GPU on our [Marketplace](https://marketplace.tensordock.com/order_list) to your specific configurations based on cost, RAM, storage, and vCPUs.&#x20;

Select any TensorML installation (any of the first row in the following image). Note the required amount of disk space required for the installation.

<figure><img src="/files/FxmvFce7wgsEJWIytthO" alt=""><figcaption></figcaption></figure>

## Running Jupyter Notebook

First, SSH into your TensorDock instance. Refer to [this tutorial](https://docs.tensordock.com/marketplace/how-to-ssh-into-your-instance) if you do not know how.

Type the following command in your TensorDock instance to run Jupyter Notebook:

```bash
$ jupyter notebook --ip=0.0.0.0
```

Now, in your local computer, open your browser of choice and in the URL, enter `ip:[port forwarded into 8888]`

For example, in this instance, your URL should be `123.12.123.12:20297.`

<figure><img src="/files/TpXOz65n4lLOFlEXPUcX" alt=""><figcaption></figcaption></figure>

You will notice that a Token is required to access Jupyter Notebook

<figure><img src="/files/gpEMnLn5HvbSX0ImwbMl" alt=""><figcaption></figcaption></figure>

In your TensorDock instance, you will find the token in the provided URLs (in this example, the third URL has `token=XXXXXXX` which is the token we want to paste into the Jupyter Notebook in our local browser.

Do not paste the URL that is instructed as it is the wrong IP address, as you should be using the URL from the previous step.

<figure><img src="/files/Db1s2FfzfqTfw8BE7uzB" alt=""><figcaption></figcaption></figure>

Enter the token into Jupyter Notebook. Success! You have logged into Jupyter Notebook on your TensorDock instance.

<figure><img src="/files/ZG9ELAhpBMlJXoKY2svz" alt=""><figcaption></figcaption></figure>


# SSH server hardening on Ubuntu

Learn how to make your servers more secure using SSH hardening

## Preface: Security

Generally, intrusions only occur on ports that are actively serving requests. This might be port 22 (if you are using a standard SSH port), as well as port 80/443 if you are serving a web application. All requests to other ports would automatically be dropped given there is no service listening on those ports.&#x20;

To secure your server, you should focus on limiting access to the services that listen to ports. In this tutorial, we'll secure SSH access, but these principles also apply to all other services that you may run on your server.&#x20;

## Introduction

We include OpenSSH server on every TensorDock virtual machine. OpenSSH is the default SSH server software that is used within Ubuntu, Debian, CentOS, FreeBSD, and many other Linux-based systems.

It is important to properly secure your OpenSSH server, as it is the gateway for anyone to enter server. In this tutorial, you will learn about hardening your OpenSSH server by using different configuration options to ensure that remote access to your server is as secure as possible.

## Step 1: Setting up your TensorDock server

You can deploy a GPU on our [Marketplace](https://marketplace.tensordock.com/order_list) to your specific configurations based on cost, RAM, storage, and vCPUs. You can use either Ubuntu 20.04 or Ubuntu 22.04 as your installation.

<figure><img src="/files/KK8HllOvPGJk5RX5ZxIM" alt=""><figcaption></figcaption></figure>

## Step 2: General Hardening

In order to start securing your SSH server, we will start with a general secure configuration that will suit the majority of servers. Some advanced users may prefer to configure their servers depending on their own threat model and risk threshold, which is beyond the scope of this tutorial.

Most hardening configurations for OpenSSH will be using the standard OpenSSH server configuration file, located at `/etc/ssh/sshd_config`.&#x20;

### Create a configuration file backup

Before you continue with this tutorial, it is best practice to take a backup of your existing configuration file, in case something goes wrong. Use the following command to do this:&#x20;

```sh
$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
```

This saves a backup of the file to `/etc/ssh/sshd_config.bak`.

### Editing and testing settings

We can review the current options that are set using this command which runs the OpenSSH server in extended test mode, which will validate the full configuration file and print out the effective configuration values:

```sh
$ sudo sshd -T
```

You can now open the configuration file using your preferred text editor and begin implementing the initial hardening measures:

```bash
$ sudo nvim /etc/ssh/sshd_config
```

<figure><img src="/files/a9nC4GCLfGrMRTeDi2oB" alt=""><figcaption></figcaption></figure>

When editing your configuration file, some options will be commented out by default using a single hash character (`#`) at the start of the line, which can be seen above. In order to edit these options and/or have the commented option be recognized, you will have to uncomment them by removing the hash.

### Basic SSH hardening (Recommended)

First, disable logging in via SSH as the root user by setting the following option:

```
PermitRootLogin no
```

We do this as it will prevent a potential attacker from logging in directly as root. Virtual machines do not include root users by default, but as a good measure, we'll prevent root user login in case you define a root user later on.&#x20;

Next, limit the maximum number of authentication attempts for a particular login session by changing the following:

```
MaxAuthTries 3
```

Generally, a value of `3` is acceptable for most setups, but you can set this higher or lower if you'd like. However, setting a value too low may prove problematic; if you fail to enter your password correctly three times in a row, you'll be blocked from SSH'ing onto your server via fail2ban, which we include on all of our Linux operating system templates.&#x20;

If required, you can also set a reduced login grace period, which is the amount of time a user has to complete authentication after initially connecting to your SSH server:

```
LoginGraceTime 20
```

This is automatically specified as seconds, unless otherwise specified.

Setting this to a lower value helps to prevent certain [denial-of-service attacks](https://www.cloudflare.com/learning/ddos/glossary/denial-of-service/) where multiple authentication sessions are kept open for a prolonged period of time.

### SSH Key Authentication (Optional)

SSH keys are another method to authenticate a remote connection into a server. Learn more [here](https://help.ubuntu.com/community/SSH/OpenSSH/Keys).&#x20;

First, if you haven't already, you'll need to define an SSH key pair. Read more on how to do so [here](https://docs.oracle.com/en/cloud/cloud-at-customer/occ-get-started/generate-ssh-key-pair.html#GUID-8B9E7FCB-CEA3-4FB3-BF1A-FD3406A2432F).&#x20;

Then, you'll need to transfer your computer's public key to the TensorDock server. You can do this by running the following command from your own computer:

```
ssh-copy-id user@<TENSORDOCK IP>
```

If you have configured SSH keys for authentication, rather than using passwords, disable SSH password authentication to prevent leaked user passwords from allowing an attacker to log in:

```
PasswordAuthentication no
```

As a further hardening measure related to passwords, you may also wish to disable authentication with empty passwords. This will prevent logins if a user’s password is set to a blank or empty value:

```
PermitEmptyPasswords no
```

### Disable other authentication methods (Optional)

In the majority of use cases, SSH will be configured with public key authentication as the only in-use authentication method. However, OpenSSH server also supports many other authentication methods, some of which are enabled by default. If these are not required, you can disable them to further reduce the attack surface of your SSH server:

```
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
```

If you’d like to know more about some of the additional authentication methods available within SSH, you may wish to review these resources:

* [Challenge Response Authentication](https://en.wikipedia.org/wiki/Challenge%E2%80%93response_authentication)
* [Kerberos Authentication](https://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch11_04.htm)
* [GSSAPI Authentication](https://www.ssh.com/manuals/clientserver-product/52/Secureshell-gssapiuserauthentication.html)

X11 forwarding allows for the display of remote graphical applications over an SSH connection, but this is rarely used in practice. It is recommended to disable it if it isn’t needed on your server:

```
X11Forwarding no
```

OpenSSH server allows connecting clients to pass custom environment variables, that is, to set a `$PATH` or to configure terminal settings. However, like X11 forwarding, these are not commonly used, so can be disabled in most cases:

```
PermitUserEnvironment no
```

If you decide to configure this option, you should also make sure to comment out any references to `AcceptEnv` by adding a hash (`#`) to the beginning of the line.

Next, you can disable several miscellaneous options related to tunneling and forwarding if you won’t be using these on your server:

```
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no
```

Finally, you can disable the verbose SSH banner that is enabled by default, as it shows various information about your system, such as the operating system version:

```
DebianBanner no
```

Note that this option most likely won’t already be present in the configuration file, so you may need to add it manually.&#x20;

### Saving and applying changes

Save and exit the file once you’re done. You can now validate the syntax of your new configuration by running `sshd` in test mode:

```bash
$ sudo sshd -t
```

If your configuration file has a valid syntax, there will be no output. In the event of a syntax error, there will be an output describing the issue.

<figure><img src="/files/DhzvdZqcwe7O0UuiO23p" alt=""><figcaption></figcaption></figure>

Once you’re satisfied with your configuration file, you can reload `sshd` to apply the new settings:

```bash
$ sudo service sshd reload
```

In this step, you completed some general hardening of your OpenSSH server configuration file. Next, you’ll implement an IP address allowlist to further restrict who can log in to your server.

## Step 4: Implementing an IP Address Allowlist

You can use IP address allowlists to limit the users who are authorized to log in to your server on a per-IP address basis. In this step, you will configure an IP allowlist for your OpenSSH server.

In many cases, you will only be logging on to your server from a small number of known, trusted IP addresses. For example, your home internet connection, a corporate VPN appliance, or a static [jump box](https://en.wikipedia.org/wiki/Jump_server) or [bastion host](https://en.wikipedia.org/wiki/Bastion_host) in a data center.

By implementing an IP address allowlist, you can ensure that people will only be able to log in from one of the pre-approved IP addresses, greatly reducing the risk of a breach in the event that your private keys and/or passwords are leaked.

{% hint style="info" %}
**Note:** Please take care in identifying the correct IP addresses to add to your allowlist, and ensure that these are not reserved or dynamic addresses that may regularly change, for example as is often seen with consumer internet service providers.
{% endhint %}

You can identify the IP address that you’re currently connecting to your server with by using the `w` command:

```
$ w
```

This should output something similar to the following:

```bash
Output
 14:11:48 up 2 days, 12:25,  1 user,  load average: 0.00, 0.00, 0.00
         USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
your_username     pts/0    203.0.113.1     12:24    1.00s  0.20s  0.00s w
```

Locate your user account in the list and take a note of the connecting IP address. Here we use the example IP of `203.0.113.1`

In order to begin implementing your IP address allowlist, open the OpenSSH server configuration file in your favorite text editor:

```bash
$ sudo nvim /etc/ssh/sshd_config
```

You can implement IP address allowlists using the `AllowUsers` configuration directive, which restricts user authentications based on username and/or IP address.

Your own system setup and requirements will determine which specific configuration is the most appropriate. The following examples will help you to identify the most suitable one:

When you have found your appropriate use case, add it to the bottom of your OpenSSH server configuration file.

* Restrict all users to a specific IP address:

```
AllowUsers *@203.0.113.1
```

* Restrict all users to a specific IP address range using [Classless Inter-Domain Routing (CIDR) notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing):

```
AllowUsers *@203.0.113.0/24
```

* Restrict all users to a specific IP address range (using wildcards):

```
AllowUsers *@203.0.113.*
```

* Restrict all users to multiple specific IP addresses and ranges:

```
AllowUsers *@203.0.113.1 *@203.0.113.2 *@192.0.2.0/24 *@172.16.*.1
```

* Disallow all users except for named users from specific IP addresses:

```
AllowUsers sammy@203.0.113.1 alex@203.0.113.2
```

* Restrict a specific user to a specific IP address, while continuing to allow all other users to log in without restrictions:

```
Match User ashley
  AllowUsers ashley@203.0.113.1
```

{% hint style="danger" %}
**Warning:** Within an OpenSSH configuration file, all configurations under a `Match` block will only apply to connections that match the criteria, regardless of indentation or line breaks. This means that you must be careful and ensure that configurations intended to apply globally are not accidentally put within a `Match` block. It is recommended to put all `Match` blocks at the bottom/end of your configuration file to help avoid this.
{% endhint %}

<figure><img src="/files/vte8jV9bzSEVqyZe8woC" alt=""><figcaption></figcaption></figure>

Once you have finalized your configuration, add it to the bottom of your OpenSSH server configuration file as seen above.

Save and close the file, and then proceed to test your configuration syntax:

```bash
$ sudo sshd -t
```

If no errors are reported, you can reload OpenSSH server to apply your configuration:

```bash
$ sudo service sshd reload
```

In this step, you implemented an IP address allowlist on your OpenSSH server. Next, you will restrict the shell of a user to limit the commands that they are allowed to use.

## Step 5: (Optional/Advanced) Restricting the Shell of a User

In this step, you’ll look at the various options for restricting the shell of an SSH user.

In addition to providing remote shell access, SSH is also great for transferring files and other data, for example, via SFTP. However, you may not always want to grant full shell access to users when they only need to be able to carry out file transfers.

There are multiple configurations within OpenSSH server that you can use to restrict the shell environment of particular users. For instance, in this tutorial, we will use these to create SFTP-only users.

Firstly, you can use the `/usr/sbin/nologin` shell to disable interactive logins for certain user accounts, while still allowing non-interactive sessions to function, like file transfers, tunneling, and so on.

To create a new user with the `nologin` shell, use the following command:

```bash
$ sudo adduser --shell /usr/sbin/nologin alex
```

Alternatively, you can change the shell of an existing user to be `nologin`:

```bash
$ sudo usermod --shell /usr/sbin/nologin sammy
```

If you then attempt to interactively log in as one of these users, the request will be rejected:

```bash
$ sudo su alex
```

This will output something similar to the following message:

```
Output
This account is currently not available.
```

Despite the rejection message on interactive logins, other actions such as file transfers will still be allowed.

Next, you should combine your usage of the `nologin` shell with some additional configuration options to further restrict the relevant user accounts.

Begin by opening the OpenSSH server configuration file in your favorite text editor again:

```bash
$ sudo nano /etc/ssh/sshd_config
```

There are two configuration options that you can implement together to create a tightly restricted SFTP-only user account: `ForceCommand internal-sftp` and `ChrootDirectory`.

The `ForceCommand` option within OpenSSH server forces a user to execute a specific command upon login. This can be useful for certain machine-to-machine communications, or to forcefully launch a particular program.

However, in this case, the `internal-sftp` command is particularly useful. This is a special function of OpenSSH server that launches a basic in-place SFTP daemon that doesn’t require any supporting system files or configuration.

This should ideally be combined with the `ChrootDirectory` option, which will override/change the perceived root directory for a particular user, essentially restricting them to a specific directory on the system.

Add the following configuration section to your OpenSSH server configuration file for this:

```
Match User alex
  ForceCommand internal-sftp
  ChrootDirectory /home/alex/

```

{% hint style="danger" %}
**Warning:** As noted in Step 2, within an OpenSSH configuration file, all configurations under a `Match` block will only apply to connections that match the criteria, regardless of indentation or line breaks. This means that you must be careful and ensure that configurations intended to apply globally are not accidentally put within a `Match` block. It is recommended to put all `Match` blocks at the bottom/end of your configuration file to help avoid this.
{% endhint %}

Save and close your configuration file, and then test your configuration again:

```bash
$ sudo sshd -t
```

If there are no errors, you can then apply your configuration:

```bash
$ sudo service sshd reload
```

This has created a robust configuration for the `alex` user, where interactive logins are disabled, and all SFTP activity is restricted to the home directory of the user. From the perspective of the user, the root of the system, that is, `/`, is their home directory, and they will not be able to traverse up the file system to access other areas.

You’ve implemented the `nologin` shell for a user and then created a configuration to restrict SFTP access to a specific directory.

## Conclusion

In this article, you reviewed your OpenSSH server configuration and implemented various hardening measures to help secure your server.

This will have reduced the overall attack surface of your server by disabling unused features and locking down the access of specific users.

You may wish to review the [manual pages for OpenSSH server](https://linux.die.net/man/8/sshd) and its associated [configuration file](https://linux.die.net/man/5/sshd_config), to identify any potential further tweaks that you want to make.


# Running Stable Diffusion in Docker

Stable Diffusion is a deep learning, text-to-visual model that allows programs and projects that can use test descriptions to generate paintings and images.

## Getting Started

Begin by registering for TensorDock Marketplace and selecting a GPU with at least 10 GB of memory to launch an instance.&#x20;

<figure><img src="/files/oZsMmMmwWzrfOZS91YVI" alt=""><figcaption></figcaption></figure>

We will be using a Ubuntu instance for this tutorial. Select an external port that maps to the internal port 22. This will allowing SSHing into the instance.

<figure><img src="/files/kihkF5urQeIUMfpmpDZu" alt=""><figcaption></figcaption></figure>

Finish up your server by setting a secure username and password.

## SSH into the server

On the information page for your instance, you can find the necessary IPv4 address and command to SSH through the command line.

<figure><img src="/files/T3xfbdJWd1ReH5U2XC94" alt=""><figcaption></figcaption></figure>

Using the command, you can SSH into your server. Through command line, you will need to enter your username and password which will then grant you access to the GPU and using it for stable diffusion!

## Using Docker and Docker Networking

Docker comes default in all TensorDock instances, however by adding Docker Networking, you can make external requests needed for stable diffusion. First, clone the following git repo and cd into that directory.

`git clone https://github.com/monatis/stable-diffusion-tf-docker.git && cd stable-diffusion-tf-docker`

Then, we will add the `daemon.json` file and restart the docker service.

`sudo cp ./daemon.json /etc/docker/daemon.json`

`sudo systemctl restart docker.service`

### Setting up Docker Compose

With Docker Compose, we can create a `docker-compose.yml` file that will look to a specified port variable for the GPU. On whatever external port you chose to forward to port 22, run

&#x20;`export PUBLIC_PORT= *your port number here*`

`docker compose up -d`

Once it’s up and running, go to `http://mass-a.tensordockmarketplace.com:*port number*/docs` for the Swagger UI provided by FastAPI. Using the `POST /generate` endpoint, you can generate your image and its download id. You can download it with GET `/download/<download_id>` .


# Installing and running Stable Diffusion UI

Stable Diffusion UI is a browser interface based on Gradio library for Stable Diffusion.

For more information about Stable Diffusion UI, see [this](https://github.com/AUTOMATIC1111/stable-diffusion-webui).

## Step 1: Deploy your Cloud GPU

You can deploy a GPU on our [Marketplace](https://marketplace.tensordock.com/order_list) to your specific configurations based on cost, RAM, storage, and vCPUs. Select Windows 10 as your installation.

Stable Diffusion UI works with both NVIDIA and AMD GPUs, but NVIDIA is preferred

<figure><img src="/files/6s6azjYlH8Z3NTso8TYx" alt=""><figcaption><p>Ensure that you have selected Windows 10 as your installation</p></figcaption></figure>

## Step 2: RDP into your instance

Follow [this tutorial](https://docs.tensordock.com/marketplace/how-to-rdp-into-your-instance) to RDP into your Cloud GPU.

## Step 3: Install and run Stable Diffusion UI

**On your Remote Desktop**, perform the following:

1. Install [Python 3.10.6](https://www.python.org/ftp/python/3.10.6/python-3.10.6-amd64.exe) (Newer versions of Python do not support torch), and make sure to check "Add Python to PATH".
2. Install [git](https://github.com/git-for-windows/git/releases/download/v2.39.2.windows.1/Git-2.39.2-64-bit.exe).
3. Open Command Prompt from search bar, and type&#x20;

   `git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui`
4. Double click the `run.bat` in your File Explorer to launch web UI, during the first launch it will download large amounts of files. After everything has been downloaded and installed correctly, you should see a message "`Running on local URL: http://127.0.0.1:7860`", opening the link will present you with the web UI interface.

<figure><img src="/files/GoJTNVMDJtyK5hrQyRsr" alt=""><figcaption><p>Double click on the webui-user bat file in your file explorer. No need to run as administrator.</p></figcaption></figure>

<figure><img src="/files/DqKkK5GjpdUvphHqiTzQ" alt=""><figcaption><p>After all the installations are finished, look for the URL that the Web UI will be run on, in this case <code>http://127.0.0.1:7860</code></p></figcaption></figure>

<figure><img src="/files/3ANHSWkGUZq3YV9r55dx" alt=""><figcaption><p>You can now open the URL in your web browser and use Stable Diffusion UI</p></figcaption></figure>


# Running Disco Diffusion on a Linux instance

Disco Diffusion (aka DD) is a clip-guided diffusion model that can generate amazing images from text prompt

## Deploy your Cloud GPU

You can deploy a GPU on our [Marketplace](https://marketplace.tensordock.com/order_list) to your specific configurations based on cost, RAM, storage, and vCPUs.&#x20;

Select any TensorML PyTorch installation (or TensorML Everything). Note the required amount of disk space required for the installation.

<figure><img src="/files/whaft5L4Hswok2VUTm1X" alt=""><figcaption></figcaption></figure>

## Install dependencies

Create and activate a conda environment (inside Ubuntu) with all the appropriate dependencies.

```
conda create -n pytorch_110
conda activate pytorch_110
```

Whenever you restart your computer, or close and open Ubuntu again, you will have to run that second command (`conda activate pytorch`). Now install the correct version of pytorch:

```
conda install pytorch==1.10 torchvision torchaudio cudatoolkit==11.1 -c pytorch -c conda-forge
```

Type y whenever prompted.

Now install some other dependencies:

```
conda install jupyter pandas requests matplotlib
conda install opencv -c conda-forge
```

## Install Disco Diffusion

You can easily install Disco Diffusion on your TensorDock instance with `git clone`

```bash
$ git clone https://github.com/MohamadZeina/Disco_Diffusion_Local
```

## Run on Jupyter Notebook

Follow [this tutorial](https://docs.tensordock.com/marketplace/running-jupyter-notebook) to open your Disco Diffusion `.ipynb` on Jupyter Notebook

<figure><img src="/files/tEdBUI9F1O6gl2P3ZBBO" alt=""><figcaption><p>Any of the .ipynb files are valid versions of Disco Diffusion</p></figcaption></figure>

<figure><img src="/files/ixV25OShydqRDzEna7Ah" alt=""><figcaption></figcaption></figure>

## Using Disco Diffusion

Congratulations! You have set up Disco Diffusion on your TensorDock instance and it ready to be run.

For examples of how to use, follow any of these tutorials:

* <https://www.youtube.com/watch?v=3FVW3ewlTh0>
* <https://www.youtube.com/watch?v=1Gp5l9EUX9I>


# Running Disco Diffusion on a Windows instance

Disco Diffusion (aka DD) is a clip-guided diffusion model that can generate amazing images from text prompt

Disco Diffusion can be found at <http://discodiffusion.com/>

## Step 1: Deploy your Cloud GPU

You can deploy a GPU on our [Marketplace](https://marketplace.tensordock.com/order_list) to your specific configurations based on cost, RAM, storage, and vCPUs.

Disco Diffusion works on **NVIDIA GPUs** with at least **12 GB** of dedicated VRAM on a **Windows** OS, so make sure your Cloud GPU adheres to these settings. You will also need at least 80 GB in your Disk to run Windows.

<figure><img src="/files/1nNxrvXlVf5cZNT7NHsk" alt=""><figcaption><p>Ensure that you have at least 12 GB of dedicated RAM and 80 GB of disk storage</p></figcaption></figure>

<figure><img src="/files/Xl0IabqwSE1GRtK4J1Jj" alt=""><figcaption><p>Select Windows 10 as your installation</p></figcaption></figure>

## Step 2: RDP into your instance

Follow [this tutorial](https://docs.tensordock.com/marketplace/how-to-rdp-into-your-instance) to RDP into your Cloud GPU

## Step 3: Install required tools

In your **Remote Desktop**, download all of the following:

1. Cuda enabled GPU
   * Latest Nvidia Drivers
     * <https://www.nvidia.com/Download/index.aspx>
   * CUDA Toolkit for your version
     * <https://developer.nvidia.com/cuda-downloads>
     * <https://docs.nvidia.com/cuda/cuda-quick-start-guide>
2. Python (Anaconda)
   * <https://www.anaconda.com/products/individual#Downloads>
   * We use anaconda to make it easier to manage different projects
   * Virtual python evironment and versioning
   * Anaconda also includes Jupyter Notebook pre-installed
3. Git
   * <https://git-scm.com/downloads>
   * version control manager for code
   * we just use it to download repos from GitHub
   * When installing select the option add to system PATH
4. FFmpeg
   * <https://ffmpeg.org/download.html>
   * Video encoding tool library
   * we use this mainly to turn image sequences into videos
   * Must be on system PATH
     * <https://www.wikihow.com/Install-FFmpeg-on-Windows>
5. ImageMagick
   * <https://imagemagick.org/script/download.php>
   * software suite for displaying, creating, converting, modifying, and editing raster images.
   * used in some projects but handy to have already installed
6. Wget
   * used to download models for projects
   * Windows users need this verison
     * <https://eternallybored.org/misc/wget/>
       * download the .exe
       * create a new folder to put the .exe in (prefereable on the root of your C:/ drive)
         * e.g `C:/wget/wget.exe`
       * open Control Panel and search for `environment variables`
       * select the one with the shield icon `Edit the system environment variables`
       * click the button at the bottom `Environment Virables...`
       * under `System variables` find the and select the `path` variable
       * click `Edit...` button and then `New`
         * add the new path to folder the .exe is in
         * e.g `C:/wget`
       * once entered click `Ok` on each window until all 3 are closed
       * for the new env variables to be used you must reopen a new Command Prompt window
7. cURL
   * used to download models, some projects use this instead of wget
   * Latest versions of windows have cURL pre installed
   * Older versions that dont include cURL use this one
     * <https://curl.se/windows/>
   * Linux users can just use the package in their distributions

## Step 4: Install dependencies

Run the following in powershell on your remote desktop:

1. Setup and activate conda env

* `conda create --name disco-diffusion python=3.9`
* `conda activate disco-diffusion`

2. Install a few more pip dependencies
   * `pip install ipykernel opencv-python pandas regex matplotlib ipywidgets`
3. Install Pytorch with CUDA support!
   * <https://pytorch.org/get-started/locally/>
   * be sure to install a version with GPU support!
   * example
     * `conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch`
4. Download disco diffusion repo
   * `git clone https://github.com/alembics/disco-diffusion.git`
   * change directories into the downloaded repo
     * `cd disco-diffusion`

## Step 5: Run Disco Diffusion

You can now use any of the following methods to run disco diffusion:

1. **\[PYTHON .py]**

plain python file wich means you will need to go into the file and manually find all the configuration options and change them as needed, an easy way to go about this is searching the document for `#@param` lines and edit ones containing that comment trailing the lines e.g. `use_secondary_model = True #@param {type: 'boolean'}`.

* Run disco diffusion
  * `python -m disco.py`

2. &#x20;**\[VS .py/.ipynb]**

running the .ipynb file directly in VS also requires editing of the `#@param` lines in the code

* Download Visual Studio
  * <https://code.visualstudio.com/download>
* Open the .ipynb file in VS
  * ENJOY!
  * for more interactivity see the tutorial using jupyter extension

3. **\[VS + Jupyter extension .py/.ipynb]**

using the jupyter extension in VS we can get individual cell support to run the either the .ipynb or the .py file also requires editing of the `#@param` lines in the code

* Download Visual Studio
  * <https://code.visualstudio.com/download>
* Get the Jupyter Notebook extensions
  * head over to the extensions tab in VS code
  * search for `jupyter` and install the one from Microsoft
  * after this is enabled the notebook should have several new toolbars and features
    * you can actually run both the .py file or .ipynb file which both support individual cells
  * ENJOY!

4. **\[Jupyter .ipynb]**

using Jupyter notebooks to run the .ipynb file also requires editing of the `#@param` lines in the code

* with anaconda installed you should already have jupyter notebook installed if you dont simple run:\
  `pip install jupyterlab`
* Run Jupyter
  * `jupyter notebook`
    * this launches the juptyer notebook in the current directory and open a webpage
  * under the `Files` tab double click and open the file named `Disco-Diffusion.ipynb`
  * ENJOY!

5. **\[Colab w/ Jupyter using colab links]**

using Google Colab as a front end to get the nice view of all the editable fields while using Jupyter as middleware to connect your local resources

* with anaconda installed you should already have jupyter notebook installed if you dont simple run:\
  `pip install jupyterlab`
* Connect to colab front end
  * `pip install --upgrade jupyter_http_over_ws>=0.0.7`
  * Enable the extension for jupyter
    * `jupyter serverextension enable --py jupyter_http_over_ws`
  * Start the jupyter server
    * `jupyter notebook --NotebookApp.allow_origin='https://colab.research.google.com' --port=8888 --NotebookApp.port_retries=0 --no-browser`
  * Inside google colab click the down Arrow icon next to the Connect button to view more options
  * Select connect to Local Runtime and enter the Local Host Url that was printed in the console when we started jupyter server
  * ENJOY!

***

You can now use Disco Diffusion on your Tensordock instance. For examples of how to use, follow any of these tutorials:

* <https://www.youtube.com/watch?v=3FVW3ewlTh0>
* <https://www.youtube.com/watch?v=1Gp5l9EUX9I>


# Running SimpleTuner/Flux on a Linux instance

Special thanks to https\://github.com/bghira/SimpleTuner/blob/main/documentation/quickstart/FLUX.md for much of this tutorial. A reminder that only basics are covered here.

Go to <https://dashboard.tensordock.com/deploy_preconfig> and select the 1x h100 configuration. Adding an ssh key is recommended:&#x20;

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXecYbP7c8WZhhTqzosb03arQSaXvjRffGmHpP7Y9xyxo1qm3IsgjyWG0ixwhg1Ko6XfYAxWW6emxt0dTFNjZ1ZHs9kfJm2leiKhZKtcJq53j_AY2yVKjROm_kTuMd04_YfCSCJdJKTTZgodS_an3eOInAo?key=QKFdx8mkaBXT9K48YmdCSQ" alt=""><figcaption></figcaption></figure>

Deploy and then SSH into the instance with the provided command. Once inside, you may see the following:

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXff3hPBDUclCaRzHBeH-x9ocitYQvVAxNxJook9rtgfj6NWkP6IBv3X9l89CSTHXyaMShIyA3mWjZ7jZadmJrIMWu9uuZfaoRXaKQe9oIwvlXJb0tdoO6oxYg0Ba3TtmCKFlAPB2G-JzmB4spTM1y2jh8g?key=QKFdx8mkaBXT9K48YmdCSQ" alt=""><figcaption></figcaption></figure>

Run "sudo reboot". This will restart to the VM. Wait a couple minutes and connect again. Once you are back in run "sudo apt update" and "sudo apt upgrade" in that order. You might come across this screen:&#x20;

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXf4G2P4AmOoFF71KGjYcqBrpFlLNJ7Nqo0uBLvuasgc-QGbZkXqoFRvIOCjniCVZGyJEvdG8u7HSnovoXeku49SeA5-eAR8LWiZcR9avLSg-jT11rAlDQGasDxaNAj2lXfHkMNdofl4I9zb1AZx1JRdZ8U?key=QKFdx8mkaBXT9K48YmdCSQ" alt=""><figcaption></figcaption></figure>

Use your tab key to navigate to "\<Ok>" and press enter to continue. Now use

```
python --version
```

You should be using python 3.11 or 3.10. Now you should run the following command:

```
sudo apt -y install nvidia-cuda-toolkit libgl1-mesa-glx
```

If that is not found, then run this instead:

```
sudo apt -y install nvidia-cuda-toolkit libgl1-mesa-dri
```

With all this set up, now we can clone the SimpleTuner repository and set up a virtual environment. Run the following commands:

```
git clone --branch=release https://github.com/bghira/SimpleTuner.git

cd SimpleTuner

# if python --version shows 3.11 you can just also use the 'python' command here.
python3.11 -m venv .venv

source .venv/bin/activate

pip install -U poetry pip

poetry install --no-root

```

Flux needs a more specific version of diffusers.&#x20;

```
pip uninstall diffusers

pip install git+https://github.com/huggingface/diffusers
```

Now that we have our dependencies, we can set up SimpleTuner itself with a configuration process. First create a configure.py file in the SimpleTuner directory copying this one <https://github.com/bghira/SimpleTuner/blob/main/configure.py>. Run configure.py with&#x20;

```
python configure.py
```

It will ask you a series of questions. All of the actual configuration related questions have default answers. Use the default answers when possible. If you go to /config/config.env your config file should look like this:

```
RESUME_CHECKPOINT='latest'
DATALOADER_CONFIG='config/multidatabackend.json'
ASPECT_BUCKET_ROUNDING='2'
TRAINING_SEED='42'
USE_EMA='false'
USE_XFORMERS='false'
MINIMUM_RESOLUTION='0'
OUTPUT_DIR='output/models'
USE_DORA='false'
USE_BITFIT='false'
PUSH_TO_HUB='true'
PUSH_CHECKPOINTS='true'
MAX_NUM_STEPS='10000'
NUM_EPOCHS='0'
CHECKPOINTING_STEPS='500'
CHECKPOINTING_LIMIT='5'
HUB_MODEL_NAME='simpletuner-lora'
TRACKER_PROJECT_NAME='lora-training'
TRACKER_RUN_NAME='$(date +%s)'
DEBUG_EXTRA_ARGS='--report_to=wandb'
MODEL_TYPE='lora'
MODEL_NAME='black-forest-labs/FLUX.1-dev'
FLUX='true'
KOLORS='false'
STABLE_DIFFUSION_3='false'
STABLE_DIFFUSION_LEGACY='false'
FLUX_LORA_TARGET='all+ffs'
TRAIN_BATCH_SIZE='1'
USE_GRADIENT_CHECKPOINTING='true'
GRADIENT_ACCUMULATION_STEPS='2'
CAPTION_DROPOUT_PROBABILITY='0.1'
RESOLUTION_TYPE='area'
RESOLUTION='1024'
VALIDATION_SEED='42'
VALIDATION_STEPS='500'
VALIDATION_RESOLUTION='1024x1024'
VALIDATION_GUIDANCE='7.5'
VALIDATION_GUIDANCE_RESCALE='0.0'
VALIDATION_NUM_INFERENCE_STEPS='20'
VALIDATION_PROMPT='A photo-realistic image of a cat'
ALLOW_TF32='false'
MIXED_PRECISION='bf16'
OPTIMIZER='adamw_bf16'
LEARNING_RATE='8e-5'
LR_SCHEDULE='polynomial'
LR_WARMUP_STEPS='100'
ACCELERATE_EXTRA_ARGS=''
TRAINING_NUM_PROCESSES='1'
TRAINING_NUM_MACHINES='1'
VALIDATION_TORCH_COMPILE='false'
TRAINER_DYNAMO_BACKEND='no'
TRAINER_EXTRA_ARGS='--lora_rank=64 --lr_end=1e-8 --gradient_precision=unmodified --compress_disk_cache'
```

After that we can install the data set we will be using. First navigate to your output directory. If you used the defaults in the configuration step, then it should be called:

```
output/models
```

Create a file called multidatabackend.json (add this also to the SimpleTuner/config) take note that instance\_data\_dir will end up being the directory of your dataset and may vary if you input a custom output directory:

```
[
    {
        "id": "pseudo-camera-10k-flux",
        "type": "local",
        "crop": true,
        "crop_aspect": "square",
        "crop_style": "center",
        "resolution": 512,
        "minimum_image_size": 512,
        "maximum_image_size": 512,
        "target_downsample_size": 512,
        "resolution_type": "pixel",
        "cache_dir_vae": "cache/vae/flux/pseudo-camera-10k",
        "instance_data_dir": "/home/user/SimpleTuner/output/models/datasets/pseudo-camera-10k",
        "disabled": false,
        "skip_file_discovery": "",
        "caption_strategy": "filename",
        "metadata_backend": "json"
    },
    {
        "id": "text-embeds",
        "type": "local",
        "dataset_type": "text_embeds",
        "default": true,
        "cache_dir": "cache/text/flux/pseudo-camera-10k",
        "disabled": false,
        "write_batch_size": 128
    }
]
```

Now while you are still in your output directory, run the following commands to install the dataset:

<pre><code><strong>sudo apt -y install git-lfs
</strong>mkdir -p datasets
pushd datasets
    git clone https://huggingface.co/datasets/ptx0/pseudo-camera-10k
popd
</code></pre>

Now go back to the main SimpleTuner directory and run this command:

```
bash train.sh
```


# Spot Instances

{% hint style="info" %}
Spot instances are in beta. Expect higher risk of bugs.
{% endhint %}

## Understanding Priority

When you deploy a spot instance, you first set a bid price.

{% hint style="info" %}
Storage prices are billed at the standard rate, and are added atop the compute price that you bid. If you bid a price for $0.35/hr with 200GB of storage at $0.00005/GB/hr, then your total cost will be $0.36/hr when the workload is running and $0.01/hr when outbid.
{% endhint %}

The bid price you set is per-virtual machine, not per GPU. We prioritize workloads for max revenue, not the per-GPU price. For instance, if there are these bids for an 8x H100 machine:

* $3.00/hr for 1x H100 ($3.00/hr per H100)
* $4.00/hr for 8x H100 ($0.50/hr per H100)

Then the 8x H100 will be prioritized because the overall revenue is higher, even though it has a lower per-GPU price.

However, if there are these bids for a 3x A6000 machine:

* $3.00/hr for 1x H100&#x20;
* $1.10/hr for 1x H100
* $4.00/hr for 8x H100

Then the first and second VMs will win the instance, because the combined revenue of those two VMs ($4.10/hr) is greater than the revenue of the third VM ($3.00/hr).&#x20;

{% hint style="info" %}
Note that these are for illustrative purposes only. Each host has a minimum bid price set per GPU, typically around 50% of the on-demand price.&#x20;
{% endhint %}

Because we optimize for aggregate revenue and not per-unit revenue, we expect consumer cards and older enterprise GPUs may have great price-to-performance, since there will be less bidders.

## Deploying Spot Instances

<figure><img src="/files/jN7BNcBprIwZJqHfXbl3" alt=""><figcaption></figcaption></figure>

First, deploy an on-demand VM and click it in the "Your Servers" page to convert it to a spot instance. Set the following fields in your API request:

* `price_type`: `spot`
* `price`: \[your bid]

## Managing Interruptible Instances

<figure><img src="/files/NmoejpydJJ4lhpMBYPgO" alt=""><figcaption></figcaption></figure>

Interruptible instances will appear within your dashboard like the image above.

## Notes

Interruptible instances are only available on GPU instances, and storage costs are billed at the standard storage price set by the host. There is no "spot storage" tier, so to speak.&#x20;


# Using Parsec, Moonlight and Sunshine

## Solutions to Common Issues

**Hardware Encoding**: If Parsec, Moonlight, or Sunshine fail to use hardware encoding when a GPU is available, and hardware encoding isn't visible in the settings, this is because you need to install a [virtual monitor](https://github.com/VirtualDisplay/Virtual-Display-Driver/releases/tag/24.12.24), so the GPU can display to that virtual monitor for Parsec.

**Black Screen:** If connecting with Parsec, Moonlight, or Sunshine creates a black screen with no error message,

1. Make sure the Parsec window is focused.
2. Press CTRL + SHIFT + I to enter Interactive Mode.
3. Once connected, you can exit Interactive Mode by pressing CTRL + SHIFT + I again.
4. Press the Windows Key + P, press the Down Arrow key twice, and then Enter. This should make the VM's screen appear on Parsec.

**Error codes 6023 and 6024:** Unable To Negotiate A Successful Connection\
\
[ZeroTier ](https://www.zerotier.com/download)works as a fix. More details can be found in the [Parsec Article](https://support.parsec.app/hc/en-us/articles/115002766652-Using-a-VPN-ZeroTier-to-Connect-on-Parsec).\
\
**Error code -14003: "**&#x57;e were unable to capture the screen of the computer you were attempting to connect"\
\
Ensure your RDP connection is closed before connecting with Parsec, Moonlight, or Sunshine.

## Installing Parsec

If Parsec needs to be updated, you can first try [Parsec's custom installer](https://support.parsec.app/hc/en-us/articles/18238357621773-Loader-and-Service-update-for-Parsec-150-88-or-later). If that doesn't work, follow these instructions to perform a complete reinstall.

First, uninstall the current Parsec. Then, locate the "Downloads" folder in the virtual machine. There should be an installer for Parsec already present (parsec-windows.exe). Run that. If not, [Download Parsec](https://parsec.app/) from the website.&#x20;

Parsec setup instructions will pop up. First, you will choose which components of Parsec to install. Make sure the Parsec App and Virtual Display Driver are selected, then press Next.

<figure><img src="/files/pJYKxvz6sID03I7mBlyM" alt=""><figcaption><p>Make sure the Virtual Display Driver is also going to be installed</p></figcaption></figure>

Second, you will choose an installation type. Choose to download Parsec in "Per User mode" and press Next.

<figure><img src="/files/aETegLidjwE7Ca8A2bop" alt=""><figcaption><p>Download Parsec in Per User Mode</p></figcaption></figure>

Parsec will begin downloading; wait for this to finish. Note: Once downloaded, there may be a message saying that a reboot is required. You can ignore this for now, as we are doing that in a later step.

Now login with your Parsec account and click on the settings tab. Scroll down until you see "edit configuration file" at the bottom. Then, click on the "edit configuration file" link.

<figure><img src="/files/N07yADt5a2XE5EEBbYJt" alt=""><figcaption></figcaption></figure>

Paste in the following lines, if they don't exist already:

```
host_virtual_monitors = 1
host_privacy_mode = 1
```

<figure><img src="/files/aMhu0JZ8oJaSYV1PkVO7" alt=""><figcaption><p>The Parsec config file with the pasted lines</p></figcaption></figure>

Save the file and then quit Parsec from the system tray (quitting from within Parsec sometimes fails to save the configuration file).&#x20;

Open Parsec again and verify that the two lines are in the configuration file. If not, add them again, save, quit Parsec, and check. When it persists, reboot the VM. Now you can try out Parsec.


# Installation Guide

Ubuntu 22.04 is the operating system our hypervisor runs on. Here's how to properly configure the BIOS and install Ubuntu

1\. Create your server

Double check:

* You are not mixing-and-matching RAM
* You have an integrated graphics card, your motherboard includes a graphics device, OR you have an extra discrete GPU

## 2. Update BIOS Settings

First, hop into the machine's BIOS. For most servers, this will mean pressing down the delete key.&#x20;

<figure><img src="/files/srbzsrpQC0dxYTFoVUhf" alt=""><figcaption><p>Hop into the machine's BIOS</p></figcaption></figure>

### Enable Virtualization

This allows the CPU to be divided up into customer virtual machines.

In Asrock Rack and Supermicro motherboards, you'll find SVM (virtualization support for AMD CPUs) in Advanced --> CPU Configuration

<figure><img src="/files/4pBygxFgrQ4oolWqPz7k" alt=""><figcaption></figcaption></figure>

### Enable IOMMU / Above 4G Decoding and set VGA priority to onboard

This enables us to pass through GPUs into virtual machines.&#x20;

Also, enable SR-IOV support. While this is not required at the moment, our software will need this functionality in the future.&#x20;

In Asrock Rack motherboards, you'll find IOMMU in Advanced --> AMD CBS --> NBIO Common Options

<figure><img src="/files/0EMTR9zMbqSbb6MP2Ltk" alt=""><figcaption></figcaption></figure>

## 3. Install Ubuntu 22.04

Hop here and install the **Ubuntu 22.04 Server Edition**:

{% embed url="<https://releases.ubuntu.com/22.04/>" %}

<figure><img src="/files/DuhrCuEPQIKtcJ8oVnIo" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ysArC6fJUR0ff7gLtMbp" alt=""><figcaption><p>For this tutorial, we'll be using English</p></figcaption></figure>

<figure><img src="/files/ffv9pN6Gy3UmF6aRhw5v" alt=""><figcaption><p>Generally, you can continue without updating. If the installation fails, try it with the updated installer</p></figcaption></figure>

<figure><img src="/files/CY8cvHF23cFvj5pOaqB1" alt=""><figcaption><p>Please select "Ubuntu Server," not the minimized option. We require the additional packages that come with it</p></figcaption></figure>

<figure><img src="/files/CR1tPcl0MxoKGIeA6uFT" alt=""><figcaption><p>If you have multiple network devices connected to the network, you may want to create a bond to ensure better reliability. If your router supports 802.3ad, we recommend that. If not, you can just use one network device.  </p></figcaption></figure>

<figure><img src="/files/Kz1hnyTOteYa0oJQujst" alt=""><figcaption><p>Regardless of if you are using a bond or the network card directly, please make sure you set the IPv4 method through manual mode, <strong>not DHCP.</strong> This will ensure that the IP will never change, which we require. </p></figcaption></figure>

<figure><img src="/files/Z5SWHuEB62XAO3rNLQ9J" alt=""><figcaption><p>When setting your mirror, please set a geographically-close mirror to ensure responsiveness and speed</p></figcaption></figure>

<figure><img src="/files/k99ddFxq3Hx7o0RU3VpC" alt=""><figcaption><p>Once you've selected "Use an entire disk, check the "Set up this disk as an LVM group box"</p></figcaption></figure>

On this step, MAKE SURE YOU CHECK "Set up this disk as an LVM group."&#x20;

<figure><img src="/files/DW3VTfcl2dwmQJya1N2m" alt=""><figcaption><p>Then, confirm! </p></figcaption></figure>

<figure><img src="/files/NdZlcBX64smAJgurIudV" alt=""><figcaption></figcaption></figure>

* Your name: Set this to be anything
* Your server's name: set this to be something descriptive. It does not need to be anything special; it's solely the name of the server that connects to your network, so it can largely be ignored.&#x20;
* Pick a username: tensordock. Please do NOT do anything else! Not tensordock01, not tensordock\_user. Just tensordock.&#x20;
* Choose a password: Make this a long and complex password! If it is guessable, then hackers could access your machine and do damage to your internal network! You can also log on later and then change the password then.&#x20;

<figure><img src="/files/82VHJ487KGsmA5eGq6tS" alt=""><figcaption></figcaption></figure>

Then, install OpenSSH server, as shown above. DO NOT install additional 3rd-party drivers (do not install NVIDIA drivers)&#x20;

## 4. Fill in the form and await contact from your TensorDock account manager

[Host Form](https://docs.google.com/forms/d/e/1FAIpQLScaXGo6pqA27E32fis7xkoJLUxRfG2Vc7fPuntKswnj4YmVqg/viewform)

We'll promptly get your machine listed after we verify a few additional things and run some tests!&#x20;


# Overview

Learn how to create a whitelabeled GPU storefront with TensorDock

TensorDock offers a solution to whitelabel your GPUs, allowing you to sell directly to customers with a fully customizable storefront. We handle machine virtualization and billing logic so that you can focus on your business. Key features include:

* Custom HTML templates for easy setup and customization
* Whitelabel admin dashboard (accessible via the TensorDock dashboard)&#x20;
* Reduced fees for GPUs provisioned on the whitelabel
* Documented API, which allows you to add functionality to the storefront as necessary
* Support for custom domains

{% hint style="info" %}
For a live demo, visit <https://gpufleet.com>.
{% endhint %}


# Setting Up a Storefront

In the TensorDock dashboard, navigate to the admin dashboard (<https://marketplace.tensordock.com/organization/storefront/panel>) to begin setting up your whitelabeled storefront. The admin dashboard allows you to customize:

* HTML for individual pages on the storefront
* Images/assets
* Domains

<figure><img src="/files/gvCWISu7So8IQnCNH0Q1" alt=""><figcaption><p>Customizable HTML pages in the admin dashboard</p></figcaption></figure>

TensorDock provides HTML templates so that you don't have to build a website from scratch — including a landing page, deployment page, authentication logic, and more.

### Tracking users

You can view a list of all users who have registered on your whitelabeled storefront.

<figure><img src="/files/HhjICnTZOZAl2gG43M8L" alt=""><figcaption></figcaption></figure>


# Customization Overview

Learn how to integrate the storefront with TensorDock's API

### Authentication

The whitelabel uses JWTs with the TensorDock API in order to securely authenticate users. These are stored in the browser via the `whitelabelToken` cookie.

### Payments

TensorDock uses Stripe for deposits and payments. To deploy virtual machines, users first deposit funds to their account. This balance is incrementally billed over time depending on their usage of their virtual machines. In our templates, we provide a simple flow on the `Account` page that uses Stripe payment intents to allow users to deposit funds.

We use Stripe destination charges to ensure that when the customer views their financial statements, they are billed from your organization, not TensorDock. For more information on how this works, please view this guide: <https://docs.stripe.com/connect/destination-charges>.

### Deploying and Managing VMs

Deployments and VM management settings (such as stopping or deleting a VM) function by using our public API. If you need custom functionality that is not currently offered by our API, please contact us for support.


# Customize Whitelabel Storefront

TensorDock offers a "whitelabel" service to select hosts. Organizations can setup storefronts powered by TensorDock's infrastructure, and take a %x commission off sales. Contact us for details.

## Admin Panel

The admin panel is your interface for managing the storefront. TensorDock will take care of web hosting and all else under the hood. You must be the administrator of your organization to access the admin panel. To setup your site, simply save your frontend code, along with a subdomain address. We will go over how to do this in the following sections.

### Edit Pages

First, you will be greeted by the edit pages section. If you do not have a storefront setup, there will be boilerplate code provided (as seen below). Each page is an HTML document, and we have two stylesheets (Theme, Custom CSS) you can edit. Edits are not live- you must click the "save" button to deploy your code to TensorDock's end. Additionally, the save button will save all the pages & CSS, so it does not matter which tab you're toggled on. You can also upload photos, which will be stored in static/img/.&#x20;

<figure><img src="/files/rHjymGf16QkdG5pOMVRT" alt=""><figcaption></figcaption></figure>

### Domain Management

The next section is domain management. Here, you can set the subdomain and custom domain of your frontend. For example, if you enter the subdomain "test", then anytime another user visits test.tensordock.com they will be served the frontend home page. If they visit test.tensordock.com/login, they will be served the login page of your saved frontend. If you own a custom domain, then you can also insert the domain here.&#x20;

<figure><img src="/files/KHTuL5zF58FlVqrpCI4E" alt=""><figcaption></figcaption></figure>

If its your first time setting up a whitelabel storefront, then after saving the page files and subdomain, you will have a custom storefront ready. All user purchases through your storefront site will earn a x% commission. With a custom domain, you must contact support to finish setting up.&#x20;

### User Management

Here, you can view information on registered users of your storefront.&#x20;

<figure><img src="/files/QobKCokPjB5Zxt4O7S4M" alt=""><figcaption></figcaption></figure>

**Email**: The email the user registered with

**Date Created:** The timestamp creation of the user

**Email Verified:** If the user's email is verified

**Organization Name:** The organization the user is registered under.

**Organization Balance**: Available funds of an organization

You can delete users (rendered unable to login). However, that will not delete their machines, as they are registered under organizations. Deleting an organization will delete all of its machines and remove their users.

When users create an account on the whitelabel storefront, that account is only valid on your storefront. They cannot login on the TensorDock marketplace.&#x20;

## Whitelabel API

Here, we will review critical code snippets of the boilerplate frontend, so you can make adjustments easier.

### home.html

This simply your landing page; nothing to do here

### signup.html

Aside from the standard markup, we have the following code for registration.

```
fetch(url, {
        method: 'POST',
        body: formData
      })
      .then((response) => response.json())
      .then((data) => {
        console.log(data);
        document.cookie = `whitelabelToken=${data.token}`;
        window.location.href = '/home';
      })
      .catch(error => console.error('Error:', error));
```

Here, we make a POST request to the /api/v0/client/whitelabel/register endpoint. Fields must be in form-data form, and has the fields email (string), password (string), confirm\_password (string), organization\_name (string), subdomain (string). After a successful request, the user will be generated on our end and a token will be send back in the response with the field `token`. This will be stored as a cookie on the client's browser, to be used for authentication later.

### login.html

```
let formData = new FormData();
      formData.append('email', document.getElementById('email').value);
      formData.append('password', document.getElementById('password').value);
      formData.append('subdomain', window.location.hostname.split('.')[0]);

      fetch(url, {
        method: 'POST',
        body: formData
      })
      .then((response) => response.json())
      .then((data) => {
        console.log(data);

        if (data === undefined || data.token === undefined) {
          showMessage('Login failed');
        } else {
          document.cookie = `whitelabelToken=${data.token}`;
          window.location.href = '/deploy';
        }
      })
      .catch(error => {
        console.error('Error:', error);
        alert('Login failed');
      });
```

Here, we are using the /api/v0/client/whitelabel/login endpoint to simply post the email, password, and subdomain (which is uniquely linked to your storefront). If successful, we will get a `token` which will be stored as a cookie to be access later.&#x20;

### account.html

##

```
const response = await fetch(`${baseUrl}/api/vO/client/whitelabel/getUserInfo`, {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': whitelabelToken.split('=')[1]
          }
        });

        if (response.ok) {
          const userInquiryResponse = await response.json();
          console.log("RESPONSE WAS OK!")
          console.log("RESPONSE: ", userInquiryResponse)
          document.getElementById('account-funds').textContent = userInquiryResponse.balance;
          document.getElementById('user-id').textContent = userInquiryResponse.uuid;
          document.getElementById('user-email').textContent = userInquiryResponse.email;
          document.getElementById('organization-id').textContent = userInquiryResponse.organization;
          document.getElementById('organization-name').textContent = userInquiryResponse.organization_name;
          document.getElementById('organization-type').textContent = userInquiryResponse.organization_type;
          const membersList = document.getElementById('organization-members-list');
          const members = userInquiryResponse.members; 
          ...
        }else{
          window.location.href = './login.html';
        }
```

Here, we are doing a GET request to `/api/vO/client/whitelabel/getUserInfo` to get user information. In order to make authenticated requests, we put in the Authorization header our previous `token`.  If the token is valid, then our response will have the user's balance, unique identifier, email, organization, organization name, organization type, as well as other users in the same organization. You can then display this information anywhere on the page for the user to view.&#x20;

On an invalid token, the response will be an error code and we will simply redirect the user to the login screen.

```
const depositFunds = () => {
  const depositAmount = window.prompt("Please enter the deposit amount:");

  if (depositAmount !== null && Number(depositAmount) >= 0) {
    fetch(`http://localhost:5000/createDepositFundsSession/${depositAmount}`, {
      method: 'POST',
      headers: {
        'Authorization': document.cookie.split(';').find((elem) => elem.includes('whitelabelToken')).trim().split('=')[1],
      },
    })
    .then((response) => response.json())
    .then((session) => stripe.redirectToCheckout({ sessionId: session.id }))
    .then(function (result) {
      if (result.error) alert(result.error.message);
    })
    .catch(function (error) {
      console.error("Error:", error);
    });
  } else {
    alert("Invalid deposit amount");
  }
}
```

This function is used to open a Stripe deposit funds session. We make a POST request to /createDepositFundsSession/, with the deposit amount in the URI and the user's token in the Authorization header. In our boilerplate code, we have this method binded to a button press. When it has run successfully, it will open a Stripe tab on the user's browser to deposit money.

### list.html

```
document.addEventListener("DOMContentLoaded", async () => {
        //const whitelabelToken = document.cookie.split('; ').find(row => row.startsWith('whitelabelToken='));
        if (whitelabelToken) {
            try {
            console.log("THIS RAN!")
            const response = await fetch(`${baseUrl}/api/v0/client/whitelabel/token_verify`, {
                method: 'POST',
                headers: {
                'Content-Type': 'application/json',
                'Authorization': whitelabelToken.split('=')[1]
                },
                //body: JSON.stringify({ whitelabelToken: whitelabelToken.split('=')[1] })
            });

            if (!response.ok) {
                window.location.href = './login.html';
            }
            } catch (error) {
            window.location.href = './login.html';
            }
        }else{
            window.location.href = './login.html';
        }
        })
```

Here, we do a POST request to the /api/v0/client/whitelabel/token\_verify endpoint to verify if the user is logged in. As usual, we put the token in the Authorization header. On an unsuccessful response, we redirect them to login.&#x20;

### deploy.html

Most methods used here (deployServer, updateAvailableLocations, etc) are either using endpoints we covered above, or are using endpoints listed in our [docs](https://documenter.getpostman.com/view/20973002/2s8YzMYRDc#27cf1f9e-a597-4046-8d86-eaee799cc36b). If the endpoint is in our docs (start, stop, & delete VM, getting available hostnodes, get list of virtual machines), you can use it as described, but will have to include the token in the Authorization header. Without using the Authorization header, it will be treated as a "normal" TensorDock request as opposed to a whitelabel.


# Company Information

Last Updated: June 27, 2024

**Company Name:** TensorDock.com, Inc

**Delaware State File Number:** 6825666

**Mailing Address:**

TensorDock.com, Inc

16192 Coastal Highway

Lewes, DE 19958

**Email Address:** <hello@tensordock.com>


# Terms of Service (TOS)

Last updated: September 24, 2024

Welcome to the Terms of Service (these "Terms") for the online sales platform operated by TensorDock.com, Inc. (the "Company, "we", or "us") through <https://www.tensordock.com/> (such website, as well as any content, tools, features and functionality offered on or through such website, are collectively referred to as the "Platform").

These Terms govern your access to and use of the Platform and your procurement of access to computing equipment and related services through the Platform ("Compute Services"). Please read these Terms carefully, as they include important information about your legal rights. By accessing and/or using the Platform and submitting offers for Compute Services through the Platform (each such offer, an "Offer"), you are agreeing to these Terms. If you do not understand or agree to these Terms, please do not use the Platform or submit any Offers.

If and when we accept your Offer for Compute Services (as further described in Section 3.4 below), our provision of, and your use of, such Compute Services will be governed by the Compute Services Agreement (as described in Section 3.3 below) and not these Terms.

For purposes of these Terms, "you" and "your" means you as the user of the Platform seeking to purchase Compute Services. If you use the Platform on behalf of a company or other entity then "you" includes you and that entity, and you represent and warrant that (a) you are an authorized representative of the entity with the authority to bind the entity to these Terms, and (b) you agree to these Terms on the entity's behalf.

These terms do not apply to hosts that provide the infrastructure used in the Compute Services (each, a "Host"). The terms and conditions governing a Host's access to and use of the Platform, and the provision of access to Compute Services through the Platform, is set forth in Supplier Hosting Agreement available at <https://docs.tensordock.com/legal-information/supplier-hosting-agreement>.

**SECTION 8 CONTAINS AN ARBITRATION CLAUSE AND CLASS ACTION WAIVER. BY AGREEING TO THESE TERMS, YOU AGREE (A) TO RESOLVE ALL DISPUTES (WITH LIMITED EXCEPTION) RELATED TO THE COMPANY'S PLATFORM AND/OR OFFERS THROUGH BINDING INDIVIDUAL ARBITRATION, WHICH MEANS THAT YOU WAIVE ANY RIGHT TO HAVE THOSE DISPUTES DECIDED BY A JUDGE OR JURY, AND (B) TO WAIVE YOUR RIGHT TO PARTICIPATE IN CLASS ACTIONS, CLASS ARBITRATIONS, OR REPRESENTATIVE ACTIONS, AS SET FORTH BELOW.**

### 1. Who May Use the Platform

You must be 18 years of age or older to use the Platform (subject to the additional limitations in Section 3.8 below). By using the Platform, you represent and warrant that you meet these requirements.

### 2. User Accounts

#### 2.1 Creating and Safeguarding your Account

To use the Platform, you need to create an account ("Account"). You agree to provide us with accurate, complete and updated information for your Account. You are solely responsible for any activity on your Account (including any Offers placed through your Account) and for maintaining the confidentiality and security of your password. We are not liable for any acts or omissions by you in connection with your Account. You must immediately notify us if you know or have any reason to suspect that your Account or password have been stolen, misappropriated or otherwise compromised, or in case of any actual or suspected unauthorized use of your Account. You agree not to create any Account if we have previously removed you, or we previously banned you from using our Platform, unless we provide written consent otherwise. We reserve the right to verify information that you have provided to create an Account before we allow you to submit Offers.

### 3. Placing offers through the Platform

#### 3.1 Descriptions of Compute Services; Pricing

It is your responsibility to review all of the information provided about the Compute Services before placing an Offer. While we attempt to provide accurate descriptions of the Compute Services offered through the Platform we do not warrant that the product descriptions, pricing or other information provided are accurate, complete, precise, reliable, current or error-free.

#### 3.2 Offers

By displaying Compute Services that are available for purchase through the Platform, we are only inviting you to submit an Offer. You agree that your Offer is a firm offer to purchase, in accordance with these Terms and the Compute Services Agreement, all Compute Services listed in the Offer. You may not cancel or withdraw an Offer following its placement. By placing an Offer, you authorize us, and our third-party service providers, to charge your selected payment method for all amounts presented to you in connection with the Compute Services on which you placed an Offer. By placing an Offer, you represent that you are procuring the Compute Services on your own behalf and not for resale or use by another entity. We reserve the right to take steps to verify your payment information before accepting your Offer. You acknowledge that the Platform may allow for transactions in real time, and your Offer may compete simultaneously against multiple other Offers.

#### 3.3 Compute Services Agreement

By placing an Offer, you agree to our form of agreement for Compute Services, as set out at <https://docs.tensordock.com/legal-information/terms-of-service-tos> ("Compute Services Agreement"), which will form an agreement between you and us for the provision and use of the Compute Services if we accept your Offer pursuant to Section 3.4. Any terms or conditions that are included in any order form, invoice or other similar document that you issue in connection with your procurement of Compute Services is hereby expressly rejected and will not be deemed to modify or supplement the Compute Services Agreement or these Terms. The Compute Services Agreement, and not these Terms, will govern our provision of, and your use of, the Compute Services. We are under no obligation to deliver any Compute Services until you have paid all amounts due under the Compute Services Agreement.

#### 3.4 Offer Acceptance

All Offers are subject to our acceptance, and we will not be obligated to fulfil any Offer pursuant to the Compute Services Agreement unless and until we accept it in accordance with this Section. Offers are subject to service availability, and we may, in our sole discretion, choose to reject an Offer for any reason. This may occur, for example, if the services ordered are not available or have been mispriced, if we suspect an Offer is fraudulent, or in other circumstances we deem appropriate in our sole discretion. We also reserve the right, in our sole discretion, to determine to which customers we will sell Compute Services. If your Offer is accepted, we will send you a confirmation email with your order number, a summary of the items ordered, and pricing details, or, if you opt out of receiving emails from us through your Account, you may see details of your accepted Offer through your Account page ("Offer Confirmation"). We reserve the right to take steps to verify your payment information before confirming your Offer. Our acceptance of your Offer and the formation of a contract between you and us (pursuant to the terms of the Compute Services Agreement) with respect to the provision of relevant Compute Services will not take place unless and until (a) you have received your Offer Confirmation email (or the details of your Offer Confirmation are available under your Account on our website); and (b) we have received the initial payment for the Compute Services that we have requested.

#### 3.5 Payment

We reserve the right to require to you to pre-pay certain amounts for the Compute Services you wish to procure before you can submit an Offer for such Compute Services. You acknowledge and agree that all information you provide with regards to a purchase of Compute Services, including payment information, is accurate, current and complete. You represent and warrant that you have the legal right to use the payment method you provide to us or our payment processor, including any credit card you provide when completing a transaction. We reserve the right, with or without prior notice and in our sole and complete discretion, to (a) discontinue, modify, or limit the available quantity of, any Compute Services, and (b) refuse to allow any user to purchase any Compute Services. Unless otherwise noted, all currency references are in U.S. Dollars and do not include applicable taxes, duties and other similar charges, which you are responsible for paying.

#### 3.6 Changes

We may, at any time, revise or change the pricing, availability, specifications, content, descriptions or features of the Compute Services that are displayed in the Platform. All such changes shall be effective immediately upon posting of such new information to the Platform and/or upon making you aware of such new information (whichever occurs earlier).

#### 3.7 No Commitment to Sell Displayed Compute Services

We reserve the right to modify, suspend or discontinue, temporarily or permanently, our invitation to procure Compute Services through the Platform at any time, in our sole discretion, regardless of whether you have placed an Offer or we have accepted your Offer. For the avoidance of doubt, the foregoing does not limit any rights or remedies you may have pursuant to a Compute Services Agreement that you and we have entered into pursuant to Section 3.4.

#### 3.8 Territorial Restrictions on use of the Platform

The Compute Services may not be available in the location from which you have placed an Offer or intend to use the Compute Services. We reserve the right to limit the locations from which Offers may be placed, including as required to comply with applicable laws and regulations.

### 4. Location of Our Privacy Policy; Usage Information

#### 4.1 Privacy Policy

Our Privacy Policy describes how we handle certain information you provide to us when you use the Platform. For an explanation of our privacy practices, please visit our Privacy Policy located at <https://docs.tensordock.com/legal-information/tensordock-privacy-policy>.

#### 4.2 Usage Information

You acknowledge that the Company monitors the performance and usage of the Platform by its customers (including information related to Offers) and may combine this data ("Usage Information") with other information and use such combined data in an aggregate, de-identified and anonymous manner for its business purposes. Examples of aggregate data include compiling statistical and performance information related to the operation of the Platform, determining usage trends, performing analytics and developing and improving the Platform and the Company's other products and services. The Company retains all intellectual property rights in and to Usage Information.

### 5. Rights We Grant You

#### 5.1 Right to Use Platform

We hereby permit you to use the Platform to review Compute Services that are available for purchase and to submit Offers, provided that you comply with these Terms in connection with all such use. If any software, content or other materials owned or controlled by us are distributed to you as part of your use of the Platform, we hereby grant you a personal, non-assignable, non-sublicensable, non-transferrable, and non-exclusive right and license to access such software, content and materials provided to you as part of the Platform in each case for the sole purpose of enabling you to use the Platform as permitted by these Terms. Your access and use of the Platform may be interrupted from time to time for any of several reasons, including the malfunction of equipment, periodic updating, maintenance or repair of the Platform or other actions that Company, in its sole discretion, may elect to take.

#### 5.2 Restrictions On Your Use of the Platform

You may not do any of the following in connection with your use of the Platform, unless applicable laws or regulations prohibit these restrictions or you have our written permission to do so:

(a) download, modify, copy, distribute, transmit, display, perform, reproduce, duplicate, publish, license, create derivative works from, or offer for sale any information contained on, or obtained from or through, the Platform, except for temporary files that are automatically cached by your web browser for display purposes, or as otherwise expressly permitted in these Terms;

(b) duplicate, decompile, reverse engineer, disassemble or decode the Platform (including any underlying idea or algorithm), or attempt to do any of the same;

(c) use, reproduce or remove any copyright, trademark, service mark, trade name, slogan, logo, image, or other proprietary notation displayed on or through the Platform;

(d) use automation software (bots), hacks, modifications (mods) or any other unauthorized third-party software designed to modify the Platform;

(e) access or use the Platform in any manner that could disable, overburden, damage, disrupt or impair the Platform or interfere with any other party's access to or use of the Platform or use any device, software or routine that causes the same;

(f) attempt to gain unauthorized access to, interfere with, damage or disrupt the Platform, or the computer systems or networks connected to the Platform;

(g) circumvent, remove, alter, deactivate, degrade or thwart any technological measure or content protections of the Platform;

(h) use any robot, spider, crawlers, scraper, or other automatic device, process, software or queries that intercepts, "mines," scrapes, extracts, or otherwise accesses the Platform to monitor, extract, copy or collect information or data from or through the Platform, or engage in any manual process to do the same;

(i) introduce any viruses, trojan horses, worms, logic bombs or other materials that are malicious or technologically harmful into our systems;

(j) violate any applicable law or regulation in connection with your access to or use of the Platform; or

(k) access or use the Platform in any way not expressly permitted by these Terms.

### 6. Ownership

#### 6.1 Ownership of the Platform

The Platform, including its "look and feel" (e.g., text, graphics, images, logos), proprietary content, information and other materials, are protected under copyright, trademark and other intellectual property laws. You agree that the Company and/or its licensors own all right, title and interest in and to the Platform (including any and all intellectual property rights therein) and you agree not to take any action(s) inconsistent with such ownership interests. We and our licensors reserve all rights in connection with the Platform and its content, including the exclusive right to create derivative works.

#### 6.2 Ownership of Trademarks

The Company's name, trademarks, logos, all related names, logos, product and service names, designs and slogans are trademarks of the Company or its affiliates or licensors. Other names, logos, product and service names, designs and slogans that appear on the Platform are the property of their respective owners, who may or may not be affiliated with, connected to, or sponsored by us.

#### 6.3 Ownership of Feedback

We welcome feedback, comments and suggestions for improvements to the Platform or the Compute Services ("Feedback"). You acknowledge and expressly agree that any contribution of Feedback does not and will not give or grant you any right, title or interest in the Platform or in any such Feedback. All Feedback becomes the sole and exclusive property of the Company, and the Company may use and disclose Feedback in any manner and for any purpose whatsoever without further notice or compensation to you and without retention by you of any proprietary or other right or claim. You hereby assign to the Company any and all right, title and interest (including, but not limited to, any patent, copyright, trade secret, trademark, show-how, know-how, moral rights and any and all other intellectual property right) that you may have in and to any and all Feedback.

### 7. Disclaimers, Limitations of Liability and Indemnification

#### 7.1 Disclaimers

(a) Your access to and use of the Platform are at your own risk. You understand and agree that the Platform are provided to you on an "AS IS" and "AS AVAILABLE" basis. Without limiting the foregoing, to the maximum extent permitted under applicable law, the Company, its parents, affiliates, related companies, officers, directors, employees, agents, representatives, partners and licensors (the "Company Entities") DISCLAIM ALL WARRANTIES AND CONDITIONS, WHETHER EXPRESS OR IMPLIED, OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. The Company Entities make no warranty or representation and disclaim all responsibility and liability for: (i) the completeness, accuracy, availability, timeliness, security or reliability of the Platform or your ability to submit Offers through the Platform; (ii) any harm to your computer system, loss of data, or other harm that results from your access to or use of the Platform; (iii) the operation or compatibility with any other application or any particular system or device; or (iv) whether the Platform will meet your requirements or be available on an uninterrupted, secure or error-free basis. No advice or information, whether oral or written, obtained from the Company Entities or through the Platform, will create any warranty or representation not expressly made herein.

(b) THE LAWS OF CERTAIN JURISDICTIONS, INCLUDING THE STATE OF NEW JERSEY, DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES OR THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES AS SET FORTH IN SECTION 7.2 BELOW. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE ABOVE DISCLAIMERS, EXCLUSIONS, OR LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MAY HAVE ADDITIONAL RIGHTS.

#### 7.2 Limitations of Liability

TO THE EXTENT NOT PROHIBITED BY LAW, YOU AGREE THAT IN NO EVENT WILL THE COMPANY ENTITIES BE LIABLE (A) FOR DAMAGES OF ANY KIND, INCLUDING INDIRECT, SPECIAL, EXEMPLARY, INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA OR PROFITS, BUSINESS INTERRUPTION OR ANY OTHER DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE THE PLATFORM), HOWEVER CAUSED AND UNDER ANY THEORY OF LIABILITY, WHETHER UNDER THESE TERMS OR OTHERWISE ARISING IN ANY WAY IN CONNECTION WITH THE PLATFORM OR THESE TERMS AND WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) EVEN IF THE COMPANY ENTITIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE, OR (B) FOR ANY OTHER CLAIM, DEMAND OR DAMAGES WHATSOEVER RESULTING FROM OR ARISING OUT OF OR IN CONNECTION WITH THESE TERMS OR THE DELIVERY, USE OR PERFORMANCE OF THE PLATFORM, THE COMPANY ENTITIES' TOTAL LIABILITY TO YOU FOR ANY DAMAGES FINALLY AWARDED SHALL NOT EXCEED THE GREATER OF: (I) ONE HUNDRED DOLLARS ($100.00); AND (II) THE AGGREGATE AMOUNTS YOU PRE-PAID IN CONNECTION WITH THE OFFER GIVING RISE TO THE CLAIM. THE FOREGOING LIMITATIONS WILL APPLY EVEN IF THE ABOVE STATED REMEDY FAILS OF ITS ESSENTIAL PURPOSE. For the avoidance of doubt: (a) the foregoing does not limit any rights or remedies you may have pursuant to a Compute Services Agreement that you and we have entered into pursuant to Section 3.4. For greater certainty, your rights and remedies are limited to those set out in the Compute Services Agreement or these Terms, as applicable, and you may not seek recovery under both the Compute Services Agreement and these Terms for any such breach, event, action or occurrence.

#### 7.3 Indemnification

By entering into these Terms and accessing or using the Platform, you agree that you shall defend, indemnify and hold the Company Entities harmless from and against any and all claims, costs, damages, losses, liabilities and expenses (including attorneys' fees and costs) incurred by the Company Entities arising out of or in connection with any of the following: (a) your violation or breach of any term of these Terms or any applicable law or regulation; (b) your violation of any rights of any third party; (c) your misuse of the Platform; and (d) your negligence or wilful misconduct. If you are obligated to indemnify any Company Entity hereunder, then you agree that Company (or, at its discretion, the applicable Company Entity) will have the right, in its sole discretion, to control any action or proceeding and to determine whether Company wishes to settle, and if so, on what terms, and you agree to fully cooperate with Company in the defense or settlement of such claim.

### 8. ARBITRATION and injunctive relief

#### 8.1 Dispute Resolution Procedures

Except as provided below, for any dispute arising out of, or relating to, these Terms or breach of these Terms, or the transactions contemplated hereby, the parties will use good faith efforts to promptly resolve the matter informally before resorting to more formal means of resolutions. The parties hereby agree to submit any dispute they cannot resolve informally to final and binding arbitration. The arbitration will be conducted in the State of Delaware, using the English language, before a single neutral arbitrator under the auspices of JAMS Streamlined Arbitration Rules and Procedures (for claims under $250,000.00) or JAMS Comprehensive Arbitration Rules and Procedures (for claims over $250,000.00). The arbitrator will follow Delaware law in adjudicating the dispute. Interpretations of these Terms, including determinations of unconscionability and the interpretation of this Section will be determined by the arbitrator selected through this provision. The determinations of the arbitrator shall be final and shall not be subject to judicial review; provided, however, that any award or determination rendered by the arbitrator may be entered in any court of competent jurisdiction. The parties shall share equally the costs of arbitration, including the costs of transcribing the arbitration, but each party shall bear its own attorneys' fees and related costs, unless otherwise provided by law or regulation. Except to the extent necessary to confirm an award or as may be required by applicable laws or regulations, neither a party nor an arbitrator may disclose the existence, content or results of an arbitration without the prior written consent of the parties. Each party expressly and irrevocably waives any claim or defense in any arbitration or proceeding based on any alleged lack of personal jurisdiction, improper venue, forum non conveniens or any similar doctrine or theory. Each party irrevocably waives any and all right to trial by jury in any proceeding arising out of or related to these Terms. Any proceeding to resolve a dispute hereunder will be conducted solely on an individual basis, and neither party will seek to have any dispute heard as a class action or class arbitration.

#### 8.2 Injunctive Relief

The parties acknowledge and agree that any action for equitable relief or any other action that may not be submitted to arbitration under applicable laws or regulations, including the enforcement of any arbitration ruling, shall be tried by a court of competent jurisdiction located in the State of Delaware. To that end the parties hereby submit to the jurisdiction of the State of Delaware for this limited purpose.

### 9. Additional Provisions

#### 9.1 Updating These Terms

We may modify these Terms from time to time in which case we will update the "Last Revised" date at the top of these Terms. It is your sole responsibility to review these Terms from time to time to view any such changes. The updated Terms will be effective as of the time of posting, or such later date as may be specified in the updated Terms. Your continued access or use of the Platform after the modifications have become effective will be deemed your acceptance of the modified Terms. No amendment shall apply to a dispute for which an arbitration has been initiated prior to the change in Terms.

#### 9.2 Termination of License and Your Account

If you breach any of the provisions of these Terms, all licenses granted by the Company will terminate automatically. Additionally, the Company may suspend, disable, or delete your Account and/or the Platform (or any part of the foregoing) with or without notice, for any or no reason. If the Company deletes your Account for any suspected breach of these Terms by you, you are prohibited from re-registering for the Platform under a different name. All sections which by their nature should survive the termination of these Terms shall continue in full force and effect subsequent to and notwithstanding any termination of these Terms by the Company or you. Termination will not limit any of the Company's other rights or remedies at law or in equity.

#### 9.3 Injunctive Relief

You agree that a breach of these Terms will cause irreparable injury to the Company for which monetary damages would not be an adequate remedy and the Company shall be entitled to equitable relief in addition to any remedies it may have hereunder or at law without a bond, other security or proof of damages.

#### 9.4 California Residents

If you are a California resident, in accordance with Cal. Civ. Code § 1789.3, you may report complaints to the Complaint Assistance Unit of the Division of Consumer Platform of the California Department of Consumer Affairs by contacting them in writing at 1625 North Market Blvd., Suite N 112 Sacramento, CA 95834, or by telephone at (800) 952-5210.

#### 9.5 U.S. Government Restricted Rights

The Platform and related documentation are "Commercial Items", as that term is defined at 48 C.F.R. §2.101, consisting of "Commercial Computer Software" and "Commercial Computer Software Documentation", as such terms are used in 48 C.F.R. §12.212 or 48 C.F.R. §227.7202, as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Software and Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial Items, and (b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein.

#### 9.6 Trade Control

The Platform and the Compute Services are subject to applicable trade control laws, rules, and regulations, including without limitation the Export Administration Regulations ("EAR"), and sanctions administered by the Office of Foreign Assets Control ("OFAC") (collectively, "Trade Control Laws"). By accessing or using the Platform or the Compute Services, you agree to, and to cause all those who access your account to, comply with all Trade Control Laws. You represent and warrant, on your behalf and on behalf of all those who access your account, that: (i) you are responsible for compliance with applicable Trade Control Laws in connection with your and all those who access your account's use of the Platform and the Compute Services and you shall obtain all necessary export licenses or other governmental approval related to use of the Platform and the Compute Services; (ii) you and each person who accesses your account is not, nor is any of the foregoing 50% or more owned or otherwise controlled by one or more parties that are (1) located in any country that is subject to OFAC's trade and economic sanctions; (2) an individual or entity included on any U.S. lists of prohibited parties, including, without limitation, the Treasury Department's Specially Designated Nationals List ("SDN List") and Sectoral Sanctions List ("SSI List"), export denial list, or other prohibited transactions list or directive; (3) engaged in activities prohibited by Trade Control Laws or that would cause the Company to violate such Trade Control Laws in its performance of these Terms; and (iii) you will not, and will cause each person who accesses your account to not, use the Platform or the Compute Services to (1) support end uses prohibited under Trade Control Laws, including those related to nuclear, chemical, or biological weapons proliferation, missile systems or technology, restricted unmanned aerial vehicle, or certain advanced supercomputer or semiconductor applications; or (2) circumvent or facilitate any violations of Trade Control Laws. Additionally, You agree not to, and to cause each person who accesses your account not to, directly or indirectly sell, export, re-export, transfer, divert or otherwise dispose of the Platform or the Compute Services in contradiction of Trade Control Laws. Failure to comply with such laws and regulations may result in the suspension or termination of your access to the Platform, the Compute Services, and these Terms, without liability to the Company.

#### 9.7 Force Majeure

Company shall not be liable under these Terms for delays, failures to perform, damages or losses caused or occasioned by or due to fire, earthquake, flood, water, the elements, labor disputes or shortages, utility curtailments, power failures, explosions, civil disturbances, governmental actions, epidemics, shortages of equipment or supplies, equipment malfunctions, loss of access to or degradation networks, acts or omissions of third parties or any other cause beyond its reasonable control.

#### 9.8 Miscellaneous

If any provision of these Terms is held by a court of competent jurisdiction to be contrary to law, the provision shall be modified by the court and interpreted so as best to accomplish the objectives of the original provision to the fullest extent permitted by law, and the remaining provisions of these Terms shall remain in effect. These Terms and the licenses granted hereunder may be assigned by the Company but may not be assigned by you without the prior express written consent of the Company. The Company may subcontract or delegate its obligations under these Terms without your content. The failure of any party in any one or more instances to insist upon strict performance of any provisions of these Terms, or to exercise any option or remedy which is conferred by these Terms, shall not be construed as a waiver or relinquishment to any extent of the right to assert or rely upon any such provisions, options or remedies on any future occasion. No waiver by either party shall be effective unless agreed to pursuant to a writing signed by a duly authorized representative of the party granting the waiver. The section headings used herein are for reference only and shall not be read to have any legal effect. The Platform is operated by us in the United States. Those who choose to access the Platform from locations outside the United States do so at their own initiative and are responsible for compliance with applicable local laws. The parties hereby agree that any disputes under these Terms will be resolved pursuant to the laws of the State of Delaware, without giving effect of any conflicts of laws principles. You and the Company agree that the United Nations Convention on Contracts for the International Sale of Goods will not apply to the interpretation or construction of these Terms.

#### 9.9 No Third Party Beneficiaries

These Terms are for the sole benefit of the parties and their respective successors and assigns and, except as provided in Section 7, nothing herein, express or implied, is intended to or will confer upon any other person any legal or equitable right, benefit or remedy.

#### 9.10 Interpretation

The titles, headings and captions contained in these Terms are for reference purposes only and will not affect in any way the meaning or interpretation of these Terms. Unless otherwise indicated to the contrary herein by the context or use thereof, for the purposes of these Terms: (i) the words "include," "includes" and "including" are deemed to be followed by the words "without limitation"; (ii) the word "or" is not exclusive; and (iii) the terms "shall" and "will" are synonyms as used in these Terms and each term indicates that the corresponding party must perform the obligation that is subject to such term. The parties intend these Terms to be construed without regard to any presumption or rule requiring construction or interpretation against the party drafting an instrument or causing any instrument to be drafted. Unless otherwise expressly stated herein, the rights and remedies of the parties are cumulative and are in addition to, and not in substitution for, any other rights and remedies available at law or in equity or otherwise.

#### 9.11 Notices

Except as provided in this Section, all notices under these Terms to you shall be in writing and shall be delivered to the addresses you indicate in your Account. Notices to the Company shall be addressed to <suppot@tensordock.com>, with a copy to <legal@tensordock.com>. Either party may change its address for notice by giving notice of such address change in the manner provided herein. All communications and notices to be made or given pursuant to these Terms shall be in the English language. Notwithstanding the foregoing, the Company may provide all business and product-related communications (e.g., release notes for product updates, privacy policy updates, critical security updates and information on critical bugs and outages) to you by email, posting on the Platform or other electronic means.


# Privacy Policy

Last updated: June 27, 2024

## Privacy Policy

This Privacy Notice describes how TensorDock.com, Inc ("**we**", "**us**", "**our**") collects, uses and discloses information about you when you use our websites <https://tensordock.com/> or <https://dashboard.tensordock.com/deploy>, applications, services, tools and features, or otherwise interact with us (collectively, the "**Platform**"). For the purposes of this Privacy Notice, "**you**" and "**your**" means you as the user of the Platform. Please note that the Platform is designed for users in the United States only and is not intended for users located outside the United States.

Please read this Privacy Notice carefully. By using or accessing the Platform, you agree to the collection, use, and disclosure of your information as described in this Privacy Notice. If you do not agree to this Privacy Notice, please do not use or access the Platform.

### 1. CHANGES TO THIS PRIVACY NOTICE

We may modify this Privacy Notice from time to time, in which case we will update the "Last Updated" date at the top of this Privacy Notice. If we make material changes to how we use or disclose information we collect, we will use reasonable efforts to notify you (such as by emailing you at the last email address you provided us, by posting notice of such changes on the Platform, or by other means consistent with applicable law) and will take additional steps as required by applicable law. If you do not agree to any updates to this Privacy Notice, please do not continue using or accessing the Platform.

### 2. COLLECTION AND USE OF INFORMATION

When you use or access the Platform, we collect certain categories of information about you from a variety of sources.

#### Information You Provide to Us

Some features of the Platform may require you to directly provide certain information about yourself. You may elect not to provide this information, but doing so may prevent you from using or accessing these features. Information that you directly submit through our Platform includes:

* **Basic contact details**, such as name, and email. We use this information to create and maintain your account and provide the Platform, and to communicate with you.
* **Payment information, such as bank account information and billing address**. We use this information to process your payment and provide the Platform.
* **Any other information you choose to include in communications with us**, for example, when sending a message to us.

#### Information Collected Automatically

We may also use cookies or other similar technologies to automatically collect certain information about your interactions with the Platform. We collect and use this information to run analytics and better understand user interactions with the Platform. Such information includes:

* Information regarding your interaction with the Platform, such as log data, date and time stamps, and clickstream data.

Most browsers accept cookies automatically, but you may be able to control the way in which your devices permit the use of cookies. If you so choose, you may block or delete certain of our cookies from your browser; however, blocking or deleting cookies may cause some of the Platform, including any portal features and general functionality, to work incorrectly. Your browser settings may also allow you to transmit a "Do Not Track" signal when you visit various websites. Like many websites, our website is not designed to respond to "Do Not Track" signals received from browsers. To learn more about "Do Not Track" signals, you can visit [http://www.allaboutdnt.com](http://www.allaboutdnt.com/).

To opt out of Google Analytics, click [here](https://tools.google.com/dlpage/gaoptout).

#### Information Collected From Other Sources

We may obtain information about you from outside sources, including information that we collect directly from third parties and information from third parties that you choose to share with us. Such information includes:

* Basic contact details, such as name, and email, from Google when you use your Google account to access the Platform. We use this information to create and maintain your account and provide the Platform, and to communicate with you.

Any information we receive from outside sources will be treated in accordance with this Privacy Notice. We are not responsible for the accuracy of the information provided to us by third parties and are not responsible for any third party's policies or practices. For more information, see the section below, *Third Party Websites and Links*.

In addition to the specific uses described above, we may use any of the above information to provide you with the Platform and to maintain our business relationship, including by enhancing the safety and security of our Platform (e.g., troubleshooting, data analysis, testing, system maintenance, and reporting), providing customer support, sending service and other non-marketing communications, monitoring and analyzing trends, conducting internal research and development, complying with applicable legal obligations, enforcing any applicable terms of service, and protecting the Platform, our rights, and the rights of our employees, users or other individuals.

### 3. DISCLOSURE OF YOUR INFORMATION

We may disclose your information for legitimate purposes subject to this Privacy Notice, including the following categories of third parties:

* Our affiliates or others within our corporate group, to efficiently provide the Services.
* Vendors or other service providers who help us provide the Platform, including for system administration, cloud storage, security, web analytics, and payment networks.
* Professional advisors, such as auditors, law firms, or accounting firms.
* Third parties in connection with or anticipation of an asset sale, merger, bankruptcy, or other business transaction.

We may also disclose your information as needed to comply with applicable law or any obligations thereunder or to cooperate with law enforcement, judicial orders, and regulatory inquiries, to enforce any applicable terms of service, and to ensure the safety and security of our business, employees, and users.

### 4. THIRD PARTY WEBSITES AND LINKS

We may provide links to third-party websites or platforms. If you follow links to sites or platforms that we do not control and are not affiliated with us, you should review the applicable privacy notice, policies and other terms. We are not responsible for the privacy or security of, or information found on, these sites or platforms. Information you provide on public or semi-public venues, such as third-party social networking platforms, may also be viewable by other users of the Platform and/or users of those third-party platforms without limitation as to its use. Our inclusion of such links does not, by itself, imply any endorsement of the content on such platforms or of their owners or operators.

### 5. CHILDREN'S PRIVACY

Our Platform is not intended for children, and we do not seek or knowingly collect any personal information about children. If we become aware that we have unknowingly collected information about a child, in particular any child under 13 years of age, we will make commercially reasonable efforts to delete such information from our database. If you are the parent or guardian of a child under 13 years of age who has provided us with their personal information, you may contact us using the below information to request that it be deleted.

### 6. DATA SECURITY AND RETENTION

Despite our reasonable efforts to protect your information, no security measures are impenetrable, and we cannot guarantee "perfect security." Any information you send to us electronically, while using the Platform or otherwise interacting with us, may not be secure while in transit. We recommend that you do not use unsecure channels to send us sensitive or confidential information.

We retain your information for as long as is reasonably necessary for the purposes specified in this Privacy Notice. When determining the length of time to retain your information, we consider various criteria, including whether we need the information to continue to provide you the Platform, resolve a dispute, enforce our contractual agreements, prevent harm, promote safety, security and integrity, or protect ourselves, including our rights, property or products.

### 7. CALIFORNIA PRIVACY RIGHTS

This section applies to you only if you are a California resident ("**resident**" or "**residents**"). For purposes of this section, references to "personal information" shall include "sensitive personal information," as these terms are defined under the California Consumer Privacy Act ("**CCPA**").

#### Processing of Personal Information

In the preceding 12 months, we collected and (where indicated below) disclosed for a business purpose the following categories of personal information about residents:

| Category                                                                                                                 | Categories of Recipients                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Identifiers such as name and e-mail address                                                                              | Vendors or other service providers who help us provide the Platform, including for system administration, cloud storage, security, web analytics, and payment networks |
| Personal information categories listed in the California Customer Records statute such as name, bank account information | Vendors or other service providers who help us provide the Platform, including for system administration, cloud storage, security, web analytics, and payment networks |
| Commercial information such as records of products or services purchased                                                 | Vendors or other service providers who help us provide the Platform, including for system administration, cloud storage, security, web analytics, and payment networks |
| Internet or other similar network activity such as information regarding your interaction with the Platform              | Vendors or other service providers who help us provide the Platform, including for system administration, cloud storage, security, web analytics, and payment networks |
| Professional or employment-related information such as employer                                                          | Vendors or other service providers who help us provide the Platform, including for system administration, cloud storage, security, web analytics, and payment networks |

The specific business or commercial purposes for which we collect your personal information and the categories of sources from which we collect your personal information are described in the section above, *Collection and Use Your Information*. We do not use or disclose any of your sensitive personal information. The criteria we use to determine how long to retain your personal information is described in the section above, *Data Security and Retention*.

We disclosed personal information over the preceding 12 months for the following business or commercial purposes:

* to communicate with you, provide you with products and services, etc.
* to maintain and secure your account with us; and
* to process your payment, to provide you with products or services you have requested.

#### Selling and/or Sharing of Personal Information

**We do not "sell" or "share" (as those terms are defined under the CCPA) personal information, nor have we done so in the preceding 12 months.** Further, we do not have actual knowledge that we "sell" or "share" personal information of residents under 16 years of age.

#### Your California Privacy Rights

As a California resident, you may have the rights listed below in relation to personal information that we have collected about you. However, these rights are not absolute, and in certain cases, we may decline your request as permitted by law, including in the event you reside in a state that does not currently grant you these rights.

* **Right to Know.** You have a right to request the following information about our collection, use and disclosure of your personal information:
  * categories of personal information we have collected and disclosed for a business purpose;
  * categories of sources from which we collected personal information;
  * the business or commercial purposes for collecting personal information;
  * categories of third parties to whom the personal information was disclosed for a business purpose; and
  * specific pieces of personal information we have collected.
* **Right to Delete.** You have a right to request that we delete personal information we maintain about you.
* **Right to Correct.** You have a right to request that we correct inaccurate personal information we maintain about you.

You may exercise any of these rights by contacting us using the information provided below. We will not discriminate against you for exercising any of these rights. We may need to collect information from you to verify your identity, such as your email address, government issued ID or date of birth, before providing a substantive response to the request. You may designate, in writing or through a power of attorney document, an authorized agent to make requests on your behalf to exercise your rights. Before accepting such a request from an agent, we will require that the agent provide proof you have authorized them to act on your behalf, and we may need you to verify your identity directly with us.

### 8. HOW TO CONTACT US

Should you have any questions about our privacy practices or this Privacy Notice, please email us at <hello@tensordock.com> or contact us at *555 Montgomery Street, Suite 811, San Francisco, CA 94111.*


# Acceptable Use Policy (AUP)

Last updated: June 27, 2024

We host a wide variety of mission critical projects from all over the world. With the power of the computational resources we provide, we find it important that our clients and hosts act in good faith. While using the Service, you must comply with our Acceptable Use Policies, which include restrictions on conduct on TensorDock related to user safety, intellectual property, privacy, authenticity, and other limitations. In short, be excellent to others.

Capitalized terms used but not defined in these Acceptable Use Policies have the meanings assigned to them in your main agreements with us — the TensorDock Terms of Service and the TensorDock Privacy Policy. This Acceptable Use Policy (this “AUP”) outlines the materials and activities prohibited in association with a Customer's utilization of TensorDock Services. "You" and "your" refer to "Clients" and "Hosts". "We", "us", and "our" refer to "TensorDock".

### 1. Compliance with Laws and Regulations

You are responsible for using the Service in compliance with all applicable laws, regulations, and all of our Acceptable Use Policies. These policies may be updated from time to time and are provided below.

### 2. User Safety

We do not allow data or activity on TensorDock that is unlawful or promotes unlawful activities. Examples include but are not limited to data or activity that

* relates to sexual exploitation or abuse of minors (“child pornography”)
* depicts nudity or sexual activity obtained or disseminated without the consent of those depicted (“revenge/nonconsensual pornography”)
* is libelous, defamatory, or fraudulent;
* is discriminatory or abusive toward any individual or group;
* Is promoting, buying, selling, or distributing illegal substances
* is false, inaccurate, or intentionally deceptive information and likely to adversely affect the public interest (including health, safety, election integrity, and civic participation);
* harasses or abuses another individual or group, including our employees, officers, and agents, or other users;
* threatens or incites violence toward any individual or group, especially based on who they are;
* gratuitously depicts or glorifies violence, including violent images; or
* interacts with platform features in a way that significantly or repeatedly disrupts the experience of other users.

You must not engage in activity that significantly harms other users. We will interpret our policies and resolve disputes in favor of protecting users as a whole, both Clients and Hosts.

### 3. Intellectual Property, Authenticity, and Private Information

We do not allow data or activity on TensorDock that:

* infringes any proprietary right of any party, including patent, trademark, trade secret, copyright, right of publicity, or other right;
* impersonates any person or entity, including any of our employees or representatives, including through false association with TensorDock, or by fraudulently misrepresenting your identity or site's purpose; or
* violates the privacy of any third party, such as by posting another person's personal information without consent.

### 4. Spam and Inauthentic Activity

We do not allow data or activity on TensorDock that is:

* automated excessive bulk activity and coordinated inauthentic activity, such as
  * spamming (unsolicited advertising)
  * cryptocurrency mining, without our express written permission;
* bulk distribution of promotions and advertising;
* inauthentic interactions, such as fake accounts and automated inauthentic activity;
* creation of or participation in secondary markets for the purpose of the proliferation of inauthentic activity;
* using TensorDock as a platform for propagating abuse on other platforms;
* using our servers for any form of excessive automated bulk activity to place undue burden on our infrastructure through automated means, as determined by us in our sole discretion;
* collection of personal information through deceitful means, such as phishing, Internet scamming, password robbery, spidering, and harvesting; or
* offering or disseminating fraudulent goods, services, schemes, or promotions, such as get-rich-quick, pyramid, or Ponzi schemes

### 5. Site Access and Safety

We do not allow data, technology, software, or activity on TensorDock that may attempt to disrupt any service, device, data, account, or network (defined as “Systems”)

Examples include but are not limited to

* Viruses, malware, ransomware, spyware, adware, Trojan horses, worms, or time bombs with no implicit or explicit dual-use purpose
* Gaining unauthorized access to any Systems, whether owned by TensorDock, a host, or a third party.
* Intercepting or monitoring a System’s data or traffic without permission.
* Using misleading TCP-IP email headers, packet headers, or any component of a message to falsify its origin or route, excluding the use of aliases and anonymous remailers.

### 6. Network Abuse (Clients Only)

The Service's network limitations vary based on the Host whose server you are renting. If we determine your bandwidth usage to be significantly excessive in relation to other users of similar features, we reserve the right to suspend your account, throttle your internet, or otherwise limit your activity until you can reduce your bandwidth consumption. We reserve the right to delete servers that we determine to be placing undue strain on the infrastructure of us or our hosts, after providing advance notice

Additionally, we prohibit:

* Monitoring, crawling, or scraping any System, including TensorDock Services.
* Interfering with a System, including deliberate attempt of mail bombing, news bombing, broadcast attacks, flooding techniques, or denial of service attacks.
* Running open proxies, open mail relays, open recursive domain name servers, Tor exit nodes, or other similar network services.
* Bypassing any System’s limitations, such as access limits or storage restrictions.
* Instigating retaliation, such as a denial of service attack, against TensorDock, including its Services, employees, or other agents.
* Misrepresenting or concealing identity, including the omission, deletion, forgery, or misreporting of identification information, such as return mailing and IP addresses.

### 7. Privacy

Don't use our Services to post other people's personal information. This includes:

* Personal, private email addresses
* Phone numbers
* Physical addresses or other private location information
* Bank account information or credit card numbers
* Social Security/National Identity numbers
* Passwords
* Voter information
* Medical information and personal biometric data
* Other private information that may pose a safety or security risk

We may consider other information, such as photos or videos that were taken or distributed without the subject's consent, to be an invasion of privacy, especially when such material presents a safety risk to the subject, such as in the case of intimidation or harassment.

TensorDock will take context into account as well as whether the reported content is publicly available elsewhere. However, please note that while sharing publicly available content may not be a violation of this policy, we may still consider it a violation if the information is shared with the intent to harass or incite other abusive behavior.

### 8. Services Usage Limits

You may not reproduce, duplicate, copy, sell, resell, or exploit any portion of our Services, use of our Services, or access to our Services without our express written permission.

### 9. Security Vulnerability Testing

Users may not attempt to test the vulnerability of a TensorDock system or network, breach TensorDock security or authentication measures, or conduct security or malware research on or using TensorDock Services, without TensorDock’s express written permission.

### 10. Enforcement

TensorDock retains full discretion to take action in response to a suspected violation of these policies, including account suspension, account termination, or removal of data, regardless of whether the violation was unintentional or committed without the user’s permission. TensorDock reserves the right to intercept or prevent any data or traffic associated with a Client or its end users if TensorDock Services are being used in violation of this AUP.

We reserve the right, but have no obligation, to investigate violations of this AUP. Nothing in this AUP can be construed as an obligation for TensorDock to act at any given time or with respect to any given instance, and we retain the discretion to exercise this right at any time we see fit.&#x20;

TensorDock may report, by disclosing, examining, and safeguarding relevant customer data in compliance with applicable laws any potentially unlawful activity or violations of this AUP to law enforcement authorities or third parties. We may report any activity we suspect violates our AUP, the law, or regulations to appropriate law enforcement officials or third parties and cooperate with them in providing related information.

### 10. Reporting AUP Violations

If a user is aware of any possible violations of the AUP, the user can contact TensorDock at <support@tensordock.com> with a full explanation of the violations.

### 11. Appeals

If you believe that a decision regarding a violation of our Acceptable Use Policy has been made in error or unfairly, please don't hesitate to reach out to us for an appeal. We're here to assist you in resolving any concerns you may have. Legitimate reinstatement requests will be reviewed by TensorDock staff and answered with a decision.

When a user can agree to abide by our Acceptable Use Policies moving forward and has made the changes necessary to address the violation(s), we may choose to reinstate their account or data depending on the circumstances and severity of the initial violation.

### 12. Change Log

June 27, 2024: Complete overhaul


# Taxes, VAT, GST

This page serves as a guide to our policies, and nothing here supersedes our Terms of Service or Supplier Hosting Agreement, or should be construed as legal advice.

**Customers:**

All prices listed on our website don't include sales tax, value-added tax (VAT), goods and services tax (GST), or any other government-required taxes or fees. Currently, TensorDock users are responsible for paying all applicable Taxes relating to any use of our services.

We expect all users in countries that collect VAT and GST to provide proper business tax identification, such as an VAT or GST ID, so that we may apply the "reverse charge mechanism". This means that the buyer is responsible for calculating and paying VAT or GST.

The reverse charge mechanism is only applicable to businesses and not consumers. As such, we cannot serve users without a registered VAT or GST ID in countries that collect VAT or GST, since we do not currently have the capacity to handle it. We are planning to add automatic VAT and GST functionality as soon as possible so that we can continue to serve consumers worldwide.

Keep in mind this is not applicable to the US, as the US does not collect VAT or GST at the federal or state level. US businesses may opt to provide their EIN and have it appear on invoices, but are not required to do so.

**Hosts:**

If you're a US host, we require your Social Security Number (SSN) so that we can issue you a 1099 and report your earnings to the IRS, in case your income through TensorDock is higher than the $600/year threshold.


# Downtime Compensation

Last Updated: June 27, 2024

While we do our best to uphold the compensation policies listed below, we may be unable to fulfill them in special circumstances. This page serves as a guide to our policies, and nothing here supersedes our Terms of Service or Supplier Hosting Agreement.

## Good Practices. Remember to always...

* Make offsite backups
* AI/ML Inference: Distribute workloads across multiple hosts and load balance accordingly
* AI/ML Training: Checkpoint training jobs

## Downtime Measurements

We monitor downtime from at least four servers located in different regions. If the servers reach a quorum and agree that a GPU hostnode has gone offline, then we will count that as downtime.&#x20;

## Downtime Remediation

Our minimum compensation is $5, and our maximum compensation is capped at 100% of a client's previous month's spending.&#x20;

#### Top Hosts

These are typically hosts who've demonstrated reliability and whose GPUs are located in data centers, with services marketed as such. Because we hold these hosts to standards meant for mission critical workloads, we deduct **10x the hourly rate** multiplied by the downtime and add that to the customer's account. For example, if a client workload was running at $10/hour and incurred 1 hour of downtime, we'd add $100 of compensation.

#### Standard Hosts

These are hosts who may be hosting servers in residential or business facilities. They may have little or no redundancy. Some may be located in a data center but opt to be marketed as a standard host to face lower downtime penalties. In any case, expect that a system hosted with a standard host will eventually experience downtime.

For downtime, we deduct **5x the hourly rate** multiplied by the downtime and add that to the customer's account.

## Data Loss Remediation

In the event of unexpected data loss, you will be provided with credits equivalent to 40x the hourly rate you were paying when your virtual machine went offline.

## Change Log

June 27, 2024: Modified wording. Increased Top Host compensation from 5x hourly rate to 10x hourly rate. Increased Standard Host compensation from refund to 5x hourly rate.


# Supplier Hosting Agreement

Last updated: March 26, 2024.

This agreement (‘Supplier Hosting Agreement’) sets out the legal terms on which TensorDock.com, Inc of 16192 Coastal Highway, Lewes, Delaware, United States 19958 (‘TensorDock’) contracts with the individual or entity providing compute power for the TensorDock Marketplace (‘Supplier’).

#### Definitions

* End Users are individuals or entities who have registered accounts with TensorDock's Marketplace product for the purpose of renting computing infrastructure.
* Cloud Services refers to the computing infrastructure rental provided by Supplier for TensorDock's End Users.
* TensorDock Confidential Information refers to any and all information whether in oral, written or electronic form sent from TensorDock to Supplier that is not publicly stated on TensorDock’s website, documentation, or press releases or that is not public knowledge. This includes technical or business expertise, finance details, intellectual property rights, media assets, strategy plans, product details, and End Users, including such details about other arrangements or operations of any person, firm, or organization associated with TensorDock.
* Customer Confidential Information refers to any and all information whether in oral, written or electronic form sent from TensorDock to Supplier about Customer that is not publicly stated on TensorDock’s website, Customer’s website, publicly available documentation, or that is not public knowledge. This includes technical or business expertise, finance details, intellectual property rights, media assets, strategy plans, product details, and customers, including such details about other arrangements or operations of any person, firm or organization associated with Customer
* Customer Data refers to all data, software, information (including Customer Confidential Information) which, by Customer's actions, are hosted or processed on the Cloud Services
* Platform, Marketplace Platform, TensorDock Platform, and TensorDock Marketplace all refer to the software-as-a-service platform facilitating Customers’ access to Suppliers’ Cloud Services

#### TensorDock’s Obligations

TensorDock owns and operates the TensorDock Platform, which facilitates access to and use of Cloud Services hosted by Supplier. TensorDock assists End Users in setting up their projects, facilitates Customer access to Cloud Services, and provides customer support for End Users when issues arise, in exchange for taking a fee.&#x20;

#### Supplier’s Obligations

Supplier agrees to grant TensorDock a non-exclusive license to advertise, list, and provide details of Supplier’s Cloud Services on the TensorDock Marketplace and serve the Cloud Services to the End User at the Supplier's set price.

Supplier is responsible for reliably operating Cloud Services and indemnifies TensorDock and Customer for any breach of obligations. In addition, Supplier will implement both physical and network security measures to guarantee that Cloud Services will not be accessed by third parties to ensure the security of Customer Data and Confidential Customer Information.&#x20;

**Supplier’s Service Level Agreement (SLA)**

Supplier understands that TensorDock provides an SLA to Customer; thus, if Supplier does not achieve 100% uptime, TensorDock reserves the right to charge Supplier a penalty to uphold TensorDock’s SLA. All penalties are transferred to Customer as remediation for the downtimes, and TensorDock does not profit from such transactions.&#x20;

* Short Network Disconnects or Reboots: If any physical servers undergo unplanned reboots or disconnect from TensorDock’s redundant monitoring service for two (2) or more continuous minutes but less than one hour due to the Supplier’s fault, TensorDock will charge Supplier a penalty worth 5 hours multiplied by the hourly earnings of the server when the interruption occurred. For instance, if Customer was running a workload of $1/hr that was interrupted by a reboot, TensorDock will deduct $1 \* 5 = $5 from Supplier’s balance and deposit that into Customer’s balance. TensorDock understands and accepts that the cloud security policies of Supplier may interfere with the workloads of the Customers, and may cause disconnections related to the identification of malicious inbound or outbound traffic. These types of interruptions will not be considered downtime, and Supplier will not pay any penalties for such interruptions.
* Extended Downtimes: If any physical servers undergo unscheduled extended downtimes of one hour or greater, TensorDock will charge Supplier a penalty of five (5) multiplied by the hourly earnings of the server when the interruption started. For instance, if Customer was running a workload of $1/hr that was interrupted by a one-day interruption, TensorDock will deduct 5 \* $1 \* 24 = $120 from Supplier’s balance and deposit that into Customer’s balance.
* Data Loss: Supplier understands that Customer rents Supplier’s hardware to run mission-critical workloads, and that losing data might lead to Customer needing to re-compute weeks’ worth of previous work. If Supplier’s hardware loses Customer data, TensorDock reserves the right to charge Supplier a penalty up to but not exceeding Supplier’s previous month’s earnings on the impacted server to compensate Customer.&#x20;

**Supplier Rights**

TensorDock does not accept any responsibility or liability for unauthorized access to the Cloud Services, misuse of the Cloud Services by the customer, or any damages including but not limited to effect of interfering adversely with, the operation of any hardware or software, including any bugs, worms, logic bombs, Trojan horses or any other such programs; or use of the Cloud Services in a manner which infringes supplier’s intellectual property rights.&#x20;

However, if and only if there is documented evidence of illegal activities occurring on Cloud Services directly consumed by Customer, then Supplier may ask to terminate this contract. In the event of this, TensorDock shall only pay for the prorated time of services consumed by customer before the notice, and TensorDock shall receive fourteen (14) days of free access to all previously provisioned Cloud Services to migrate Customer Data to a different supplier.&#x20;

**Intellectual Property Rights**

TensorDock retains ownership of all intellectual property rights in the TensorDock Marketplace and any materials created by TensorDock in the course of fulfilling its obligations. In addition, Supplier retains ownership of all intellectual property rights in supplier data, and Customer shall retain ownership of all intellectual property rights of their Customer Data and Customer Confidential Information.

TensorDock may use any feedback and suggestions for improvement relating to the Marketplace provided by the supplier without charge or limitation.

The supplier shall indemnify TensorDock and/or customer from any losses, claims, damages, liability, costs, and expenses incurred by them as a result of any action or claim that the transmission, receipt, copying, installation, use, possession, or other utilization of data or Cloud Services infringes the intellectual property rights of any supplier.

**Confidentiality**

Supplier agrees to use TensorDock’s Confidential Information only in the exercise of its rights and performance of its obligations under the agreement and not to disclose TensorDock’s Confidential Information to any other party, except as required by law, court, governmental, regulatory or supervisory authority, or any other authority of competent jurisdiction.

Supplier also agrees not to disclose any Customer Confidential Information or Customer Data and shall assume liability for TensorDock and Customer from any losses, damages, liability, costs, and expenses they may incur as a result of any breach of their confidentiality obligations.

The supplier shall not access Customer Data or any Cloud Services used by the customer, even hosted by Supplier, without prior written consent from TensorDock.

#### Non-Circumvention Policy&#x20;

Supplier acknowledges and agrees that a portion of TensorDock’s compensation is tied to facilitating Customer’s access to the Cloud Services.

During the term of the Supplier Hosting Agreement, Supplier agrees not to engage in any attempts to contact, solicit, communicate with, or seek the contact information of other Customers or suppliers for the purpose of using or providing Cloud Services outside of TensorDock; and not to contact or sell Cloud Services to the any customers who have purchased TensorDock’s Services during the Supplier Hosting Agreement term or within the 12 months preceding the Supplier Hosting Agreement without paying a ten percent (10%) commission of Customer’s transaction volume on Supplier to TensorDock; or individuals or entities with whom TensorDock is currently or has been in discussions regarding the sale of TensorDock Services during the term of the Agreement or within the 12 months preceding the Agreement without paying a ten percent (10%) commission of Customer’s transaction volume on Supplier to TensorDock.

For a period of 48 months after the Supplier Hosting Agreement’s termination, Supplier agrees that, except for general recruitment efforts open to all applicants and not specifically aimed at TensorDock, supplier shall not, without prior written consent from TensorDock, engage in directly or indirectly seek to recruit, hire, or engage in any contractual relationship with any employees or personnel of TensorDock; or to provide assistance or instructions to any third party regarding the recruitment, employment, contracting, or subcontracting of personnel from TensorDock.&#x20;

#### Warranties

Both parties represent and warrant that they have the power and authority to enter into and perform their obligations under the agreement. Supplier represents and warrants that they have the right to grant TensorDock.com, Inc the rights to use the Cloud Services and that they will provide complete and accurate information about Cloud Services.

All other warranties, conditions, terms, undertakings, or obligations, whether express or implied, are excluded to the fullest extent allowed by the applicable laws.

#### Liabilities

TensorDock is not responsible for any indirect, special, or consequential loss or damage, regardless of the cause (contract, tort, breach of statutory duty, or otherwise) related to the Agreement or any related activities. TensorDock’s maximum total liability to supplier for all claims (regardless of the cause) related to the Agreement or any related activities shall not exceed the total payouts withdrawn by Supplier via Stripe Connect over the previous ninety (90) days.

#### Contract Termination

In the event of an unplanned disconnect of Cloud Services from Supplier’s hosting site to the public internet, data breach, or data loss of any sort, TensorDock reserves the right to terminate this contract and have one (1) free week to remove Customer Data from Supplier’s Cloud Services. TensorDock may also immediately terminate the Supplier Hosting Agreement, deactivate supplier’s account, and/or seize previous earnings if supplier materially or persistently breaches the Agreement.

Under normal circumstances, TensorDock may terminate this Supplier Hosting Agreement with one (1) week of notice. Also, this agreement will terminate if TensorDock ceases to exist, or if the provision of Cloud Services or TensorDock.com, Inc Services becomes illegal. TensorDock will make reasonable efforts to give supplier notice beforehand, but this may not always be possible.

If Customers are running actively using Supplier’s Cloud Services, Supplier must give at least one month of written notice via email to TensorDock before terminating this agreement or decommissioning servers, but if no Customers are actively using Supplier’s Cloud Services, Supplier may remove Supplier’s servers or terminate this agreement without notice.

#### Other Important Information

Suppliers can review the Agreement at any time on TensorDock’s website. TensorDock reserves the right to change the Agreement at any time by posting updates to its website periodically. TensorDock will submit a written (email) notification with the statement of changes and/or an Agreement Addendum to this contract to be validated and agreed by Supplier. If TensorDock is required to do so by law, TensorDock will notify the Supplier by way of email, and such changes shall take effect within the minimum timeframe as allowed by law. If Supplier does not agree with the changes, it may terminate the Agreement by providing TensorDock with notice within a fourteen (14) day period, otherwise supplier will be deemed to have accepted the changes.

Suppliers can contact TensorDock at any time by emailing <hello@tensordock.com>.

Supplier may not assign, transfer, sub-license or deal in any other manner with any or all of its rights or obligations under the Agreement, without TensorDock’s prior written consent. TensorDock reserves the right to transfer, assign, sub-contract or deal in any other manner with any or all of its rights or obligations under the Agreement, without notifying Supplier or receiving their consent.

The Supplier Hosting Agreement constitutes the entire agreement between TensorDock and Supplier and supersedes and extinguishes all previous agreements, promises, assurances, warranties, representations and understandings between them, whether written or oral, relating to its subject matter.

The Supplier Hosting Agreement and any dispute or claim arising out of, or in connection with it, its subject matter or formation (including non-contractual disputes or claims) shall be governed by, and construed in accordance with, the laws of the state of Delaware in the United States.

The parties irrevocably agree that this agreement and any dispute or claim arising out of, or in connection with it, shall be dealt with via arbitration. The number of arbitrators shall be one. The seat, or legal place, of arbitration shall be Delaware. The language to be used in the arbitral proceedings shall be English.

Any obligation of TensorDock under the Supplier Hosting Agreement to comply or ensure compliance with any law shall be limited to compliance only with laws where TensorDock.com, Inc is established.

#### Payment

TensorDock shall give Supplier the ability to set their own a la carte per-resource pricing. For on-demand usage, TensorDock will track and monitor usage by Customers and credit Supplier’s account accordingly. Once Supplier’s account surpasses $250 of account balance, Supplier will be able to withdraw their balance.

If Supplier and TensorDock agree on providing monthly or longer term subscription billing options for customers, earnings from monthly or longer subscription servers will be deposited at the end of each calendar month.

TensorDock will take a twenty percent (25%) fee from Supplier’s earnings.

Supplier will create a Stripe Connect account on the TensorDock Platform linking their bank account to the TensorDock Platform. Supplier agrees to withdraw their accumulated funds at least once during each month. Supplier may withdraw their balance spread over multiple days each month but agrees to only withdraw at most one-thousand US dollars ($1,000) within a single 24-hour period through Stripe Connect. Stripe will convert the currency to Supplier’s preferred currency at a mid-market price, with slippage paid for by TensorDock. Alternatively, Supplier can provide TensorDock a bank account wiring details, and TensorDock will wire Supplier’s account balance at the end of each month, in Euros.

Supplier is responsible for the accuracy and completeness of their bank account information listed in Stripe Connect, and TensorDock is not liable for delays or losses resulting from withdrawing money to an incorrect payment method.


