{"id":3343,"date":"2025-04-25T07:02:22","date_gmt":"2025-04-25T07:02:22","guid":{"rendered":"https:\/\/mailitics.com\/index.php\/2025\/04\/25\/aws-deploying-a-fastapi-app-on-ec2-in-minutes\/"},"modified":"2025-04-25T07:02:22","modified_gmt":"2025-04-25T07:02:22","slug":"aws-deploying-a-fastapi-app-on-ec2-in-minutes","status":"publish","type":"post","link":"https:\/\/mailitics.com\/index.php\/2025\/04\/25\/aws-deploying-a-fastapi-app-on-ec2-in-minutes\/","title":{"rendered":"AWS:\u00a0Deploying a FastAPI App on EC2 in Minutes"},"content":{"rendered":"<p>    AWS:\u00a0Deploying a FastAPI App on EC2 in Minutes<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n    <!-- no image --><br \/>\n \t<BR><br \/>\n<BR><\/BR><\/p>\n<div>\n<h2 class=\"wp-block-heading\"><mdspan datatext=\"el1745541501643\" class=\"mdspan-comment\">Introduction<\/mdspan><\/h2>\n<p class=\"wp-block-paragraph\" id=\"ed29\"><a href=\"https:\/\/towardsdatascience.com\/tag\/aws\/\" title=\"AWS\">AWS<\/a> is a popular cloud provider that enables the deployment and scaling of large applications. Mastering at least one cloud platform is an essential skill for software engineers and data scientists. Running an application locally is not enough to make it usable in production \u2014 it must be deployed on a server to become accessible to end users.<\/p>\n<p class=\"wp-block-paragraph\" id=\"fb25\">In this tutorial, we will walk through an example of deploying a FastAPI application. While the example focuses on core EC2 networking concepts, the principles are broadly applicable to other types of applications as well.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\" id=\"be17\">Please note that this tutorial does not cover best practices for AWS usage. Instead, the goal is to give readers a hands-on introduction to application deployment using EC2 instances.<\/p>\n<\/blockquote>\n<h2 class=\"wp-block-heading\" id=\"dcc5\"># 01. Instance creation<\/h2>\n<p class=\"wp-block-paragraph\" id=\"aa5d\">Navigate to the <a href=\"https:\/\/towardsdatascience.com\/tag\/ec2\/\" title=\"Ec2\">Ec2<\/a> dashboard in the AWS service menu and choose to create a new instance. This will open a page where we can define instance parameters.<\/p>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"647\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/image-110-1024x647.png?resize=1024%2C647&#038;ssl=1\" alt=\"\" class=\"wp-image-601980\"><\/figure>\n<p class=\"wp-block-paragraph\">Select the corresponding instance type. In this tutorial, we will launch a very simple server with minimal technical requirements, so\u00a0<em>t3.nano<\/em>\u00a0should be sufficient for our needs.<\/p>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"315\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/image-111-1024x315.png?resize=1024%2C315&#038;ssl=1\" alt=\"\" class=\"wp-image-601981\"><\/figure>\n<p class=\"wp-block-paragraph\">For its containers, AWS uses SSH authentication. When creating a new instance, it is necessary to create a new key pair that will allow us to log in from the local machine using the SSH protocol. Click on\u00a0<strong><em>Create new key pair<\/em><\/strong>.<\/p>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"278\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/image-112-1024x278.png?resize=1024%2C278&#038;ssl=1\" alt=\"\" class=\"wp-image-601982\"><\/figure>\n<p class=\"wp-block-paragraph\">Assign a name to the new key. We will not dive into the possible options here, so we will choose RSA as the key pair type and .pem as the private key file format.<\/p>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"601\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/image-113-1024x601.png?resize=1024%2C601&#038;ssl=1\" alt=\"\" class=\"wp-image-601983\"><\/figure>\n<p class=\"wp-block-paragraph\">To save time, in our demonstration application we will not worry about security. For the network settings, tick all the checkboxes corresponding to SSH, HTTP, and HTTPS traffic.<\/p>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"784\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/image-114-1024x784.png?resize=1024%2C784&#038;ssl=1\" alt=\"\" class=\"wp-image-601984\"><\/figure>\n<p class=\"wp-block-paragraph\">Great! By clicking\u00a0<strong>Launch instance<\/strong>, AWS will create a new instance.<\/p>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"82\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/image-115-1024x82.png?resize=1024%2C82&#038;ssl=1\" alt=\"\" class=\"wp-image-601985\"><\/figure>\n<p class=\"wp-block-paragraph\" id=\"2e1d\">After the instance is created, a\u00a0<em>.pem<\/em>\u00a0file will be downloaded to your local machine. This file contains the private key that allows SSH authentication. As a good practice, store this file in a safe location because AWS does not provide a way to recover it if it is lost.<\/p>\n<p class=\"wp-block-paragraph\" id=\"4978\">By opening the EC2 dashboard, you will notice that the created instance has an associated IP address. This IP is shown under the label\u00a0<em>\u201cPublic IPv4 address\u201d<\/em>. For example, in the image below, it is\u00a0<em>\u201c16.16.202.153\u201d<\/em>. Once we deploy our application, it will be accessible from a browser using this IP address.<\/p>\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" height=\"233\" width=\"1024\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/image-116-1024x233.png?resize=1024%2C233&#038;ssl=1\" alt=\"\" class=\"wp-image-601986\"><\/figure>\n<h2 class=\"wp-block-heading\" id=\"a398\"># 02. SSH connection<\/h2>\n<p class=\"wp-block-paragraph\" id=\"2a7a\">AWS offers several ways to perform authentication. In our case, we will use the SSH mechanism.<\/p>\n<p class=\"wp-block-paragraph\" id=\"d053\">In the instance menu, click\u00a0<strong><em>Connect<\/em><\/strong>\u00a0and select\u00a0<strong><em>SSH client<\/em><\/strong>\u00a0from the top bar.<\/p>\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/contributor.insightmediagroup.io\/wp-content\/uploads\/2025\/04\/10_f3fxONQUQHKBFdRWg6Dg.png?ssl=1\" alt=\"\" class=\"wp-image-601988\"><\/figure>\n<p class=\"wp-block-paragraph\" id=\"4cd7\">Open the local terminal and, using the screenshot above as reference, copy and execute command #3 (<code>chmod 400 \"&lt;key_name&gt;.pem\"<\/code>) along with the command shown below the\u00a0<em>\u201cExample\u201d<\/em>\u00a0label. Make sure your current terminal directory matches the location where the\u00a0<em>.pem<\/em>\u00a0key was downloaded in the previous step.<\/p>\n<p class=\"wp-block-paragraph\" id=\"58bd\">During the SSH connection, the terminal might prompt whether to proceed. If it does, type\u00a0<em>\u201cyes\u201d<\/em>.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\" id=\"982b\">At this point, we are successfully connected from the local terminal to the EC2 instance. Any commands entered into the terminal will now be executed directly in the EC2 container.<\/p>\n<\/blockquote>\n<h2 class=\"wp-block-heading\" id=\"6f08\"># 03. Environment configuration<\/h2>\n<p class=\"wp-block-paragraph\" id=\"4ce0\">After connecting to the instance from the local terminal, the next step is to update the package manager and install Python along with Nginx.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">sudo apt-get update\nsudo apt install -y python3-pip nginx<\/code><\/pre>\n<p class=\"wp-block-paragraph\">To redirect traffic to our application, we need to create an Nginx configuration file. This file should be placed in the directory\u00a0<code>\/etc\/nginx\/sites-enabled\/<\/code>\u00a0and can have any custom name. We will add the following configuration to it:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">server {\n  listen 80;\n  server_name &lt;Public_IP_Address&gt;;\n  location \/ {\n    proxy_pass http:\/\/127.0.0.1:8000;\n  }\n}<\/code><\/pre>\n<p class=\"wp-block-paragraph\" id=\"f585\">Basically, we are specifying that any external request sent to the EC2 instance\u2019s IP address on the default port 80 should be redirected via a proxy to the application running inside the EC2 container at the address\u00a0<code>http:\/\/127.0.0.1:8000<\/code>. As a reminder, this is the default HTTP address and port assigned by FastAPI.<\/p>\n<p class=\"wp-block-paragraph\" id=\"f56e\">To apply these changes, we need to restart Nginx:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">sudo service nginx restart<\/code><\/pre>\n<p class=\"wp-block-paragraph\">If we have a FastAPI server that we would like to launch, the simplest way would be to publish it on GitHub and then clone the repository onto the EC2 instance.<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">git clone &lt;GitHub_URL&gt; &lt;directory&gt;\ncd &lt;directory&gt;<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Create and activate a virtual environment:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-bash\">python3 -m venv venv\nsource venv\/bin\/activate<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Install the necessary Python requirements (assuming that the cloned repository contains a\u00a0<em>requirements.txt<\/em>\u00a0file):<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">pip3 install -r requirements.txt<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Run the server:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">python3 -m uvicorn &lt;server_filename&gt;:app<\/code><\/pre>\n<p class=\"wp-block-paragraph\" id=\"f9c5\">Open the browser and enter the IP address of the instance.<\/p>\n<p class=\"wp-block-paragraph\" id=\"e511\">Make sure to use the HTTP (not HTTPS) protocol. For example:\u00a0<code>&lt;a href=\"http:\/\/16.16.202.153\/\" rel=\"noreferrer noopener\" target=\"_blank\"&gt;http:\/\/16.16.202.153&lt;\/a&gt;<\/code>. The firewall might block your connection, but you should proceed to open the web page. Add\u00a0<code>\/docs<\/code>\u00a0after the URL to open Fast API Swagger.<\/p>\n<h3 class=\"wp-block-heading\" id=\"2004\">Exercise<\/h3>\n<p class=\"wp-block-paragraph\" id=\"75d6\">If you would like to run a FastAPI example, you can create a simple repository consisting of just a\u00a0<em>main.py<\/em>\u00a0file and a\u00a0<em>requirements.txt<\/em>.<\/p>\n<p class=\"wp-block-paragraph\" id=\"1958\"><em>main.py<\/em><\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">from fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"\/\")\ndef read_root():\n    return {\"message\": \"Hello, World!\"}<\/code><\/pre>\n<p class=\"wp-block-paragraph\"><em>requirements.txt<\/em><\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">fastapi\nuvicorn<\/code><\/pre>\n<h2 class=\"wp-block-heading\" id=\"abb9\">Uploading files<\/h2>\n<p class=\"wp-block-paragraph\" id=\"c246\">If you try to upload a file to a server and receive a 413 status with the error message\u00a0<em>\u201cError: Request Entity Too Large\u201d<\/em>, it is likely because Nginx has a limit on the maximum file size that can be uploaded. To resolve this issue, go to the Nginx configuration file and specify the maximum allowed file size by using the\u00a0<em>client_max_body_size<\/em>\u00a0directive (setting it to 0 indicates no limits on input file sizes):<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-nginx\">server {\n  listen 80;\n  server_name &lt;PUBLIC_IP_ADDRESS&gt;;\n  location \/ {\n    proxy_pass http:\/\/127.0.0.1:8000;\n    client_max_body_size 0;\n  }\n}<\/code><\/pre>\n<p class=\"wp-block-paragraph\">After changing the configuration file, do not forget to restart Nginx.<\/p>\n<h2 class=\"wp-block-heading\" id=\"e34f\">Conclusion<\/h2>\n<p class=\"wp-block-paragraph\" id=\"0fd1\">In this article, we have learned how to quickly create a running EC2 instance using a FastAPI server as an example. Although we did not follow the best deployment and security practices, the main goal of the article was to provide minimal information for beginners to launch their first server on AWS.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\" id=\"7b01\">The next logical step in the AWS study roadmap would be creating multiple EC2 instances and connecting them to each other.<\/p>\n<\/blockquote>\n<p class=\"wp-block-paragraph\" id=\"5272\"><em>All images unless otherwise noted are by the author.<\/em><\/p>\n<h2 class=\"wp-block-heading\">Connect with me<\/h2>\n<ul class=\"wp-block-list\">\n<li class=\"wp-block-list-item\">\n<strong><a href=\"https:\/\/medium.com\/@slavahead\" data-type=\"link\" data-id=\"https:\/\/medium.com\/@slavahead\">Medium<\/a><\/strong> <img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/270d.png?ssl=1\" alt=\"\u270d\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\">\n<\/li>\n<li class=\"wp-block-list-item\">\n<strong><a href=\"https:\/\/www.linkedin.com\/in\/vyacheslav-efimov\/\" data-type=\"link\" data-id=\"https:\/\/www.linkedin.com\/in\/vyacheslav-efimov\/\">LinkedIn<\/a><\/strong> <img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/s.w.org\/images\/core\/emoji\/15.0.3\/72x72\/1f9d1-200d-1f4bb.png?ssl=1\" alt=\"\ud83e\uddd1\u200d\ud83d\udcbb\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\">\n<\/li>\n<\/ul>\n<p>The post <a href=\"https:\/\/towardsdatascience.com\/aws-deploying-a-fastapi-app-on-ec2-in-minutes\/\">AWS:\u00a0Deploying a FastAPI App on EC2 in Minutes<\/a> appeared first on <a href=\"https:\/\/towardsdatascience.com\/\">Towards Data Science<\/a>.<\/p>\n<\/div>\n<p> \t<BR><br \/>\n <BR><\/BR><br \/>\n    Vyacheslav Efimov<br \/>\n \t<BR><br \/>\n<BR><\/BR><br \/>\n<a href=\"https:\/\/towardsdatascience.com\/aws-deploying-a-fastapi-app-on-ec2-in-minutes\/\">Go to original source<\/a><br \/>\n \t<BR><br \/>\n <BR><\/BR><\/p>\n","protected":false},"excerpt":{"rendered":"<p>AWS:\u00a0Deploying a FastAPI App on EC2 in Minutes Introduction AWS is a popular cloud provider that enables the deployment and scaling of large applications. Mastering at least one cloud platform is an essential skill for software engineers and data scientists. Running an application locally is not enough to make it usable in production \u2014 it [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62,2418,2419,401,2480,2481,2482],"tags":[263,2483,42],"class_list":["post-3343","post","type-post","status-publish","format-standard","hentry","category-aimldsaimlds","category-aws","category-cloud","category-data-engineering","category-deploy","category-devops","category-ec2","tag-aws","tag-instance","tag-will"],"_links":{"self":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/3343"}],"collection":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/comments?post=3343"}],"version-history":[{"count":0,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/posts\/3343\/revisions"}],"wp:attachment":[{"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/media?parent=3343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/categories?post=3343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mailitics.com\/index.php\/wp-json\/wp\/v2\/tags?post=3343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}