> ## 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 Flask App on a DigitalOcean Droplet using Clouddley

> Learn how to deploy a Flask App on a DigitalOcean Droplet using Clouddley.

export const date_0 = "Updated on May 20, 2025"

Deploying a [Flask](https://flask.palletsprojects.com/en/stable/) app to a virtual machine can feel overwhelming, but [**Clouddley**](https://clouddley.com/) makes it simple. It automates deployments, connects smoothly with DigitalOcean, and handles the setup for you. In this tutorial, you’ll learn how to deploy your Flask app to a DigitalOcean Droplet with ease.

## Prerequisites

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

* A [Clouddley account](https://clouddley.com/)
* A [DigitalOcean account](https://www.digitalocean.com/)
* A [GitHub](https://github.com/) or [Bitbucket](https://bitbucket.org/product/) account
* [`doctl` (DigitalOcean CLI)](https://docs.digitalocean.com/reference/doctl/how-to/install/) installed and configured
* [DigitalOcean API](https://cloud.digitalocean.com/account/api/tokens) token generated
* [Python](https://www.python.org/downloads/) installed locally
* [pip](https://pip.pypa.io/en/stable/installation/) installed
* [Git installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) locally
* Basic familiarity with the Linux command line

## Create a Flask Application

Before you deploy your Flask app, it's a good idea to make sure everything runs smoothly on your local machine. Let’s walk through how to set up and test the simple Flask application step by step.

<Steps>
  <Step title="Create project folder">
    In your terminal, run:

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

  <Step title="Create and activate Virtual Environment(Optional but recommended)">
    Open the command line and run:

    * For Windows:

    ```bash theme={null}
    # Create virtual environment
    python -m venv venv

    # Activate the environment
    venv\Scripts\activate
    ```

    * For Linux/MacOS:

    ```bash theme={null}

    # Create virtual environment
    python3 -m venv venv

    # Activate the environment
    source venv/bin/activate
    ```

    <Info> Creating a virtual environment helps keep your project’s dependencies isolated, so they don’t conflict with other Python projects on your machine.</Info>
  </Step>

  <Step title="Install Flask">
    ```bash theme={null}
    pip install flask
    ```
  </Step>

  <Step title="Create the Flask App">
    Create a file named `app.py` and add the following code:

    ```python theme={null}
    from flask import Flask

    app = Flask(__name__)

    @app.route("/")
    def hello():
        return "Hello, World!"

    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=3070)
    ```
  </Step>

  <Step title="Open the App in Your Browser">
    With the server up and running, open your browser and head to:
    [http://localhost:3070](http://localhost:3070)
    You should see **"Hello, World!"** on the screen, that means your Flask app is working perfectly!
  </Step>
</Steps>

## Push Your Flask App to GitHub

Once your Flask app is running locally, the next step is to track it with Git and push it to a remote repository like GitHub or Bitbucket. This helps you manage changes over time and is also key for deploying with Clouddley.

In this tutorial, we’ll use GitHub. Let’s walk through the steps:

<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 code is pushed to GitHub, it is ready for deployment.

## Launch a DigitalOcean Droplet

Next, we’ll spin up a Droplet right from the command line using the `doctl` CLI.

Before you begin, ensure you have your DigitalOcean API token ready.

* Authenticate with your DigitalOcean account, run the following command in your terminal:

```bash theme={null}
doctl auth init
```

* Enter your <b>API token</b> when prompted. This will allow doctl to interact with your DigitalOcean account.

* Before creating your Droplet, make sure you have your `vpc_uuid` and `SSH key` added to your DigitalOcean account.

<Accordion title="How to find your VPC UUID">
  Open your terminal and run the command:

  ```bash theme={null}
  doctl compute vpc list
  ```

  This will display all your VPCs along with their UUIDs. Choose the one you want to use for your Droplet.
</Accordion>

<Accordion title="How to add your SSH Key to DigitalOcean">
  Open your terminal and run the command:

  ```bash theme={null}
  doctl compute ssh-key list
  ```

  If you do not have a previously created one, follow the steps below.

  <b>Step 1:</b> To generate an SSH key, run the command:

  ```
  ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  ```

  Press <b>Enter</b> to accept the default file location and choose a passphrase if you want one.

  <b>Step 2:</b> To add your SSH key to digitalocean, run:

  ```
  doctl compute ssh-key create "my-key-name" --public-key-file ~/.ssh/id_rsa.pub
  ```

  Replace `my-key-name` with a name you’ll recognize.
</Accordion>

* Now, let’s create a Droplet by running the following command in your terminal:

```bash theme={null}
doctl compute droplet create app-droplet \
  --image ubuntu-24-10-x64 \
  --size s-1vcpu-1gb \
  --ssh-keys your_ssh_key_id \
  --region nyc1 \
  --vpc-uuid your_vpc_uuid
```

<Note>Be sure to replace `your_vpc_uuid` and `your_ssh_key_id` with your actual values. The SSH key you add here lets Clouddley securely connect to your Droplet during deployments. It uses this key to access the VM, run deployment scripts, and manage your app with no passwords required.</Note>

You will see the output below

<img src="https://mintcdn.com/clouddley/YkMcNqR8t_n43UbS/images/create-droplet.png?fit=max&auto=format&n=YkMcNqR8t_n43UbS&q=85&s=01092030b97aa83f5e926bc1c481eeed" alt="Creating a droplet in DigitalOcean" width="2602" height="172" data-path="images/create-droplet.png" />

You’ve successfully created a Droplet named `app-droplet` using the `Ubuntu 24.10 x64` image, located in the `nyc1` region.

* To confirm that your Droplet was created successfully, run the command:

```bash theme={null}
doctl compute droplet list
```

This will display all your active Droplets, along with their names, IPs, and statuses.

<img src="https://mintcdn.com/clouddley/YkMcNqR8t_n43UbS/images/list-droplet.png?fit=max&auto=format&n=YkMcNqR8t_n43UbS&q=85&s=4a05e0eda04914c7cd7fff2c4a58aa99" alt="Listing all droplets in DigitalOcean" width="2575" height="167" data-path="images/list-droplet.png" />

Make sure to note the **public IP address** for SSH access.

## Deploy

Your Flask app and DigitalOcean Droplet are ready, now you can deploy your app.

* Open your browser and log in to your [Clouddley account](https://app.clouddley.com/auth/signin)
* Navigate to **Apps** and click on <b>Deploy App</b>

<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 Service</b>

* Choose your Git hosting service; either <b>GitHub or Bitbucket</b>. For this tutorial, we will be using 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, Select your <b>repository</b> and the <b>branch</b> from the dropdown list or quickly search.
* Click on <b>Next</b>

<Frame caption="Setup the Flask 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: Configure your Virtual Machine</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 droplet'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 DigitalOcean Droplet">
  - 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 DigitalOcean Droplet:

  ```bash theme={null}
  ssh root@<your-droplet-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 test the connection to your VM.
* Once it’s verified, click on <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>

* Enter the <b>name</b> of your flask application and 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-flask-name.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=ca288e5e518465d53a86aaf2047cf19d" width="3810" height="1710" data-path="images/Apps-flask-name.png" />
</Frame>

<br />

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

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

* To add environment variables, 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 your app needs and click on <b>Save</b>
* Click on <b>Next</b>

<br />

<Frame caption="Adding environment variables">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-flask-env.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=63a62e33061511d7aca87e33e4dc5f20" width="3815" height="1707" data-path="images/Apps-flask-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 Alerts.
* Toggle the events you want to track; failed, timed out, or successful deployments.
* Enter the <b>Email address</b> where you want to receive alerts. (You can add multiple email addresses)
* Click on <b>Save</b>
* Click on <b>Deploy</b>

<Frame caption="Notifications set up and creation of Flask 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>

* Once deployed, click on <b>Go to Dashboard</b>. Your app will be visible on the apps dashboard.
* When the status changes from `Deploying` to `Online`, your Flask app is live!

<Frame caption="Flask application dashboard overview">
  <img src="https://mintcdn.com/clouddley/p_iVNvg5jCvbMG-4/images/Apps-flask-dashboard.png?fit=max&auto=format&n=p_iVNvg5jCvbMG-4&q=85&s=d9eacb8bda08cf5559b6ad1ee7e04481" width="3777" height="1707" data-path="images/Apps-flask-dashboard.png" />
</Frame>

<br />

* To check it out, click the 🌐 Website button at the top right and this will open your deployed app in a new browser tab
* Now, go ahead and test its functionality to make sure everything's working just right.

<Frame caption="Flask application running from Clouddley on a DigitalOcean Droplet">
  <img src="https://mintcdn.com/clouddley/YkMcNqR8t_n43UbS/images/flask-app.png?fit=max&auto=format&n=YkMcNqR8t_n43UbS&q=85&s=de1d9ce8985974b3469a73b8f234d2fc" width="1306" height="662" data-path="images/flask-app.png" />
</Frame>

<br />

## Post-Deployment: Managing Your Flask App

After deploying your Flask app to a DigitalOcean Droplet using Clouddley, you can manage everything from the apps dashboard, there is no need to log into the server.\
You can modify deployment settings, [scale](https://docs.clouddley.com/apps/extras/scale-applications-on-clouddley) your app, [roll back](https://docs.clouddley.com/apps/extras/how-to-rollback-an-application) to a previous version, [pause or resume](https://docs.clouddley.com/apps/extras/how-to-pause-and-resume-applications) the app, or delete it when needed. The dashboard also includes helpful features like deployment history, live logs, [environment variables](https://docs.clouddley.com/apps/extras/environment-variables) management, and [custom domain](https://docs.clouddley.com/apps/extras/custom-domain) setup, making it easy to stay on top of your app after deployment.

<AccordionGroup>
  <Accordion title="Flask App Best Practices">
    Want to build Flask apps that are clean, reliable, and easy to scale? Here are some best practices worth sticking to:

    <Icon icon="check" iconType="solid" /> <b>Structure your project well</b>\
    Organize your code into modules and folders to keep things tidy and scalable.

    <Icon icon="check" iconType="solid" /> <b>Use virtual environments</b>\
    Isolate your dependencies so your project doesn’t clash with others on your system.

    <Icon icon="check" iconType="solid" /> <b>Keep secrets out of your code</b>\
    Store API keys and config values in environment variables and not directly in your files.

    <Icon icon="check" iconType="solid" /> <b>Break your app into Blueprints</b>\
    Blueprints help separate concerns and make large apps easier to manage.

    <Icon icon="check" iconType="solid" /> <b>Handle errors gracefully</b>\
    Set up custom error pages and log issues for smoother debugging and better UX.

    <Icon icon="check" iconType="solid" /> <b>Don’t use the dev server in production</b>\
    Always run Flask with a WSGI server like Gunicorn when deploying live.

    <Icon icon="check" iconType="solid" /> <b>Add basic logging</b>\
    Logging helps you spot issues early and track what’s happening in your app.

    <Icon icon="check" iconType="solid" /> <b>Test your app</b>\
    Even a few simple tests can save you from big surprises later.

    <Icon icon="check" iconType="solid" /> <b>Secure your app</b>\
    Watch out for CSRF, input validation, and other common web vulnerabilities.

    <Icon icon="check" iconType="solid" /> <b>Keep your packages updated</b>\
    Regularly update your dependencies to patch bugs and stay secure.
  </Accordion>
</AccordionGroup>

## Conclusion

And that’s a wrap! You’ve just seen how simple it is to deploy your Flask app to a DigitalOcean Droplet using Clouddley. We built Clouddley to take the stress out of deployments so you can spend more time building and less time configuring.

Got feedback or ideas to improve the experience? We’d love to [hear from you](https://clouddley.productlane.com/roadmap). 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>

## Additional Resources

Here are some helpful links to keep learning and refining your deployment setup:

* [Clouddley Documentation](https://docs.clouddley.com/)
* [Run Dockerfile on Clouddley](https://docs.clouddley.com/apps/extras/deploy-an-application-with-a-dockerfile-on-clouddley)
* [DigitalOcean Droplet guides](https://docs.digitalocean.com/products/droplets/)
* [Official Flask documentation](https://flask.palletsprojects.com/en/stable/tutorial/)
* [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>
