> ## 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 FastAPI Application on an AWS EC2 Instance using Clouddley

> Learn how to deploy a FastAPI Application on an AWS EC2 instance using Clouddley.

export const date_0 = "Updated on August 29, 2025"

Getting your [**FastAPI**](https://fastapi.tiangolo.com/) app up and running on AWS doesn’t have to feel like a big task. With an EC2 instance as your server and [**Clouddley**](https://clouddley.com) taking care of the heavy lifting, you can go from setup to launch in just a few steps. In this guide, I’ll walk you through the process so you can have your FastAPI app live on an AWS EC2 instance.

## Prerequisites

* A [Clouddley account](https://clouddley.com/)
* An [AWS account](https://aws.amazon.com/)
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed and configured on your local machine
* [AWS Access Keys](https://docs.aws.amazon.com/keyspaces/latest/devguide/create.keypair.html) with permissions to create and manage EC2 instances
* [FastAPI](https://fastapi.tiangolo.com/) installed on your local machine
* [Git installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) locally
* Basic familiarity with the Linux command line

## Create a FastAPI Application

If you don't have a FastAPI app yet, you can create a simple one by following these steps:

<Steps>
  <Step title="Set Up a Virtual Environment">
    Create and activate a virtual environment:

    ```bash theme={null}
    python3 -m venv venv
    source venv/bin/activate  # On Windows use `venv\Scripts\activate`
    ```
  </Step>

  <Step title="Install FastAPI and Uvicorn">
    Install FastAPI and Uvicorn using pip:

    ```bash theme={null}
    pip install fastapi uvicorn
    ```
  </Step>

  <Step title="Create the Application File">
    Create a file named `main.py` and add the following code:

    ```python theme={null}
      from fastapi import FastAPI
      import uvicorn

      app = FastAPI()


      @app.get("/")
      def read_root():
          return {"Hello": "World"}


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

  <Step title="Run the Application Locally">
    You can run your FastAPI app locally to test it:

    ```bash theme={null}
    python main.py
    ```

    Open your browser and navigate to `http://localhost:3033` to see `{"Hello": "World"}`.
  </Step>

  <Step title="Create a Procfile">
    To deploy your FastAPI app using Clouddley, you need a Procfile. Create a file named `Procfile` in the root of your project directory and add the following line:

    ```Procfile theme={null}
    web: python main.py
    ```
  </Step>
</Steps>

## Push Your Code to GitHub

You need to push your FastAPI 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>

Your FastAPI app code is now on GitHub, let's create an EC2 instance.

## Create an AWS EC2 Instance

Now, let's create an EC2 instance on AWS using AWS CLI. Make sure you have AWS CLI configured with your credentials.
First, create a VPC and security group if you don’t have one already.

* Create a VPC by running the command:

```bash theme={null}
aws ec2 create-vpc --cidr-block 10.0.0.0/16
```

You should see an output like below:

<Frame caption="Create a VPC on AWS">
  <img src="https://mintcdn.com/clouddley/wuHX6szeuQPUk6oa/images/aws-create-vpc.png?fit=max&auto=format&n=wuHX6szeuQPUk6oa&q=85&s=8365b482684727bfca822e9dac2bf06f" width="1407" height="547" data-path="images/aws-create-vpc.png" />
</Frame>

<br />

* Create a security group by running the command:

```bash theme={null}
aws ec2 create-security-group \
    --group-name new-security-group \
    --description "Security group for EC2 with port 8080 open" \
    --vpc-id <vpc_id> \
    --region us-east-1
```

<Note>Replace the `vpc_id` with the one created in the previous step. </Note>
You should see an output like this:

<Frame caption="Create a Security group on AWS">
  <img src="https://mintcdn.com/clouddley/wuHX6szeuQPUk6oa/images/aws-create-sg.png?fit=max&auto=format&n=wuHX6szeuQPUk6oa&q=85&s=4dc2f133f251e8bf2ef23726d2c7c800" width="1987" height="442" data-path="images/aws-create-sg.png" />
</Frame>

<br />

* Allow inbound traffic on port 22 (SSH) and port 3033 (your application port):

```bash theme={null}
aws ec2 authorize-security-group-ingress \
    --group-id <sg_id> \
    --protocol tcp \
    --port 22 \
    --cidr 0.0.0.0/0
```

```bash theme={null}
aws ec2 authorize-security-group-ingress \
    --group-id <sg_id> \
    --protocol tcp \
    --port 3033 \
    --cidr 0.0.0.0/0
```

<Note>Replace the `sg_id` with the one created in the previous step. </Note>

* To create an EC2 instance, you need to have an SSH key pair. If you don’t have one, you can generate and import one below.

<Accordion title="How to Generate and Import SSH Keys to AWS">
  If you don’t have an SSH key pair on your local machine, follow the steps below.

  * **Step 1:** To generate an SSH key, run the command:

  ```bash theme={null}
  ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  ```

  Press **Enter** to accept the default file location and choose a passphrase if you want one.

  * **Step 2:** To add your SSH key to AWS, run:

  ```bash theme={null}
  aws ec2 import-key-pair \
    --key-name my-key \
    --public-key-material file://~/.ssh/id_rsa.pub
  ```

  <Note>Replace the path to your public key if it's different.</Note>
</Accordion>

* Finally, create the EC2 instance:

```bash theme={null}
aws ec2 run-instances \
  --image-id ami-xxxxxxxx \
  --count 1 \
  --instance-type t2.micro \
  --key-name my-key \
  --security-group-ids <sg_id>
```

<Note>
  * Replace *ami-xxxxxxxx* with regions's compatible AMI
  * Replace *my-key* with your key pair name
  * Replace *sg\_id* with your security group id
</Note>

You should see the output below:

<Frame caption="Create a EC2 instance on AWS">
  <img src="https://mintcdn.com/clouddley/wuHX6szeuQPUk6oa/images/aws-create-ec2.png?fit=max&auto=format&n=wuHX6szeuQPUk6oa&q=85&s=76480a7889b778d09ba60224dd87010f" width="1400" height="680" data-path="images/aws-create-ec2.png" />
</Frame>

<br />

Once the instance is running, note the **Public IP address** of the instance. You'll need it later.

## Deploy

Now you have your FastAPI app on GitHub and an EC2 instance running on AWS. The next step is to deploy it.

* Log in to your [Clouddley account](https://app.clouddley.com/auth/signin)
* Click on **Apps** at the left sidebar
* Click on **Deploy App**

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

**Step 1: Configure Service**

* Choose your Git hosting service which can be **Github** or **Bitbucket**. We will use Github in this tutorial.
* Click on **Continue with Github** and authorize Clouddley to access your Github account.

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

**Step 2: Configure Git**

* To connect your Github user or organization account, click on the **Select username/organization** dropdown and **Add Github account**.
* Select your **repository** and the **branch** from the dropdown list or quickly search.
* Click on **Next**.

<Frame caption="Setup the FastAPI 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 />

**Step 3: Configure your Virtual Machine**

* 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 instance's **IP address** as **VM host**,  **VM user**, and the **VM port** 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 AWS EC2 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 EC2 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 on **Verify**. This verifies the connection to your VM.
* Once verified, click on **Next** to proceed.

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

**Step 4: Configure app settings**

* Enter the **name** of your application and its **port** **number**.
* Click on **Next** to continue.

<Frame caption="Configure the App name and port">
  <img src="https://mintcdn.com/clouddley/m4JLi_8_fwaEh8mq/images/Apps-fastapi-name.png?fit=max&auto=format&n=m4JLi_8_fwaEh8mq&q=85&s=75393cb6f01cf9bf9a475fa54f040fd4" width="3827" height="1695" data-path="images/Apps-fastapi-name.png" />
</Frame>

<br />

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

**Step 5: Configure Environment Variables**

* Click on <Icon icon="plus" iconType="solid" /> <b>Add Variable</b>
* Choose an ENV mode: either a **single variable** or **import variables** mode. 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 **Save**.
* Click on **Next** to continue.

<Frame caption="Adding environment variables">
  <img src="https://mintcdn.com/clouddley/m4JLi_8_fwaEh8mq/images/Apps-fastapi-env.png?fit=max&auto=format&n=m4JLi_8_fwaEh8mq&q=85&s=ccc959510f5a5c40b9c35d0e267f3135" width="3817" height="1695" data-path="images/Apps-fastapi-env.png" />
</Frame>

<br />

**Step 6: Setup Notifications (optional)**

* To configure the notifications settings of the application, click on <Icon icon="plus" iconType="solid" /> **Add Alert**
* Select the **Alert type**. For this tutorial, we will set up Email Alerts.
* Toggle on the buttons of the deployment event (failed, timed out, or success) you want to be notified of.
* Enter the **Email address** where you want to receive alerts. (You can add multiple email addresses)
* Click on **Save**
* Click on **Deploy**

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

**Step 7: Test and Verify the app**

* Click on **Go to Dashboard** to see your application on the apps dashbaord.
* Once the deployment is complete, the app status changes from `Deploying` to `Online`.

<Frame caption="FastAPI application dashboard overview">
  <img src="https://mintcdn.com/clouddley/m4JLi_8_fwaEh8mq/images/Apps-fastapi-dashboard.png?fit=max&auto=format&n=m4JLi_8_fwaEh8mq&q=85&s=f260bb0e7855b5e1eeb8ba78ac376c71" width="3775" height="1705" data-path="images/Apps-fastapi-dashboard.png" />
</Frame>

<br />

* Click on 🌐 **Website** at the top right corner of the webpage, this opens the URL of your application in your browser.
* You should see your Golang application running successfully.

<Frame caption="FastAPI application running from Clouddley on an AWS EC2 instance">
  <img src="https://mintcdn.com/clouddley/m4JLi_8_fwaEh8mq/images/Apps-fastapi-web.png?fit=max&auto=format&n=m4JLi_8_fwaEh8mq&q=85&s=2a9d983b6d8e0f4b742a47970004ea54" width="3797" height="1822" data-path="images/Apps-fastapi-web.png" />
</Frame>

<br />

## Post Deployment: Managing Your Application

After your FastAPI app is live on an AWS EC2 instance using Clouddley, managing it becomes straightforward. From the apps dashboard, you can take care of everything without logging into the server. You can update settings, [scale](https://docs.clouddley.com/apps/extras/scale-applications-on-clouddley), [roll back](https://docs.clouddley.com/apps/extras/how-to-rollback-an-application) to previous versions, [pause or resume](https://docs.clouddley.com/apps/extras/how-to-pause-and-resume-applications) the app, or even delete it. The dashboard also gives you tools to view deployment history, check logs, manage [environment variables](https://docs.clouddley.com/apps/extras/environment-variables), and connect a [custom domain](https://docs.clouddley.com/apps/extras/custom-domain) all in one place.

<AccordionGroup>
  <Accordion title="FastAPI Application Best Practices">
    Follow these best practices to ensure your code is clean, secure and optimized.

    <Icon icon="check" iconType="solid" /> **Structure your project**\
    Instead of cramming everything into one `main.py`, split things out. Have separate files or folders for routes, models, services, and utilities. It makes your code easier to read and scale.

    <Icon icon="check" iconType="solid" />  **Hide your secrets**\
    API keys, database passwords, or tokens don’t belong in your code. Use environment variables or a config manager so you can swap them out without touching your codebase.

    <Icon icon="check" iconType="solid" /> **Use Pydantic to your advantage**\
    One of FastAPI’s biggest strengths is data validation. Define request and response models with Pydantic, and let it catch bad inputs before they cause trouble.

    <Icon icon="check" iconType="solid" /> **Make errors human-friendly**\
    Nobody likes a messy traceback. Add custom exception handlers so your API responds with clear, helpful messages when something goes wrong.

    <Icon icon="check" iconType="solid" /> **Go async when it matters**\
    FastAPI is built for async, but it only helps if you use it. Choose async-ready libraries for database calls, HTTP requests, or anything that waits on I/O. Otherwise, you’re just slowing yourself down.

    <Icon icon="check" iconType="solid" /> **Lock down your endpoints**\
    Even small projects deserve security. Use authentication (JWT, OAuth2, or at least API tokens) and authorization checks so only the right people can access sensitive routes.

    <Icon icon="check" iconType="solid" /> **Write tests**\
    Start small with endpoint tests and expand from there. Tools like Pytest work beautifully with FastAPI, and having tests in place keeps you from shipping bugs.

    <Icon icon="check" iconType="solid" /> **Document as you go**\
    FastAPI generates docs for you, but don’t stop there. Add descriptions, examples, and notes in your route definitions so your API feels polished and easy to use.
  </Accordion>
</AccordionGroup>

## Conclusion

And that’s it, you’ve got your FastAPI application deployed on an AWS EC2 instance using Clouddley, making the process smoother. No complicated setup. Just a simple, reliable way to bring your app online and keep it running. Now you can focus less on deployment and more on building the features your users actually care about.

If you’ve got feedback or ideas to make Clouddley even better, let us know [here](https://clouddley.productlane.com/roadmap). We’re excited to see the cool things you’ll deploy with it!

<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)
* [AWS EC2 Documentation](https://aws.amazon.com/ec2/)
* [FastAPI Documentation](https://fastapi.tiangolo.com/)
* [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>
