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

# How to Deploy a NestJS app on a Scaleway Instance using Clouddley

> Learn how to deploy a NestJS app on a Scaleway Instance using Clouddley.

export const date_0 = "Updated on June 09, 2025"

Taking your [NestJS](https://docs.nestjs.com/) app live is easier than it sounds. With [**Clouddley**](https://clouddley.com) handling deployments and connecting smoothly with Scaleway, you can skip the setup and focus on your code. This tutorial walks you through deploying a NestJS app on a Scaleway Instance, whether it’s for a personal project or production.

## Prerequisites

Before you dive in, make sure you have the following:

* A [Clouddley account](https://clouddley.com/)
* [Scaleway account](https://www.scaleway.com/en/) with billing enabled
* A [GitHub](https://github.com/) or [Bitbucket](https://bitbucket.org/product/) account.
* [Node.js](https://nodejs.org/en/download/current) (version 16 or higher) installed locally
* An [API key](https://www.scaleway.com/en/docs/iam/how-to/create-api-keys/) on Scaleway to manage your instances.
* [Git installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) locally
* Basic familiarity with command line interface

## Set up a New NestJS App

If you don’t already have a NestJS app ready, let’s quickly spin one up.

<Steps>
  <Step title="Install NestJS CLI">
    Open your terminal and run:

    ```bash theme={null}
    npm i -g @nestjs/cli
    ```

    This command will scaffold a new NestJS project in a folder called `my-app`. You’ll be asked to choose a package manager, go with whatever you’re comfortable with (npm or yarn works just fine).
  </Step>

  <Step title="Navigate to the NestJS Project">
    Once it’s done, move into your project directory:

    ```bash theme={null}
    cd my-app
    ```
  </Step>

  <Step title="Install Dependencies">
    Install the necessary dependencies:

    ```bash theme={null}
    npm install
    ```
  </Step>

  <Step title="Run the App">
    You can now run your NestJS app locally to make sure everything is set up correctly:

    ```bash theme={null}
    npm run start
    ```

    Open your browser and go to [http://localhost:3001](http://localhost:3001). You should see “Hello World!”, you're good to go.
  </Step>
</Steps>

Now that you have a basic NestJS app set up, it’s time to prepare it for deployment.

## Push Your Code to GitHub

First, you need to push your NestJS app code to a Git repository.

<Steps>
  <Step title="Create a New Repository on GitHub">
    Go to [GitHub](https://github.com/) and create a new repository. Give it a name and leave the rest of the settings as default (no README, no .gitignore, you already have those locally).
  </Step>

  <Step title="Initialize Git">
    If you haven’t already, initialize a Git repository in your project folder:

    ```bash theme={null}
    git init
    ```
  </Step>

  <Step title="Add and Commit Your Code">
    Add your files and commit:

    ```bash theme={null}
    git add .
    git commit -m "Initial commit"
    ```
  </Step>

  <Step title="Create branch and add Remote Repository">
    Create a branch and link your local repository to the GitHub repository you created:

    ```bash theme={null}
    git branch -M main
    git remote add origin <your-repo-url>
    ```
  </Step>

  <Step title="Push code">
    Finally, push your code to GitHub:

    ```bash theme={null}
    git push -u origin main
    ```
  </Step>
</Steps>

Now your NestJS app is pushed to GitHub, let's create a Scaleway instance.

## Create a Scaleway instance using Scaleway CLI

* First, install the Scaleway CLI if you haven’t already done so. It helps you manage Scaleway resources right from your terminal.

```bash theme={null}
curl -sSL https://install.scaleway.dev | bash
```

* Once it’s installed, authenticate by running the command:

```bash theme={null}
scw init
```

You’ll be prompted to enter your <b>access key</b> and <b>secret key</b>. You can [generate](https://www.scaleway.com/en/docs/iam/how-to/create-api-keys/) these from your Scaleway Console under `API Keys`.

* To make sure everything’s working run:

```bash theme={null}
scw instance server list
```

You should see a list of any existing servers or none if this is your first time.

* Configuring security groups is essential for controlling access to your instance. Create a security group that allows HTTP and HTTPS traffic:

```bash theme={null}
scw instance security-group create name=my-sec-group description="Allow port access"
```

This command creates a security group named `Allow port access`.

See the output below:

<Frame caption="Creating a Security Group">
  <img src="https://mintcdn.com/clouddley/YkMcNqR8t_n43UbS/images/scaleway-create-sec.png?fit=max&auto=format&n=YkMcNqR8t_n43UbS&q=85&s=e4f788509b6d9883e066c0f0337cc104" width="1697" height="720" data-path="images/scaleway-create-sec.png" />
</Frame>

* Next, add rules to allow inbound traffic on port `3001` and `22`. Run the following commands:

```bash theme={null}
scw instance security-group create-rule \
  security-group-id=<your-sg-id> \
  protocol=TCP \
  direction=inbound \
  action=accept \
  ip-range=0.0.0.0/0 \
  dest-port-from=3001
```

```bash theme={null}
scw instance security-group create-rule \
  security-group-id=<your-sg-id> \
  protocol=TCP \
  direction=inbound \
  action=accept \
  ip-range=0.0.0.0/0 \
  dest-port-from=22
```

<Info>Replace `<your-sg-id>` with the ID of the security group you just created. You can find your security group ID by running the command `$ scw instance security-group list` and this will list all security groups.</Info>

You see the output below:

<Frame caption="Creating a Security Group Rule">
  <img src="https://mintcdn.com/clouddley/YkMcNqR8t_n43UbS/images/scaleway-create-rule-3001.png?fit=max&auto=format&n=YkMcNqR8t_n43UbS&q=85&s=792f325458fcd62e585aa43f62fb8ab1" width="1162" height="700" data-path="images/scaleway-create-rule-3001.png" />
</Frame>

* Now, create a new instance:

```bash theme={null}
scw instance server create \
  name=app-server \
  type=DEV1-S \
  image=ubuntu_focal \
  zone=fr-par-1 \
  ip=new \
  security-group=id=<your-sg-id>
```

<Info>Replace `<your-sg-id>` with the ID of the security group you created earlier.</Info>
This command creates a new instance named `app-server` with the `DEV1-S type`, using the `Ubuntu Focal image` in the `fr-par-1` zone. It also assigns a new public IP and applies the security group you created earlier.

You should see output similar to this:

<Frame caption="Creating a Scaleway Instance">
  <img src="https://mintcdn.com/clouddley/YkMcNqR8t_n43UbS/images/main-create-server.png?fit=max&auto=format&n=YkMcNqR8t_n43UbS&q=85&s=2d77ecd404e179e1c00fb1cf80d6630c" width="1427" height="647" data-path="images/main-create-server.png" />
</Frame>

Once your server is ready, get its public IP:

```bash theme={null}
scw instance ip list
```

You should see your new instance listed with its public IP address. Note this down, as you’ll need it later.

## Deploy

Once your NestJS app and your Scaleway instance are ready, it's time to deploy using Clouddley.

* Open your browser, log in to your [Clouddley account](https://app.clouddley.com/auth/signin)
* Click on the <b>Apps</b> in the left sidebar.
* Click on **Deploy App** to begin.

<Frame caption="Accessing Apps">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-dashboard.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=a351a8b6a71fd42b76757eb1d5b03269" width="3772" height="1705" data-path="images/Apps-dashboard.png" />
</Frame>

<br />

<b>Step 1: Configure your service</b>

* Choose your Git provider: either <b>GitHub</b> or <b>Bitbucket</b> and authorize Clouddley to access your repository. For this tutorial, we’ll use GitHub.
* Click on <b>Continue with GitHub</b>

<Frame caption="Choose your Git hosting service">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-configure-service.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=2875d8a62a7761282438986e2f4b74b6" width="3820" height="1707" data-path="images/Apps-configure-service.png" />
</Frame>

<br />

<b>Step 2: Configure Git</b>

* To connect your GitHub user or organization account, click the <b>Select username/organization</b> dropdown and <b>Add GitHub account</b>.
* Once connected, choose the <b>repository</b> and <b>branch</b> that contains your NestJS app.
* Click on <b>Next</b> to proceed.

<Frame caption="Setup the NestJS application repository on Clouddley">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-configure-git.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=39ccbf1aad9cddc8d4de699480f9f752" width="3807" height="1715" data-path="images/Apps-configure-git.png" />
</Frame>

<br />

<b>Step 3: Connect Your Scaleway Instance</b>

* From the **Choose or add server** dropdown, select your VM if it appears in the list. If not, click **+ Add Virtual Machine**.

* To add your VM, enter your Scaleway Instance's <b>IP address</b> as <b>VM host</b>,  <b>VM user</b>, and the <b>VM port</b> for SSH access.

* Once you've entered the details, verify the connection using the **Clouddley CLI(recommended)** or **SSH**.

<Accordion title="How to Install Clouddley CLI to Verify your Scaleway Instance">
  - Open your local machine’s command line, then connect to the remote VM you want to configure with Clouddley. Use this command to SSH into your Scaleway instance:

  ```bash theme={null}
  ssh root@<your-instance-ip>
  ```

  * Install Clouddley CLI by running the command:

  ```bash theme={null}
  curl -L https://raw.githubusercontent.com/clouddley/cli/main/install.sh | sh
  ```

  * To add the SSH public key, run the command:

  ```bash theme={null}
  clouddley add key
  ```

  Using the CLI, you can deploy resources, manage configurations, and automate tasks efficiently.
</Accordion>

* Click <b>Verify</b> to confirm the connection, then click <b>Next</b>.

<Frame caption="Configure virtual machine on Clouddley">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-configure-VM.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=833ea7178fc7b09e20cbfcad85f46771" width="3817" height="1705" data-path="images/Apps-configure-VM.png" />
</Frame>

<br />

<b>Step 4: Configure app settings</b>

* Now, insert the <b>name</b> of your application and specify the <b>port</b> it runs on.
* Click on **Next**

<Frame caption="Configure the App name and port">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-nestjs-name.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=f86d24e9e41138c7596994908d587d5d" width="3820" height="1715" data-path="images/Apps-nestjs-name.png" />
</Frame>

<Tip>The firewall of the virtual machine should allow access to the application port.</Tip>

<b>Step 5: Add Environment Variables </b>

* Click on <Icon icon="plus" iconType="solid" /> <b>Add Variable</b>
* Choose an ENV mode: either a <b>single variable</b> or <b>import variables</b>. Learn more [here](https://docs.clouddley.com/apps/extras/environment-variables).

<Tabs>
  <Tab title="Single Variable">
    <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/TA-singleVar.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=a72c90362f7aa5c82cc72a30d719b30e" alt="Single Variable ENV mode" width="1210" height="945" data-path="images/TA-singleVar.png" />
  </Tab>

  <Tab title="Import Variables">
    <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/TA-importVar.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=912fde4f5978f8b78b78248d71ad92ad" alt="Import Variables ENV mode" width="1227" height="990" data-path="images/TA-importVar.png" />
  </Tab>
</Tabs>

* Add the key-value pairs and click on <b>Save</b>
* Click on <b>Next</b>

<Frame caption="Adding environment variables">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-nestjs-env.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=0b72ef97461c57e009bd8cf8016e0bf9" width="3820" height="1707" data-path="images/Apps-nestjs-env.png" />
</Frame>

<br />

<b>Step 6: Setup Notifications (optional)</b>

* To configure the notifications settings of the application, click on <Icon icon="plus" iconType="solid" /> <b>Add Alert</b>
* Select the <b>Alert type</b>. For this tutorial, we will set up Email notifications.
* Toggle on the buttons for the deployment events (failed, timed out, or success) you want to get notified of.
* Enter your <b>email address</b> (or multiple, if needed).
* Click on <b>Save</b>
* Click on **Deploy**

<Frame caption="Notifications set up and creation of NestJS application on Clouddley">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-notif.gif?s=79c66a68ffd5284ae5900f7a28855366" width="600" height="267" data-path="images/Apps-notif.gif" />
</Frame>

<br />

<b>Step 7: Test and Verify the app</b>

* Click on <b>Go to Dashboard</b>. Your app will be visible on the apps dashboard.
* Once deployment completes, its status will update from `Deploying` to `Online`.

<Frame caption="NestJS application dashboard overview">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-nestjs-dashboard.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=a447e3e0c03c424bc82144920cb02b8d" width="3780" height="1710" data-path="images/Apps-nestjs-dashboard.png" />
</Frame>

<br />

* To test it, click the 🌐 Website button in the top right corner to open your live app in the browser. You should see your NestJS app running on your Scaleway instance.

<Frame caption="NestJS application running from Clouddley on a Scaleway Instance">
  <img src="https://mintcdn.com/clouddley/YkMcNqR8t_n43UbS/images/nest-app.png?fit=max&auto=format&n=YkMcNqR8t_n43UbS&q=85&s=f71a839ec98e16796473d742a6f47b1a" width="1904" height="927" data-path="images/nest-app.png" />
</Frame>

## After Deployment: Managing Your NestJS App

Once your NestJS app is live on your Scaleway instance, managing it through Clouddley is straightforward. The dashboard gives you all the control you need without having to SSH into your server.\
You can change your deployment settings, [roll back](https://docs.clouddley.com/apps/extras/how-to-rollback-an-application) to a previous version, [scale](https://docs.clouddley.com/apps/extras/scale-applications-on-clouddley) up if traffic grows, and even [pause or resume](https://docs.clouddley.com/apps/extras/how-to-pause-and-resume-applications) your app when needed. Everything’s designed to be simple and quick.
Need to update [environment variables](https://docs.clouddley.com/clouddley-triggr/triggr-apps/extras/environment-variables) or check your logs? That’s all built in too. You’ll also be able to connect a [custom domain](https://docs.clouddley.com/apps/extras/custom-domain) and keep track of your deployment history, right from the same dashboard.

<AccordionGroup>
  <Accordion title="Best Practices When Working with NestJS">
    Building with NestJS is already a step in the right direction. It gives you structure, scalability, and a clean development experience. But to get the most out of it, here are a few best practices you’ll want to keep in mind.

    <Icon icon="check" iconType="solid" /> <b>Keep your folders organised</b>\
    Stick to a modular folder structure. Group your features by domain (like users, auth, products) and keep related files together. This makes your codebase easier to navigate as it grows.

    <Icon icon="check" iconType="solid" /> <b>Rely on dependency injection</b>\
    NestJS is built around dependency injection, so use it. Avoid tightly coupling your services or hardcoding dependencies. Inject what you need through constructors and let Nest handle the rest.

    <Icon icon="check" iconType="solid" /> <b>Use DTOs for data validation</b>\
    Data Transfer Objects (DTOs) aren’t just a nice-to-have. They help validate and shape incoming data, keeping your app secure and predictable. Use them with class-validator to enforce rules and avoid nasty surprises.

    <Icon icon="check" iconType="solid" /> <b>Keep business logic in services</b>\
    Your controllers should be lean. Move all the actual business logic into services so your code stays clean and reusable. Controllers should only handle requests and responses.

    <Icon icon="check" iconType="solid" /> <b>Write unit and e2e tests</b>\
    NestJS makes testing easy with built-in tools. Take advantage of it. Write unit tests for your services and end-to-end tests for your routes. It helps catch bugs early and gives you confidence when deploying.

    <Icon icon="check" iconType="solid" /> <b>Use environment variables</b>\
    Avoid hardcoding secrets, ports, or database configs. Use environment variables and load them properly with @nestjs/config. This keeps your app flexible and production-ready.

    <Icon icon="check" iconType="solid" /> <b>Handle errors gracefully</b>\
    Use filters and exception handling to return meaningful errors. Don’t leave users (or your logs) guessing when something goes wrong.
  </Accordion>
</AccordionGroup>

## Conclusion

And that’s it! You’ve deployed your NestJS app to a Scaleway instance using Clouddley. From setup to deployment, everything stays simple and efficient. This is just the beginning, Clouddley scales with your project and works for other apps too.

Got feedback or ideas to improve the experience? We’d love to hear from you. We can’t wait to see what you deploy next!

<Card title="Getting started with Clouddley?" icon="user-plus" cta="Sign up today and enjoy a 30-day free trial — no credit card required" href="https://app.clouddley.com/auth/signup" horizontal>
  A backend infrastructure for your own compute. Run apps, databases, brokers, and AI workloads on your VMs, bare metal, or VPS.
</Card>

## Resources

* [Clouddley Documentation](https://docs.clouddley.com/)
* [Run Dockerfile on Clouddley](https://docs.clouddley.com/apps/extras/deploy-an-application-with-a-dockerfile-on-clouddley)
* [Scaleway Documentation](https://www.scaleway.com/en/docs/)
* [NestJS Official Documentation](https://docs.nestjs.com/)
* [Scaleway CLI Documentation](https://www.scaleway.com/en/docs/cli/)
* [GitHub Docs](https://docs.github.com/en)

<div className="flex items-center gap-2.5 mb-6 py-0 my-0">
  <img src="https://res.cloudinary.com/dkbbdg1ko/image/upload/faith-kovi-headshot_hbezxg" alt="Faith Kovi" className="w-12 h-12 rounded-full" />

  <div>
    <div className="flex items-center gap-3">
      <p className="text-sm text-gray-600 dark:text-gray-300 flex items-center gap-1 py-0 my-0">
        <span>By</span>

        <a href="https://x.com/Vera__Kaka" target="_blank" rel="noopener noreferrer" className="font-semibold">
          <span>Faith Kovi</span>
        </a>
      </p>

      <button
        onClick={async () => {
      if (navigator.share) {
        try {
          await navigator.share({
            title: document.title,
            text: "Check this out!",
            url: window.location.href,
          });
        } catch (error) {
          console.error("Error sharing:", error);
        }
      } else {
        alert("Sharing not supported on this device/browser.");
      }
    }}
        className="ml-1 hover:scale-110 transition-transform duration-200 ease-in-out"
      >
        <Icon icon="share-nodes" iconType="light" color="#D1D5DB" size="20" />
      </button>

      <button
        onClick={() => {
      navigator.clipboard.writeText(window.location.href);
      alert("Link copied!");
    }}
        className="ml-1 hover:scale-110 transition-transform duration-200 ease-in-out"
      >
        <Tooltip tip="Copied!">
          <Icon icon="clone" iconType="light" color="#D1D5DB" size="18" />
        </Tooltip>
      </button>
    </div>

    <p className="text-xs text-gray-500 py-1 my-0">
      {date_0}
    </p>
  </div>
</div>
