Deployment of Streamlit App (using systemd) on AWS EC2 with Custom Domain (using nginx)

Hi everyone!

This is my first post and I hope you tolerate my beginner mistakes. If there is anything I’m doing wrong or I can improve, I’m happy to take in feedback!

I recently made a small app mainly to have a UI after doing some data wrangling and I was also doing some AWS at the job, and wanted to see if I am able to have “professional”, with Streamlit and AWS.

The article: Deploying a Streamlit app on AWS EC2 (with your own domain name) – Reinforced Knowledge

The goal behind the article is to take someone who knows nothing about AWS to be able to deploy its app with its own domain name, so not only I explain (lightly) these concepts but I also explain the reasoning behind some of the choices.

I really go from the ground up, even user creation and the policies (I didn’t choose the minimal set of permissions but AmazonEC2FullAccess, but I talk about the least privilege principle). I also talk about basic AWS stuff like key pair, security groups. I also talk about some of the choices in my configurations settings (nginx and Streamlit systemd unit file) in case you needed to change things. For example I’m using the uv package manager so I talk about how you can do things differently.

So I’ve done that, I don’t know how “professional” it is but I hope people can criticize it enough so that I can rebuild what I’ve done into a better version of it. I have tried to stick to some of security best practices but since the project isn’t vital it’s easy to miss some of the security concerns. But I try to speak about that whenever I can.

The “stack” if we can call it so is Streamlit, the free tier of AWS services, this includes an EC2 Instance of type t2.micro with the Amazon Linux 2023 AMI. And nginx. The rest of the stuff comes with the AMI (systemd comes with Linux, and certbot for SSL certificates, which I’m not using because I chose the flexible SSL certificates from Cloudflare, but I’m talking about it in case you wanted to use it instead)

At the menu: a User Data script to do some basic stuff, create a user with restricted privileges and for which we’re going to do some of the operations like install the package manage, pulling in the repo etc. And we might as well launch (more like, configure and launch) the Streamlit app using the User Data script. I’m choosing to do so with systemd which will gracefully manage the lifecycle and also allow us to do advanced stuff if we wanted.

This is the basic stuff to get something running on public-ip-address:8501. Then I get into how to associate your domain name, I do this with nginx so I get into the configuration, some minor modificaton to the Streamlit systemd service that I set up, and security groups (no need to use the 8501 inbound traffic rule anymore at this point).

Finally, I get into some minor stuff that could help you troubleshoot in case you encounter an error.