Running FastAPI with TLS/HTTPS on an EC2 instance

Oct 05, 2023

Setting up FastAPI with TLS/HTTPS on an Amazon EC2 instance.

I spent about 8 hours figuring this out. Now that I’ve been through it once I bet I could set it up again in 30-40 minutes.

Getting Amazon EC2 up and running

  • Set up to use Amazon EC2. I wasn’t able to select the Security Group I created when creating an EC2 instance. I tried modifying the default Security Group to allow SSH but that didn’t seem to work. I didn’t end up using a Security Group, instead I checked the boxes on the EC2 instance creation page for allowing http, https, and ssh. (Wasted an hour figuring that out.)
  • Tutorial: Get started with Amazon EC2 Linux instances.
  • Install LAMP on Amazon Linux 2023. Installed LAMP to get “Hello World” (actually it says “IT WORKS!”) for http.

Getting HTTPS/TLS to work

Install Nginx and configure TLS

  • Disable apache (in fact you never had to do that in the first place, I was just using it as a bootstrapping step. Nginx by default puts a web page up at port 80.)

    $ sudo systemctl stop httpd

  • Install pip and nginx:

    $ sudo dnf install python3-pip nginx

  • FYI the certbot user guide was helpful for finding where the certificates were located and which ones to use for configuring nginx.
  • In /etc/nginx/nginx.conf I commented out the port 80 server and uncommented the port 443 server. Then updated these fields:
      server {
          listen       443 ssl http2;
          listen       [::]:443 ssl http2;
          server_name  www.asdfasdf.fun;     # UPDATED
          root         /usr/share/nginx/html;
          location / {                              # ADDED
                  proxy_pass http://localhost:8000; # ADDED
          }                                         # ADDED
          ssl_certificate "/etc/letsencrypt/live/www.asdfasdf.fun/fullchain.pem"; # UPDATED
          ssl_certificate_key "/etc/letsencrypt/live/www.asdfasdf.fun/privkey.pem"; # UPDATED
          ...
      }
    
  • Start nginx and enable it to start at boot:

    $ sudo systemctl start nginx.service

    $ sudo systemctl enable nginx.service

Install and run FastAPI

  • From Fast API Installation: … added the main.py hello world FastAPI file from the FastAPI installation page to the ec2-user directory and ran the FastAPI server (default is port 8000):

    $ cd

    (create main.py file)

    $ uvicorn main:app –reload

  • Note the default port is 8000 which matches the nginx.conf file above.
  • Navigating to https://www.asdfasdf.fun shows { “Hello World” }. Works!

Notes

  • I was past the free period on my account so I’ve been paying $0.29 / day for the default tc2.micro instance. It looks like tc3.micro might be cheaper?
  • Stopping/starting the instance gives it a new IP address and DNS name, so you need to update that with your Domain Name provider. It took only a couple of minutes after updating to be able to ssh into the instance, but still a pain. To have a permanent IP address you can get an Elastic IP address, which seems to be free as long as the service it’s connected to is running.