Streamlit Community Cloud is the fastest path from a working local Streamlit app to a deployed URL. No Docker, no cloud provider setup, no billing configuration for small apps. Connect a GitHub repo, point it at your app.py, deploy.
Here’s the setup for a multipage analytics app backed by DuckDB, deployed in an afternoon.
What you need before deploying
- A GitHub repo with your Streamlit code
- A
requirements.txtlisting dependencies - Your
app.pyentry point at the repo root (or a configured path) - Your data accessible at deploy time
The last point is where most deployments get stuck.
requirements.txt for this stack
streamlit==1.57.0
duckdb==1.10.0
pandas==2.2.3
plotly==5.24.1
scikit-learn==1.6.1
numpy==2.2.0
Pin versions. Streamlit Community Cloud installs from requirements.txt on every deploy. An unpinned dependency that gets a major version bump will break the app at deploy time rather than during development when you’d catch it.
Handling the DuckDB file
The synthetic dataset is small enough (DuckDB file is under 50MB) to commit directly to the repo.
git add tuva.duckdb
git commit -m "add DuckDB database file"
git push
On each deploy, Community Cloud checks out the repo and the .duckdb file is present at the expected path.
If your data is larger than ~100MB, the practical approach is to store it in S3 and download it at container startup:
# app.py — runs before any page renders
import os
import boto3
if not os.path.exists("tuva.duckdb"):
s3 = boto3.client("s3")
s3.download_file("your-bucket", "tuva.duckdb", "tuva.duckdb")
pg = st.navigation([...])
pg.run()
Community Cloud containers have ephemeral storage, so the file is rebuilt on every restart. For a dataset that changes daily, pair this with a scheduled rebuild.
Secrets for S3 credentials
If your app needs AWS credentials or API keys, use Streamlit’s secrets management rather than environment variables. In the Community Cloud dashboard, go to your app’s settings and add secrets in TOML format:
AWS_ACCESS_KEY_ID = "AKIA..."
AWS_SECRET_ACCESS_KEY = "..."
Access them in code:
import streamlit as st
key_id = st.secrets["AWS_ACCESS_KEY_ID"]
secret = st.secrets["AWS_SECRET_ACCESS_KEY"]
Locally, create .streamlit/secrets.toml in your project root with the same format. Add it to .gitignore.
The deploy steps
- Push all code and the
.duckdbfile to GitHub - Go to share.streamlit.io and sign in with GitHub
- Click “New app” → select repo, branch, and main file path (
app.py) - Click “Deploy”
First deploy takes 3-5 minutes while Community Cloud installs the requirements.txt dependencies and starts the app. Subsequent deploys on the same repo pick up new pushes automatically if auto-deploy is enabled.
The app.py structure for deployment
import streamlit as st
import duckdb
st.set_page_config(
page_title="Tuva Analytics",
layout="wide",
)
@st.cache_resource
def get_db():
return duckdb.connect("tuva.duckdb", read_only=True)
if "db" not in st.session_state:
st.session_state.db = get_db()
pg = st.navigation([
st.Page("tuva_explorer.py", title="Tuva Explorer"),
st.Page("data_quality_explorer.py", title="Data Quality"),
st.Page("predictions.py", title="Risk Predictions"),
])
pg.run()
st.set_page_config must be the first Streamlit call in app.py. Setting layout="wide" is worth it for data-heavy dashboards — it uses the full browser width instead of the centered narrow column default.
What the free tier gives you
Streamlit Community Cloud free tier:
- Unlimited public apps
- 1GB memory per app instance
- Apps sleep after 7 days of inactivity (wake automatically on next visit, takes ~30 seconds)
- No custom domains
For a demo or portfolio app reading from a committed DuckDB file, the free tier is enough. A DuckDB file under 50MB, four Python files, and requirements.txt deploys cleanly and stays live with no ongoing cost.