# How to Deploy a Python Streamlit Project Online (Free, Step by Step)

Your Streamlit app runs fine on your laptop. Then someone asks for the link, and all you can send is `localhost:8501`, which only works on your own machine. That address points at your computer and nowhere else.

Streamlit Community Cloud is a free way to fix that. It pulls your code from GitHub, installs your packages and gives you a public URL. This guide walks through the whole thing, and then covers the errors you are most likely to hit.

I have checked the steps below against the official Streamlit docs. The Community Cloud interface changes now and then, so if a button has moved, the docs at docs.streamlit.io are the final word.

## Local vs deployed: what actually changes

When you run `streamlit run app.py`, your app uses your Python, your installed packages and your files. Deployed, it runs on a fresh Linux machine that knows nothing about your laptop. Community Cloud builds a new Python environment from your repository, then starts your app inside it.

So the rule is simple: **anything your app needs must be in the repo or listed in a dependency file.** Almost every deployment error comes from breaking that rule.

## Before you deploy: prepare the project

You need three things.

1. A GitHub repository with your app in it. If you have not pushed your code yet, see [Git and GitHub for College Students: From Local Project to GitHub Repository](https://pranaavkarthik.hashnode.dev/github-for-beginners-local-project-to-repository).
2. A `requirements.txt` file.
3. Every data file the app reads, committed to the repo.

A minimal layout looks like this:

```text
my-dashboard/
├── app.py
├── sales.csv
├── requirements.txt
└── .gitignore
```

If you want a working app to practise on, [How to Build an Interactive Dashboard Using Python and Streamlit](https://pranaavkarthik.hashnode.dev/build-interactive-dashboard-python-streamlit) gives you one that fits this layout exactly.

### Write requirements.txt

Community Cloud checks for dependency files in this order: `uv.lock`, `Pipfile`, `environment.yml`, `requirements.txt`, then `pyproject.toml`. It looks next to your main file first, then in the repo root, and uses the first one it finds. Pick one and stick with it. For most student projects, that is `requirements.txt`.

```text
streamlit>=1.32.0
pandas>=2.0.0
plotly>=5.18.0
```

Each line works like an argument to `pip install`. A few rules from the docs:

- Leave out built-in modules like `math`, `json` and `random`. They ship with Python and listing them causes errors.
- Streamlit is preinstalled, so you only need to list it if you want to pin or limit its version.
- If there is no requirements file at all, the app runs with only Streamlit and its own dependencies. That is why a missing file shows up as `ModuleNotFoundError`.

For a real-world reference, the open-source Superstore dashboard by Asha Kalavagunta ([GitHub repo](https://github.com/Ashakalavagunta/sales-analytics-dashboard)) lists streamlit, pandas, numpy and plotly in its `requirements.txt`, and is deployed on Community Cloud. That is the same shape of file you need here.

To generate your own list from your environment, run `pip freeze`, but trim it. The full output includes every sub-dependency pinned to your exact versions, and that can cause conflicts on a different operating system. Writing only the packages you import is cleaner.

### Use paths that survive deployment

The docs say the working directory on Community Cloud is always the root of your repository. If your app sits in the root, `pd.read_csv("sales.csv")` works. If it sits in a subfolder, it won't. A safer habit is to build the path from the script's own location:

```python
from pathlib import Path
import pandas as pd

DATA_PATH = Path(__file__).parent / "sales.csv"
df = pd.read_csv(DATA_PATH)
```

Two more path rules: use forward slashes (`data/sales.csv`), because backslashes don't work, and match the file name's capital letters exactly. Windows ignores case, but Linux does not. `Sales.csv` and `sales.csv` are different files there.

### Keep secrets out of GitHub

If your app uses an API key or password, never hard-code it and never commit it. Keep it in `.streamlit/secrets.toml` on your machine and add that path to `.gitignore`:

```text
.streamlit/secrets.toml
venv/
__pycache__/
```

In your code, read values like this:

```python
import streamlit as st

api_key = st.secrets["api_key"]
```

The docs are blunt about this: the `secrets.toml` file should never be committed to your repository. If you pushed a key by mistake, deleting the file in a later commit is not enough, because it stays in Git history. Treat the key as leaked and generate a new one.

## Deploy step by step

Push your latest code to GitHub first. Then:

1. Go to **share.streamlit.io** and sign in. You can sign in with GitHub, which also connects your repositories.
2. Click **Create app** in the top-right corner.
3. When asked if you already have an app, choose **Yup, I have an app**.
4. Fill in three fields: **Repository**, **Branch** and **Main file path**. The main file path is the file that starts your app, such as `app.py`. If it is inside a folder, write `folder/app.py`. You can also click **Paste GitHub URL** and drop in a link to the file.
5. Optional: choose a custom subdomain in the **App URL** field. Leave it blank and you get an automatically generated one. You can change it later.
6. Click **Advanced settings** if you need to set the Python version or add secrets (next two sections).
7. Click **Deploy**.

The first build takes a few minutes, longer if you have many packages. Logs show up on the right side while it builds. Only people with write access to the repository can see them.

### Pick the Python version

Under **Advanced settings** there is a **Python version** dropdown. The docs say the default is 3.12. Choose the same version you use locally where you can, because package versions and built-in behaviour differ between releases. You can check yours with `python --version`.

Also pick a version that still gets security updates. The docs warn that if your version becomes unsupported, it will be forcibly upgraded and may break your app.

### Add secrets

In the same **Advanced settings** dialog, paste the contents of your local `secrets.toml` into the **Secrets** field and click **Save**. For an app that is already live, you can edit secrets later from the app's settings.

### Your live app

When the build finishes, your app opens at its own URL. That link is public, so anyone you send it to can use it.

## Common errors and how to fix them

Open the logs first. On a running app, click **Manage app** in the lower-right corner. Most fixes start with reading the last few lines of the log.

### ModuleNotFoundError: No module named 'plotly'

The package is missing from your dependency file. Add it to `requirements.txt`, commit, and push. Community Cloud picks up the change and redeploys. Check spelling too: the install name and import name sometimes differ (`scikit-learn` installs, `sklearn` imports).

### FileNotFoundError for your CSV

Three usual causes:

- The file never got committed. Run `git status` and check that it is tracked.
- The path is wrong for a subfolder app. Use the `Path(__file__).parent` approach shown earlier.
- The file name has different capitalisation on Linux.

### Installer errors or version conflicts

If the log shows a failure while installing, suspect a pinned version that doesn't exist for the Python version you chose. Loosen the pin (`pandas>=2.0.0` instead of `pandas==2.0.1`), or try a different Python version under the app settings.

Some libraries also need system-level software, not just Python packages. For those, add a `packages.txt` file in the repo root, one package name per line. Community Cloud runs Debian Linux and installs them with `apt-get`. Most beginner apps never need this file.

### Two dependency files fighting each other

Only the first dependency file found is used, in the order listed earlier. If you have both a `requirements.txt` and a `pyproject.toml`, one of them is being ignored. Keep one.

### The app works, then slows down or crashes

Community Cloud gives each app limited resources. The docs list roughly 2.7 GB of memory and 2 CPU cores at the top end, with a lower floor, and note that these numbers are approximate as of February 2024 and may change without notice. Signs you are over the limit are a slow app or a message saying the app has gone over its resource limits.

What helps:

- Cache data loading with `@st.cache_data` so you don't re-read big files on every click.
- Don't load a huge dataset into memory if you only need a few columns. `pd.read_csv(..., usecols=[...])` helps.
- Open **Manage app** and choose reboot to clear memory.

### Edits don't show up

Community Cloud redeploys from GitHub, so a change only goes live after you push it. Commit, push, and refresh. Also check that you pushed to the same branch you selected during deployment. A `master` versus `main` mix-up is an easy way to push code the app never sees.

### "This app has gone to sleep"

Free apps with no traffic for 12 hours go to sleep. Anyone who visits can click **Yes, get this app back up!** to wake it, and it takes a short while to start again. You do not need to be the owner to do this.

This matters if you are putting the link on a resume or portfolio. Open the app yourself before you share it, and tell people the first load might be slow. Don't rely on tricks to keep it awake. Just expect the delay.

### Other limits to know about

Community Cloud limits updates from GitHub to five per minute, and all apps are hosted in the United States. If your `print()` output is missing from the logs, call `sys.stdout.flush()` after printing.

## A quick checklist before you click Deploy

- App runs locally from the repo root with `streamlit run app.py`
- `requirements.txt` lists every third-party import
- Data files are committed and use relative paths
- `secrets.toml` is in `.gitignore`
- Latest code is pushed to the branch you will select

## Wrap up

Deployment is mostly housekeeping. Get your dependencies listed, keep your paths relative, keep secrets out of Git, then fill in the three fields on Community Cloud. When something breaks, the logs usually tell you exactly which file or package is missing.

Once your app is live, add the link to your README so people can find it. [How College Students Can Build a Strong GitHub Portfolio](https://pranaavkarthik.hashnode.dev/github-portfolio-for-students) covers how to present projects properly.

If you want to see a full dashboard that is deployed on Community Cloud, read through [Asha Kalavagunta's Sales Analytics Dashboard](https://github.com/Ashakalavagunta/sales-analytics-dashboard). You can follow my own learning projects on [GitHub](https://github.com/Pranaav717).
